2012-12-03 76 views
2

我不想创建与World绑定的Actors。我正在考虑使用以下两个代码片段之一。其中哪一个被认为是更好的设计?我的意思是,对于源代码维护者来说更具可读性,对于只读代码的人更具可读性,对未来调整更灵活等。哪些设计更好?

对不起,如果有类似问题已经被询问,但我不知道真的不知道这个概念在OOP中被称为什么。

选项A:

// declaration: 
class World { 
    public: 
     RegisterActor(Actor* a); 
}; 

class Actor { 
    public: 
     Actor(World& w) { 
      w.RegisterActor(this); 
     } 
     foo(); 
}; 

// usage: 
World myWorld; 
Actor myActor(myWorld); 
myActor.foo(); 

选项B:

// delcaration: 
class Actor; 

class World { 
    public: 
     Actor& CreateActor(); 
} 

class Actor { 
    friend class World; 
    public: 
     foo(); 
    private: 
     Actor(); 
}; 

// usage: 
World myWorld; 
Actor& myActor = myWorld.CreateActor(); 
myActor.foo(); 
+2

无论如何,你在演员和世界之间都有循环依赖。你确定你需要吗? –

+0

不一定。选项A从不存储对世界的引用,在选项B中,“演员”从来不知道任何有关“世界”的内容。基本上我想要的是一个对象'World',它包含一个关于'World'中所有'Actor'的列表。但是,未来可能需要循环依赖。一个“演员”可能必须与所有其他的“演员”互动。 –

+0

但在代码中存在循环依赖关系。 “演员”需要知道“世界”,反之亦然。这通常是一个坏主意。 –

回答

3

像往常一样,很难说没有完整的使用环境,但也有肯定一些利弊评价:

在第一种情况下

  • 虽然世界对Actor类进行编程,它可以很容易地解耦以对interfacecontract进行工作。由于您的代码现在可以通过Actor的子类,世界永远不会知道。这样做的好处是可以降低世界与演员之间的耦合。
  • 您正在将创造演员的责任推向世界的客户。这可能有助于World类实现SRP,使运行单元测试(例如传递模拟对象)变得更加容易,并且对客户端更灵活。另一方面,这将移动创建(并最终配置)客户端上的actor实例的工作。

在第二种情况下,你会得到第一个反面优点和缺点;这个世界与演员紧密相连,使得配置和测试变得更加困难,但是你需要你的客户不那么了解创建演员的过程。

,你可以考虑另一种方法是使用builder的(如果World创作过程是一个复杂的)或factory(如果你有创造不同的子类不同的配置)。这可以帮助你保持你的类从演员脱钩,同时从客户端利用创建它的复杂性。

HTH

0
  • 第一认为:Factory Pattern,当创建一个对象是复杂的,然后另一个CL屁股将被定义处理这项工作。第二:如果创建很容易,那么它可能是一个简单的构造函数,然后通过调用一个方法来设置它的一个属性。

  • 第三:如果存在Aggregate object这是世界也许,那么你可以问他为你创建一个演员,这取决于你的域名。

0

两个我真的看到唯一的区别是,在B,一个演员被绑定到世界各地。它不与A中的世界联系在一起。如果一个演员需要在一个世界的环境之外存在,或者如果一个演员可以存在于多个世界中,那么我将投票支持A.在未来的可扩展性方面,您可能需要考虑将actor基类更改为接口。然后任何人都可以添加他们自己的演员类而不需要从你的基地继承。

1

一个演员是否永远只属于一个世界,而且始终是同一个世界?选项B最适合这种情况。它限制了Actor构造函数的可见性并使用工厂方法来构造实例。这会减少对代码客户的承诺,这意味着您可以更灵活地更改Actor的实现。它也很适合这个领域的语义 - 你用你的世界来制作Actor。

但是,如果一个演员可以改变世界,或在同一时间注册到一个以上的世界,那么你对选项A.标题

这一切都取决于你的参考需要如何结束。