0

最近我一直在尝试遵循 TDD 方法,这会产生很多子类,以便可以轻松地模拟依赖项等。

例如,我可以说 aRecurringProfile它又具有可以应用于它的方法/操作,例如MarkAsCancelRenewProfileMarkAsExpired等。由于 TDD,这些被实现为“小”类,例如MarkAsCancelService等。

为可以在 a 上执行的各种方法/操作创建一个“外观”(单例)是否有意义RecurringProfile,例如具有一个 class RecurringProfileFacade。这将包含方法,这些方法将代码委托给实际的子类,例如:

public class RecurringProfileFacade
{
    public void MarkAsCancelled(IRecurringProfile profile)
    {
        MarkAsCancelledService service = new MarkAsCancelledService();
        service.MarkAsCancelled(profile);
    }
    public void RenewProfile(IRecurringProfile profile)
    {
        RenewProfileService service = new RenewProfileService();
        service.Renew(profile);
    }
    ...
}

请注意,上面的代码不是实际代码,实际代码将使用构造函数注入的依赖项。这背后的想法是,此类代码的使用者不需要知道他们需要调用哪些类/子类的内部细节,而只需访问相应的“外观”。

首先,这是“外观”模式,还是其他形式的设计模式?

如果上述内容有意义,那么接下来的另一个问题是——考虑到它们没有任何特定的业务逻辑功能,你会对这些方法进行单元测试吗?

4

4 回答 4

2

如果您打算将代码作为库公开给其他人,我只会创建这样的外观。您可以创建一个外观,它是其他人使用的界面。

这将为您提供一些稍后更改实现的能力。

如果不是这样,那么这个门面提供了什么目的?如果一段代码想要调用外观上的一个方法,它将依赖于整个外观。最好保持较小的依赖关系,因此调用代码会更好地依赖MarkAsCancelledServicetha one on RecurringProfileFacade

于 2012-11-29T11:16:26.257 回答
0

如果您的设计“告诉”您可以使用 aSingleton为您做一些工作,那么它可能是糟糕的设计。TDD 应该使您远离考虑使用单例。

可以在维基百科上找到为什么这是一个坏主意(或者可以是一个好主意)的原因

我对你的问题的回答是:看看其他模式!例如UnitOfWorkStrategyMediator并尝试使用这些模式实现相同的功能,您将能够比较每种模式的好处。你可能最终会得到一个UnitOfStrategicMediationFacade或其他东西;-)

考虑在Code Review上发布这些问题以进行更深入的分析。

于 2012-11-28T15:53:38.200 回答
0

在我看来,这是一种外观模式,因为您在简单的方法后面抽象您的服务,尽管外观模式通常在他们的方法背后有更多的逻辑。原因是外观模式的目的是在更大的代码体上提供简化的接口。

至于您的第二个问题,我总是对所有内容进行单元测试。但是,就您而言,这取决于您取消或更新配置文件时它是否会改变项目的状态?因为您可以断言状态确实按照您的预期发生了变化。

于 2012-11-28T14:49:43.830 回答
0

面对这类问题时,我通常会尝试从 YAGNI/KISS 的角度进行推理:

  • 你首先需要MarkAsCancelServiceMarkAsExpiredService之类的吗?这些行动本身不会有更好的RecurringProfile归宿吗?

您说这些服务是您的 TDD 流程的副产品,但 TDD 1.并不意味着剥离所有逻辑的业务实体,并且2.如果您确实将某些逻辑外部化,则不必进入服务。如果您无法为提取的类提供比 [BehaviorName]Service 更好的名称,这通常表明您应该停止并重新考虑是否应该真正提取行为。

简而言之,你的对象应该保持凝聚力,这意味着它们不应该封装太多的责任,但也不应该变得乏力

  • 假设这些服务是合理的,你真的需要他们的 Facade 吗?如果它只是开发人员的便捷捷径,是否值得额外维护(其中一项服务的更改会导致外观发生更改)?如果其中一项服务的每个消费者都知道如何直接利用该服务,这不是更简单吗?

如果上述内容有意义,那么接下来的另一个问题是——考虑到它们没有任何特定的业务逻辑功能,你会对这些方法进行单元测试吗?

单元测试样板代码确实很痛苦。有些人会承受这种痛苦,而另一些人则认为这不值得。由于此类代码的重复性和可预测性,一个很好的折衷方案是自动生成测试,甚至更好的是自动生成所有样板代码。

于 2012-11-28T16:06:41.890 回答