【问题标题】:When to hide an inheritance hierarchy in a concrete class?何时在具体类中隐藏继承层次结构?
【发布时间】:2011-08-10 13:03:16
【问题描述】:
每当我遇到工厂基于某些“低级”类型参数(例如协议或外部资源的格式)向用户返回抽象基类实现的情况时,我总是很想将抽象类转换为具有内部“策略工厂”的具体类,以便用户只需将实现类型传递给构造函数并直接使用基类。
我注意到 .Net 框架选择以这种方式实现 Socket(而不是创建 DatagramSocket,而是在构造时传递 SocketType)。在决定何时可以将层次结构扁平化为像这样的单个具体类时,有哪些指导方针?
【问题讨论】:
标签:
design-patterns
inheritance
constructor
types
factory
【解决方案1】:
我认为重点是:“客户应该了解多少底层细节?”。
如果您选择第一个解决方案(抽象基类),您将向客户端类隐藏更多细节。这样,客户端可以完全忽略底层细节(协议、外部资源的格式)。当目标是完全隐藏实现细节和实现中使用的类型时,我更喜欢这种方法。
否则,如果客户端已经知道低级实现的一些细节(例如客户端知道他将使用的套接字是 UDP 并且他也想知道那种信息),那么抽象基类方法可以是取而代之的是一个内部的“战略工厂”。
【解决方案2】:
本着“优先组合胜过继承”的精神,我总是选择策略 + 工厂方法胜过继承。这给了我几个好处:
* 大多数情况下,每个策略都可以单独测试,而无需关心将使用它的类。
* 同样,客户端类可以使用模拟策略进行测试
* 可以将策略设计为可组合的,例如使用装饰器模式,这提供了很大的灵活性,而不会导致子类的爆炸。
总而言之,如果所有子类的外部语义相同(应该如此),请遵循策略路线。