类结构模式问题。我应该选择什么?
什么是(如果有的话)隐含的假设或者限制以及设计的不同之处,例如:
在他的:
class SampleClass1 { IWorker workerA; IWorker workerB; void setWorkerA(IWorker w); void setWorkerB(IWorker w); WorkResult doWork(); }
B)与此:
class SampleClass2 { WorkResult doWork(IWorker workerA, IWorker workerB); }
我知道这取决于特定的项目,但是如果上述类是小框架的一部分,该怎么办?第一类能够维护状态并更自然地分离步骤,但是第二类确保与外部调用者的"实时通信"更加自然,因为每次调用doWork()时都会传递Worker。
是否有建议的用法或者通用做法指导上述两种方式之间的选择?谢谢。
解决方案
另外一个选择:
IWorker类:
静态WorkResult doWork(Iworker a,Iworker b);
如果不止一种方法取决于IWorker a和IWorker b,那么我说做样本A。
如果仅doWork()同时使用IWorker a和IWorker b,请执行示例B。
另外,SampleClass的真正目的是什么? doWork看起来有点像实用程序方法。
A)是一个错误的设计,因为它允许对象有缺陷(可能未设置一个或者两个工作类)。
B)可以很好。如果不依赖于SampleClass2的内部状态,则将其设置为静态
IMO第二种方法看起来更好,它要求调用者使用较少的代码来执行任务。第二种方法不太容易出错,调用者不必担心对象可能不会完全初始化。
取而代之的是定义只返回一个WorkResult并让各个类决定如何实现的WorkDelegate(或者具有单个doWork方法且没有参数的接口)的方式呢?这样,我们就不会局限于过早的决定。
SampleClass1
- 我可能需要在doWork之间保持工人的状态
- 我可能需要单独设置Worker的功能。 (先做1和2,再做2和3)
- 我想维护这些工作程序,因为可能希望在同一工作程序上多次运行doWork。
- 我不是实用程序类。我的一个实例很重要。
SampleClass2
- 给我两个工人,我将与他们一起工作。
- 我不在乎他们是谁,我也不想维护他们。
- 维护工人之间的任何配对都是别人的工作。
- 我可能更像是一个实用程序类。也许我可以是静态的。
在选项(A)中,我们正在创建所谓的功能对象或者函子,这是一个有据可查的设计模式。
两个主要优点是:
- 可以将工作人员放在一个地方,然后将对象放在其他地方
- 该对象可以在两次调用之间保留状态
同样,如果我们使用的是依赖注入框架(Spring,Guice等),则函子可以在需要时自动初始化并注入。
函数对象在库中被广泛使用,例如C ++标准模板库
另一种选择是情况A的变体,如下所示:
class SampleClass3 { SampleClass3( IWorker workerA, IWorker workerB ); WorkResult doWork(); }
好处:
- 由于需要我们提供施工时所需的所有工人(与情况A相比),因此很难使对象有缺陷。
- 我们仍然可以在SampleClass3和/或者其中一个工作程序中携带状态。 (在情况B中这是不可能的。)
缺点:
- 在构造SampleClass3之前,我们必须准备好所有工作人员,而不是以后可以提供他们。当然,我们也可以提供设置器,以便以后可以更改它们。