哪个是更好的设计?

时间:2012-12-03 16:18:26

标签: oop design-patterns

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

如果已经提出类似问题,我很抱歉,但我真的不知道在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();

5 个答案:

答案 0 :(得分:3)

像往常一样,没有完整的使用环境很难分辨,但肯定有一些优点和缺点要评估:

在第一种情况下

  • 当世界针对Actor课程进行编程时,可以很容易地将其与interfacecontract分开。正如您的代码现在可以传递Actor的子类,世界永远不会知道。这样做的好处是可以降低世界与演员之间的耦合。
  • 您正在将创建演员的责任从世界转移到世界的客户身上。这可以帮助World类实现SRP,使得更容易运行单元测试(例如传递模拟对象),并且对客户端更灵活。另一方面,这推动了在客户端上创建(并最终配置)actor实例的工作。

在第二种情况下,你会得到第一种情况的反面利弊;世界与演员紧密结合,使得配置和测试变得更加困难,但是您需要您的客户更少地了解创建演员的过程。

您可以考虑的替代方案是使用builder(如果World创建的过程是复杂的过程)或factory(如果您有不同的配置)创建不同的子类)。这可以帮助您将World类与演员分离,同时从客户端利用创建它的复杂性。

HTH

答案 1 :(得分:1)

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

但是,如果一个演员可以改变世界,或同时注册到多个世界,那么你将走向选项A.

这一切都取决于您的参考文件最终需要如何结束。

答案 2 :(得分:0)

如果对哪个班级应该承担责任有疑问,我建议您根据General Responsibility Assignment Software Patterns (GRASP)

决定

答案 3 :(得分:0)

  • 首先想到:Factory Pattern,当创建一个对象很复杂时,会定义另一个处理这个工作的类。

  • 第二:如果创建很容易,那么它可以是一个简单的构造函数,然后通过调用方法设置其中一个属性。

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

答案 4 :(得分:0)

我在两者中真正看到的唯一区别是,在B中,演员与世界联系在一起。它与A中的世界无关。如果一个演员需要在一个世界的背景之外存在,或者一个演员可以存在于多个世界中,我会投票给A。

就未来的可扩展性而言,您可能需要考虑将actor基类更改为接口。然后任何人都可以添加自己的actor类,而无需从你的基础继承。