繁体   English   中英

什么设计模式?

[英]What design pattern?

我有一个类A维护对象类B的列表。但是类B的每个对象都可以在类A的任何对象中引用。类B还维护一个被引用的类A的对象列表。 该程序可以并将随意创建(几个)A类和B类的对象,并删除它们。

如果我使用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;
   }
}

这将起作用,因为删除/添加对象到ListOfObjects SECOND时间(通过递归)函数将被调用它将无法删除/添加从而避免无限循环。

但我不喜欢这段代码,即使A和B不太了解其他类,只是调用删除/添加功能。

我认为这种问题是一般的,并且存在一种设计模式,用于处理它,以便可以避免递归,并且更新两个列表将“更好”。 我应该使用什么设计模式? 如果添加一些代码,我将不胜感激。

您可以通过将“对象关联关注点”移动到专用类中来简化操作。 这就是我的想法。

定义一个名为AssociationTable的类。 此类将维护一对对列表,其中每对包含对A对象的引用和对B对象的引用。

每个A对象(以及每个B对象)将保存对AssociationTable对象的引用。 A.Add(B)将实现为table.add(this,b); B.Add(A)将实现为table.add(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); }
}

编辑:这个设计的问题是垃圾收集。 该表将保存对象的引用,从而压制其集合。 在Java中,您可以使用WeakReference对象来克服此问题。 我很确定在.Net世界中有类似的东西

此外,该表可以是单身人士。 我不太喜欢单身人士。 在这里,单例将使AB关联在您的程序中唯一。 这可能是不受欢迎的,但这取决于您的具体需求。

最后,(只是为了把事情放在上下文中)这种设计与关系数据库中的多对多关系的工作方式相同。

我最近写了一个类来处理类似的问题 它实际上是一个更简单的场景(父/子关系与孩子引用他们的父母),但你可能可以根据自己的需要调整它。 主要区别在于我的实现中的Parent属性应该由Parent的集合替换。

关于我唯一能想到的是使用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);
        }
    }
}

在此之后,您将删除读取“Object.Add(this);”的代码行。 和“if(bDeleted == true)Object.Delete(this);” 这也有利于减少每个方法的调用次数,因为对象A的方法被调用两次,因为对象B也在对象A上调用这些方法。

编辑:经过进一步审查,我意识到你已经在某种程度上使用了观察者设计模式。 对象A是观察者,对象B是可观察对象。 对象A维护其观察对象的列表,对象B维护观察它的对象列表。 唯一的事情是我没有看到任何额外的功能,虽然可能有一些。 基本上,对象B将通知所有对象A观察它已被更改,并且所有这些对象A将要求进行更改。 如果这是您正在寻找的,那么您需要做的就是删除行“Object.Add(this);” 和“if(bDeleted == true)Object.Delete(this);” 来自B代码,因为它是不必要的。

暂无
暂无

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

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