简体   繁体   English

什么设计模式?

[英]What design pattern?

I have a class A maintaining a list of objects class B. But each object of class B can be referenced in any object of class A. Class B also maintains a list of objects of class A where it is being referenced. 我有一个类A维护对象类B的列表。但是类B的每个对象都可以在类A的任何对象中引用。类B还维护一个被引用的类A的对象列表。 The program can and will create (several) objects of both class A and B 'at will' and also delete them. 该程序可以并将随意创建(几个)A类和B类的对象,并删除它们。

If I use C# I can add and delete objects from both classes with following code 如果我使用C#,我可以使用以下代码添加和删除这两个类中的对象

public class A
{
    private List<B>ListOfObjects_B;
    public bool Add(B Object)
    {
       bool bAdd = false;
       if ((Object != null) && (ListOfObjects_B.IndexOf(B) <0))
       {
          ListOfObjects_B.Add(Object);
          Object.Add(this);
          bAdded = true;
       }
       return bAdded;
    }

    public bool Delete(B Object)
    {
       bool bDeleted = ListOfObjects_B.Remove(Object);
       if (bDeleted == true) Object.Delete(this);
       return bDeleted;
    }
}

public class B
{
    private List<A>ListOfObjects_A;
    public bool Add(A Object)
    {
        bool bAdd = false;
        if ((Object != null) && (ListOfObjects_A.IndexOf(A) <0))
        {
            ListOfObjects_A.Add(Object);
            Object.Add(this);
            bAdded = true;
        }
        return bAdded;
   }

   public bool Delete(A Object)
   {
       bool bDeleted = ListOfObjects_A.Remove(Object);
       if (bDeleted == true) Object.Delete(this);
       return bDeleted;
   }
}

This will work as because of removing/adding the object to the ListOfObjects the SECOND time (by recursion) the function will be called it will fail to delete/add thereby avoiding an infinite loop. 这将起作用,因为删除/添加对象到ListOfObjects SECOND时间(通过递归)函数将被调用它将无法删除/添加从而避免无限循环。

But I don't like this code even though A and B do not know 'much' about the other class and just call a Delete/Add function. 但我不喜欢这段代码,即使A和B不太了解其他类,只是调用删除/添加功能。

I suppose this kind of problem is general and a design pattern exists for handling it in such a way that recursion can be avoided and updating both lists will be 'just better'. 我认为这种问题是一般的,并且存在一种设计模式,用于处理它,以便可以避免递归,并且更新两个列表将“更好”。 What design pattern should I use? 我应该使用什么设计模式? I would appreciate if some code would be added as well. 如果添加一些代码,我将不胜感激。

You can simplify thing by moving the "object association concern" into a dedicated class. 您可以通过将“对象关联关注点”移动到专用类中来简化操作。 Here's what I have in mind. 这就是我的想法。

Define a class called AssociationTable. 定义一个名为AssociationTable的类。 This class will maintain a list of pairs where each pair holds a reference to an A object and a reference to a B object. 此类将维护一对对列表,其中每对包含对A对象的引用和对B对象的引用。

Each A object (and each B object) will hold a reference to the AssociationTable object. 每个A对象(以及每个B对象)将保存对AssociationTable对象的引用。 A.Add(B) will be implemented as table.add(this, b); A.Add(B)将实现为table.add(this,b); B.Add(A) will be implemented as table.add(a, this); B.Add(A)将实现为table.add(a,this);

Deletion will be implemented as table.delete(this, b) or table.delete(a, this) 删除将实现为table.delete(this,b)或table.delete(a,this)

class Pair { 
  A a; B b; 
  Pair(A a, B b) { this.a = a; this.b = b; } 
  // Also override Equals(), HashCode()
}

class AssociationTalbe {
  Set<Pair> pairs = ...;

  void add(A a, B b) { pairs.add(new Pair(a, b)); }
  void remove(A a, B b) { pairs.remove(new Pair(a, b)); }
}

class A {
  AssociationTable table;

  public A(AssociationTable t) { table = t; }

  void add(B b) { table.add(this, b); }
  void remove(B b) { table.remove(this, b); }
}

Edit: The problem with this design is garbage collection. 编辑:这个设计的问题是垃圾收集。 the table will hold references to objects thereby supressing their collection. 该表将保存对象的引用,从而压制其集合。 In Java you could use a WeakReference object to overcome this issue. 在Java中,您可以使用WeakReference对象来克服此问题。 I am pretty sure there's something similar in the .Net world 我很确定在.Net世界中有类似的东西

Also, the table could be a singleton. 此外,该表可以是单身人士。 I don't like singletons too much. 我不太喜欢单身人士。 In here, a singleton will make the AB association unique across your program. 在这里,单例将使AB关联在您的程序中唯一。 This may be something that is undesirable but it depends on your concrete needs. 这可能是不受欢迎的,但这取决于您的具体需求。

Finally, (just to put things in context) this design works the same way as Many-to-Many relationships in relational data bases. 最后,(只是为了把事情放在上下文中)这种设计与关系数据库中的多对多关系的工作方式相同。

I recently wrote a class to handle a similar problem . 我最近写了一个类来处理类似的问题 It is actually a simpler scenario (parent/child relationship with the children referencing their parent), but you could probably adapt it for your needs. 它实际上是一个更简单的场景(父/子关系与孩子引用他们的父母),但你可能可以根据自己的需要调整它。 The main difference is that the Parent property in my implementation should be replaced by a collection of parents. 主要区别在于我的实现中的Parent属性应该由Parent的集合替换。

About the only thing I can think of is using a Mediator pattern so that A doesn't add itself to B. Here's an example: 关于我唯一能想到的是使用Mediator模式,这样A就不会将自己添加到B.这是一个例子:

public class Mediator {

    public void Add(A List, B Object) {
        if(list.Add(Object)) {
            object.Add(List);
        }
    }

    public void Delete(A List, B Object) {
        if(List.Delete(Object)) {
            Object.Delete(List);
        }
    }
}

After this you would remove the lines of code which read "Object.Add(this);" 在此之后,您将删除读取“Object.Add(this);”的代码行。 and "if (bDeleted == true) Object.Delete(this);" 和“if(bDeleted == true)Object.Delete(this);” This also has the benefit of reducing how many times each method is called as before object A's methods were being called twice since object B was also calling those methods on object A. 这也有利于减少每个方法的调用次数,因为对象A的方法被调用两次,因为对象B也在对象A上调用这些方法。

EDIT: Upon further review, I realized you were already using an Observer design pattern in a way. 编辑:经过进一步审查,我意识到你已经在某种程度上使用了观察者设计模式。 Object A is the observer and object B is the observable. 对象A是观察者,对象B是可观察对象。 Object A maintains a list of objects its observing and object B maintains a list of objects observing it. 对象A维护其观察对象的列表,对象B维护观察它的对象列表。 The only thing is I don't see any additional functionality, although there probably is some. 唯一的事情是我没有看到任何额外的功能,虽然可能有一些。 Basically, Object B will notify all Object A's observing it that it's changed and all of those Object A's will ask for the change. 基本上,对象B将通知所有对象A观察它已被更改,并且所有这些对象A将要求进行更改。 If this is what you're looking for, then all you need to do is remove the lines "Object.Add(this);" 如果这是您正在寻找的,那么您需要做的就是删除行“Object.Add(this);” and "if(bDeleted == true) Object.Delete(this);" 和“if(bDeleted == true)Object.Delete(this);” from the B code as it is unnecessary. 来自B代码,因为它是不必要的。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM