面向对象的设计。有什么更好的?

时间:2018-12-21 14:24:37

标签: oop design-patterns solid-principles

我有一个Printer类,应该打印numbertextnumber对于每个Client类都不会改变。我还有更多Client个具有不同number值的对象。

哪种设计更好?

sample1中,数字作为参数发送到print()方法,因此,所有Client对象都使用单个Print对象。在sample2中,该数字发送到Printer构造函数,因此每个Client对象都有自己的Printer对象。

请帮我弄清楚。

UML diagram

2 个答案:

答案 0 :(得分:3)

2号似乎更符合您的要求。

在第一个解决方案中,您使用“通用” Printer,它对Client或它们的编号一无所知,因此需要使用数字作为参数。这似乎合乎逻辑,因为您在现实生活中可能拥有物理上的“打印机”,并且 不依赖于任何Client

但是,您的对象模型必须符合要求“现实生活”。这有点令人困惑,因为我们有时将“需求”称为“现实生活”。无论如何,您的要求都明确指出Client要打印一些文本,并且对于客户而言,“数字”是静态的,即无关紧要的。因此,只需进行心理更改,即Printer不是通用打印机,而是专门用于Printer的{​​{1}}。

使用这种心理模型,2.解决方案显然更适合。

答案 1 :(得分:0)

我会推荐解决方案1。

因为如果打印机不需要此编号,则不应将其放到那里。如果该数字是客户专用的,则他们应存储其个人值并将其传递给打印机。这使得打印机可以在编号可能更改的其他地方重复使用。

如果需要查询客户号码怎么办?解决方案2使您询问打印机有关客户的特定号码,无论该号码是否唯一。这不好:您违反了关注点分离。但是除此之外,它还不流畅,对吗?解决方案2会在您每次更改编号时强制您再次初始化打印机或创建一个新实例(这将如您所说)。

打印机不应该在乎它正在打印的内容。为了使代码更可重用,您可以使'Print()'方法与方法'GetData()'一起接受IPrintable。这样,打印机就不必在添加新的内容类型或内容时更改“ Print()”的签名,在这种情况下,您还可以避免方法签名中的参数过多。因此,新的内容类型仅实现IPrintable

现在您确定需要打印数字,文本和其他日期或时间戳了吗?然后,只需修改IPrintable对象或创建一个新的实现,而不是修改Printer类本身。 IPrintable对象还可以负责格式化输出。打印机也不必在意格式以使其更通用。否则,小的改动就需要您实现一台新打印机。

打印机通常具有一个队列,以允许客户端并发使用。如果您将这些信息直接存储在打印机对象中,则实现起来会更加困难。代码看起来不再漂亮了。更好地将相关数据保持在一起,例如在IPrintable参数中。