隐含的假设或限制是什么(如果有的话)以及设计的差异如下:
A)这个:
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。
是否有任何建议的用法或通用做法可指导上述两种方式之间的选择?感谢。
答案 0 :(得分:6)
<强> SampleClass1 强>
<强> SampleClass2 强>
答案 1 :(得分:5)
在选项(A)中,您正在创建所谓的函数对象或函数,这是一个well documented的设计模式。
两个主要优点是:
此外,如果您使用依赖注入框架(Spring,Guice等...),可以在任何需要的地方自动初始化仿函数。
函数对象广泛用于库中,例如C ++标准模板库
答案 2 :(得分:2)
另一个选项,案例A的变体,如下:
class SampleClass3 { SampleClass3( IWorker workerA, IWorker workerB ); WorkResult doWork(); }
优点:
由于您需要在施工时提供所需的所有工人(与案例A相反),因此难以使对象有缺陷。
您仍然可以在SampleClass3和/或其中一个工作人员中携带状态。 (在B情况下这是不可能的。)
缺点:
答案 3 :(得分:1)
如果多个方法依赖于IWorker a和IWorker b,我说要做样本A.
如果只有doWork()同时使用IWorker a和IWorker b,那么请做样本B.
此外,SampleClass的真正目的是什么? doWork看起来有点像实用工具方法,而不是其他任何东西。
答案 4 :(得分:1)
A)是一个糟糕的设计,因为它允许对象有缺陷(可能没有设置一个或两个工人类)。
B)可以很好。如果您不依赖于SampleClass2的内部状态
,请将其设置为静态答案 5 :(得分:0)
另一种选择:
IWorker类:
静态WorkResult doWork(Iworker a,Iworker b);
答案 6 :(得分:0)
IMO第二种方法看起来更好,它要求调用者使用更少的代码来执行任务。第二种方法不易出错,调用者不必担心对象可能没有完全初始化。
答案 7 :(得分:0)
如何定义一个WorkDelegate
(或者一个没有参数的单个doWork
方法的接口),只返回一个WorkResult
并让各个类决定它们如何实现它?这样,你就不会把自己局限于过早的决定。