Oop 以下哪一项是更好的设计?
我不想创造一个与世界息息相关的演员。我正在考虑使用以下两个代码片段之一。哪一个被认为是更好的设计?我所说的更好,是指对源代码维护者来说更具可读性,对仅仅阅读代码的人来说更具可读性,对将来的调整更灵活,等等 如果已经有人问过类似的问题,我很抱歉,但我真的不知道像这样的概念在OOP中叫什么 备选方案A:Oop 以下哪一项是更好的设计?,oop,design-patterns,Oop,Design Patterns,我不想创造一个与世界息息相关的演员。我正在考虑使用以下两个代码片段之一。哪一个被认为是更好的设计?我所说的更好,是指对源代码维护者来说更具可读性,对仅仅阅读代码的人来说更具可读性,对将来的调整更灵活,等等 如果已经有人问过类似的问题,我很抱歉,但我真的不知道像这样的概念在OOP中叫什么 备选方案A: // declaration: class World { public: RegisterActor(Actor* a); }; class Actor { pu
// 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();
当对哪一类应包含责任有疑问时,我建议您根据决定当对哪一类应包含责任有疑问时,我建议您根据 首先,当创建一个对象很复杂时,将定义另一个类来处理此作业 第二:如果创建很容易,那么它可以是一个简单的构造函数,然后通过调用方法设置它的一个属性 第三:如果存在一个可能的世界,那么你可以让他为你创造一个演员,这取决于你的领域 首先,当创建一个对象很复杂时,将定义另一个类来处理此作业 第二:如果创建很容易,那么它可以是一个简单的构造函数,然后通过调用方法设置它的一个属性 第三:如果存在一个可能的世界,那么你可以让他为你创造一个演员,这取决于你的领域
通常,如果没有完整的使用上下文,很难判断,但肯定有一些优点和缺点需要评估: 在第一种情况下 虽然世界是针对Actor类编程的,但它可以很容易地解耦以针对or。正如您的代码现在所示,您可以传递一个Actor的子类,而世界永远不会知道。这样做的好处是可以降低世界与其参与者之间的耦合。 你正在把创造演员的责任从世界转移到世界的客户身上。这可能有助于世界级实现,使运行单元测试(例如,传递模拟对象)更容易,并且对客户端更灵活。另一方面,这将移动在客户端上创建并最终配置actor实例的工作。 在第二种情况下,你得到了第一种情况的正反两面;世界与参与者紧密耦合,使得配置和测试变得更加困难,但您需要客户机对创建参与者的过程了解得更少
你可以考虑的另一个选择是,如果一个世界创造的过程是一个复杂的过程,或者如果你有不同的配置来创建不同的子类,则使用A。这可以帮助您保持与参与者的世界级解耦,同时利用客户端创建它的复杂性
HTH通常,如果没有完整的使用上下文,很难判断,但肯定有一些优点和缺点需要评估: 在第一种情况下 虽然世界是针对Actor类编程的,但它可以很容易地解耦以针对or。正如您的代码现在所示,您可以传递一个Actor的子类,而世界永远不会知道。这样做的好处是可以降低世界与其参与者之间的耦合。 你正在把创造演员的责任从世界转移到世界的客户身上。这可能有助于世界级实现,使运行单元测试(例如,传递模拟对象)更容易,并且对客户端更灵活。另一方面,这将移动在客户端上创建并最终配置actor实例的工作。 在第二种情况下,你得到了第一种情况的正反两面;世界与参与者紧密耦合,使得配置和测试变得更加困难,但您需要客户机对创建参与者的过程了解得更少
你可以考虑的另一个选择是,如果一个世界创造的过程是一个复杂的过程,或者如果你有不同的配置来创建不同的子类,则使用A。这可以帮助您保持与参与者的世界级解耦,同时利用客户端创建它的复杂性
HTH我在这两者中真正看到的唯一区别是,在B中,演员与世界息息相关。如果一个演员需要存在于一个世界之外,或者一个演员可以存在于多个世界中,我会投a的票
在未来扩展性方面,您可能需要考虑将Actudio基类更改为接口。然后,任何人都可以添加自己的actor类,而无需从您的基础继承。
我真正看到的唯一区别是,在B中,actor与世界绑定。如果一个演员需要存在于一个世界之外,或者一个演员可以存在于多个世界中,我会投a的票 关于未来的广度,你可能想考虑改变。接口的参与者基类。然后,任何人都可以添加自己的actor类,而无需从您的基础继承。一个actor在任何时候都只属于同一个世界,并且总是属于同一个世界吗?选项B最适合这种情况。它限制了参与者构造函数的可见性,并使用工厂方法来构造实例。这就减少了对代码客户机的承诺,这意味着您可以更灵活地更改Actor的实现。它也非常符合领域的语义——您使用您的世界来创建参与者 然而,如果一个演员可以改变世界,或者同时注册到多个世界,那么你就朝着选项A前进
这完全取决于你的推荐信的结局。一个演员在任何时候都只属于同一个世界,而且总是属于同一个世界吗?选项B最适合这种情况。它限制了参与者构造函数的可见性,并使用工厂方法来构造实例。这就减少了对代码客户机的承诺,这意味着您可以更灵活地更改Actor的实现。它也非常符合领域的语义——您使用您的世界来创建参与者 然而,如果一个演员可以改变世界,或者同时注册到多个世界,那么你就朝着选项A前进
这完全取决于你的引用需要如何结束。在任何情况下,参与者和世界之间都存在循环依赖关系。你确定你需要吗?不一定。选项A从不存储对世界的引用,而在选项B中,演员实际上对世界一无所知。基本上,我想要的是一个对象世界,包含世界上所有参与者的列表。然而,将来可能需要循环依赖关系。一个参与者可能必须与所有其他参与者交互,但代码中存在循环依赖关系。演员需要了解世界,反之亦然。这通常是个坏主意。在任何情况下,演员和世界之间都存在循环依赖关系。你确定你需要吗?不一定。选项A从不存储对世界的引用,而在选项B中,演员实际上对世界一无所知。基本上,我想要的是一个对象世界,包含世界上所有参与者的列表。然而,将来可能需要循环依赖关系。一个参与者可能必须与所有其他参与者交互,但代码中存在循环依赖关系。演员需要了解世界,反之亦然。这通常是个坏主意。