美文网首页
设计模式之组合模式

设计模式之组合模式

作者: 今天写明天改 | 来源:发表于2022-05-02 11:42 被阅读0次

    背景

    随着项目的工程结构越来越庞大,每个类内部都有自己的子组件,这个时候,常见的一种需求情况是,我希望这个系统中的一个类的子组件执行一个方法,并且,子组件的子组件也要执行这个方法。这个时候一般就会用到今天的主题——组合模式。

    概念

    什么是组合模式

    组合模式是把一组对象当作一个单一的对象。比如说我们有一个如下的代码层级:

    class A: NSObject {
         var subNode = [B(), B()]
    }
    
    class B: NSObject {
         var subNode = [C(), C()]
    }
    
    class C: NSObject {
    }
    

    这个代码层级中,A类包含了两个B类,而B类包含了两个C类,那么组合模式就是把这包含了4个C类的A类当作一个C类来使用。

    用途

    让外部调用者可以不用关心对象的层级结构,使用者对单个对象和组合对象的使用具有一致性。
    什么叫一致性呢,举例:我希望B和B的所有子组件都具有一个功能(例如说‘hello’),但是,我不希望我让B和B的子组件执行功能时外部调用者不仅让B说hello,而且还要让B的子组件说hello。组合模式的用途就是,用户让C说hello需要

    C().hello() 
    

    那么用户让B和B的所有子组件说hello只需要

    B().hello()
    

    用户使用C和使用B的方式方法是一样的,这就叫一致性。

    实际应用

    我们以代码的形式来看看组合模式如何实现我们上边所述的功能。我们假设说hello这个功能就是一个简单的print()那么因为ABC都要实现这个功能,可以考虑将方法放到一个protocol中:

    protocol Say: AnyObject {
        func hello()
    }
    

    那么对于类C来说,它的hello方法很简单:

    func hello() {
        print(self.description)
    }
    

    对于类B来说,我们首先要让B打印它自己:

    class B: NSObject, Say {
         func hello() {
             var subNode = [C(), C()]
    
             print(self.description)
         }
    }
    

    然后我们需要让B的每个子组件也打印它本身:

    class B: NSObject, Say {
         var subNode = [C(), C()]
        
         func hello() {
             print(self.description)
             subNode.forEach { $0.hello() }
         }
    }
    

    同样,类A也是同样的实现:

    class A: NSObject, Say {
         var subNode = [B(), B()]
        
         func hello() {
             print(self.description)
             subNode.forEach { $0.hello() }
         }
    }
    

    这样当我们执行

    A().hello()
    

    的时候,所有A的子组件也都打印出来了。使用者就不必关心A的内部结构了。打印一组对象和打印一个对象的操作是一样的。

    总结

    所谓的组合模式,就是将一组对象,当作一个对象来处理,这组对象都有一个共同的功能或者特性,这个共同的功能,可能是都遵循某个协议,或者都继承自某个类。利用这种设计模式,我们可以做出消息派发、遍历层级等多种功能。

    相关文章

      网友评论

          本文标题:设计模式之组合模式

          本文链接:https://www.haomeiwen.com/subject/kdwmyrtx.html