类结构模式问题。我应该选择什么?

时间:2008-09-26 09:00:46

标签: class-design

隐含的假设或限制是什么(如果有的话)以及设计的差异如下:

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。

是否有任何建议的用法或通用做法可指导上述两种方式之间的选择?感谢。

8 个答案:

答案 0 :(得分:6)

<强> SampleClass1

  • 我可能需要在doWork之间保持工作人员的状态
  • 我可能需要单独设置Workers的功能。 (与1和2一起工作,然后与2和3一起工作)
  • 我想维护工作人员,因为可能会在同一个工作人员上多次运行doWork。
  • 我不是实用班。我的一个例子很重要。

<强> SampleClass2

  • 给我两个工人,我会和他们一起工作。
  • 我不在乎他们是谁,我不想保留他们。
  • 维持工人之间的任何配对都是别人的工作。
  • 我可能更像是一个实用类。也许我可以保持静止。

答案 1 :(得分:5)

在选项(A)中,您正在创建所谓的函数对象或函数,这是一个well documented的设计模式。

两个主要优点是:

  • 可以在一个地方设置工人,然后在其他地方使用对象
  • 对象可以在调用之间保持状态

此外,如果您使用依赖注入框架(Spring,Guice等...),可以在任何需要的地方自动初始化仿函数。

函数对象广泛用于库中,例如C ++标准模板库

答案 2 :(得分:2)

另一个选项,案例A的变体,如下:

class SampleClass3
{
    SampleClass3( IWorker workerA, IWorker workerB );
    WorkResult doWork();
}

优点:

  • 由于您需要在施工时提供所需的所有工人(与案例A相反),因此难以使对象有缺陷。

  • 您仍然可以在SampleClass3和/或其中一个工作人员中携带状态。 (在B情况下这是不可能的。)

缺点:

  • 在构建SampleClass3之前,您必须准备好所有工作者,而不是以后能够提供它们。当然,您也可以提供设置器,以便以后更改它们。

答案 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并让各个类决定它们如何实现它?这样,你就不会把自己局限于过早的决定。