我不明白何时应该使用复合设计模式。 我将从这种设计模式中获得哪些好处? 我访问过this website但它只告诉我设计模式的结构,而不告诉我它的使用场景。 希望对像我这样刚开始学习设计模式的程序员有所帮助。
最佳答案
复合是一种非常有用的模式,只要您可能需要有选择地将属于层次结构一部分的一组对象视为“相同”,而实际上它们是不同的。通常,所使用的示例讨论的是对叶和节点进行相同的处理,但该模式也可以扩展到异构列表。
例如,考虑去看医生。当你去看医生时,会发生各种各样的事情,你通常会先去看护士或助理,他们会测量你的体温等。然后医生会进行检查并做出诊断。然后医生可能会做一些治疗,但通常护士会回来完成治疗。访问期间还会进行不同的事件。您有重量和温度等观察结果。但例如实验室将是一个不同的对象,因为它通常需要一个样本,然后可以将其发送出去,并要求稍后记录结果。
因此,我们有允许记录所有这些的软件,它通常会创建某种带有节点的层次结构,例如:
遭遇:
考前
考试
治疗
在每个节点下,您将有各种条目,例如诊断、观察、实验室程序、诊断、注入(inject)等。
这一切都很好,你最终会得到一个结构化的、尽管非常复杂的遭遇层次记录。
现在假设您需要生成账单。突然你面临着一个非常不同的要求。需要您的医疗记录才能非常准确地描述这次遭遇。在计费中,尽管您不关心谁做了什么或按什么顺序进行,但实际上您并不关心计费代码之外的事件是什么。您只需要一个可计费事件的单一列表,即代码。
这些信息不仅嵌入在记录中,而且该记录也很难遍历,因为它包含大量不同的对象。它的层次结构也是可变的——如果你脑子里有钉子,他们可能会跳过任何类型的预检或相关检查并去接受治疗。如果您去拆线,可能不会进行任何预检查或检查。每年体检没有治疗。等等。很难枚举这种对象图。
复合模式解决了这一切。您为所有对象定义一个公共(public)接口(interface)或基类。我们称之为“CareEntry”。 CareEntry 有一个属性 BillingCode。现在,您的 Encounter 看起来像是一个简单的容器,里面除了 CareEntry 对象什么都没有。您的计费服务现在可以简单地枚举内部的所有内容,而不必担心某个对象是节点(PreExam、Exam)还是叶子(重量温度),或者该对象位于哪个节点(PreExam Exam 等)或实际类型是什么对象是(实验室、注入(inject)等)。一切都是 CareEntry 并进行统一处理 - 您只需枚举 Encounter 中的所有 CareEntry 对象并收集每个具有非空计费代码的对象即可完成。就这么简单。
关于design-patterns - 什么时候应该使用复合设计模式?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5334353/