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

时间:2020-03-06 14:46:22  来源:igfitidea点击:

什么是(如果有的话)隐含的假设或者限制以及设计的不同之处,例如:

在他的:

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之前,我们必须准备好所有工作人员,而不是以后可以提供他们。当然,我们也可以提供设置器,以便以后可以更改它们。