我有一个Printer
类,应该打印number
和text
。 number
对于每个Client
类都不会改变。我还有更多Client
个具有不同number
值的对象。
哪种设计更好?
在sample1
中,数字作为参数发送到print()
方法,因此,所有Client
对象都使用单个Print
对象。在sample2
中,该数字发送到Printer
构造函数,因此每个Client
对象都有自己的Printer
对象。
请帮我弄清楚。
答案 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
参数中。