【问题标题】:OO design choice and single responsibility principleOO设计选择与单一职责原则
【发布时间】:2014-04-15 10:09:42
【问题描述】:

我目前正在重构一个应用程序,它本质上是定期从各种来源(http、ftp、sql 等)下载内容。有一个时间表可以控制应用程序可以处于活动状态的时间。例如,它可以在上午 8 点到下午 16 点之间下载内容。该应用程序一直使用面向对象的语言 (C#) 编写。

这是我在第一次迭代中提出的一般设计:

Scheduler 类将负责遵守一般时间表。它在预定周期开始时开始下载,并在结束时停止。 Scheduler 包含许多 ITask 实现,每个实现都有自己的下载任务。我创建了一个抽象基类实现,它定期调用受保护的抽象方法“StartDownload”。 Task 的子类只会实现这个方法,不用担心时间和调度问题。

到目前为止,一切都很好。但是在对 Task 基类进行 TDD 时,我意识到实际上很难模拟 StartDownload 的行为。当任务的计时器计时,它应该只在完成上一次下载迭代时才调用 StartDownload。但由于这些是实现细节,因此很难模拟。

这让我想知道 Task 类是否实际上没有违反单一职责原则。毕竟,它负责 StartDownload 的定期调用。 StartDownload 方法负责实际下载。所以我想出了一个更分离的设计:

这里任务类的职责仅限于定期调用客户端。客户的唯一责任是下载内容。测试 Task 类现在会更容易,因为我可以注入一个 IDownloadClient 模拟。

我确实想知道这是否实际上是一个更清晰的设计...... Task 类现在看起来有点奇怪,它只是一个没有任何子类的单一实现。大家觉得呢?

【问题讨论】:

  • 这个问题最适合CodeReview
  • 啊,是的,我记得有类似的东西,但我找不到。我会把它放在那里,谢谢!

标签: c# design-patterns single-responsibility-principle


【解决方案1】:

调度程序包含许多 ITask 实现,每个 有自己的一点下载要做。

我认为您正在混合两个对象,我将其命名为任务和下载。每个任务可以执行多个下载吗?在这种情况下,您的第二个设计更合适,但我缺少 Task 和 IDownloadClient 之间的聚合关系。

如果每个任务只占一次下载,那么我会重构第一个设计以确保调度程序实际处理所有任务 - 我的意思是,LastDownload 和 NextDownload 代表什么?

【讨论】:

  • 任务和下载是一对一的关系。所以每个任务执行一次下载,可以这么说。你会如何重构第一个设计呢?在实践中,所有 Task 实例都将被添加到单个 Scheduler 实例中并从那里启动/停止。
  • @PJanssen 您为Task 抽象基类描述的逻辑听起来像是Scheduler 应该负责的事情。应该是他安排开始/停止并跟踪 Last/NextDownload。
  • 是的,我也考虑过。那么第二个设计中Task的逻辑(即周期性调用一个方法)会包含在Scheduler中。它必须保留一组计时器对象并管理它们,因为任务可能以不同的时间间隔运行。这可能会让它更难连接到 UI 中,而这正是我最终想要做的。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-01-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多