Android设计模式详解之组合模式

前言

组合模式也称为部分整体模式,结构型设计模式之一;

定义:将对象组合成树形结构以表示“部分-整体”的层次结构,使得用户对单个对象和组合对象的使用具有一致性;

使用场景:

  • 表示对象的部分-整体的层次结构时;
  • 从一个整体中能够独立出部分模块或功能的场景;

安全的组合模式

安全组合模式的UML类图:
安全组合模式的UML
Component:抽象根节点,对组合中的对象声明接口。在适当的情况下,实现所有类共有接口的缺省行为。声明一个接口用于访问和管理Component的子节点。可在递归结构中定义一个接口,用于访问一个父节点,并在合适的情况下实现它。

Composite:定义有子节点的那些枝干节点的行为,存储子节点,在Component接口中实现与子节点有关的操作;

Leaf:在组合中表示叶子节点对象,叶子节点没有子节点,在组合中定义节点对象的行为;

Client:通过Component接口操纵组合节点的对象;

模板代码

  • 定义抽象根节点,Component
abstract class Component(val name: String) {

    /**
     * 具体的逻辑交给子节点实现
     */
    abstract fun doSomething()
}
  • 定义具体枝干节点,Composite
class Composite(name: String) : Component(name) {
    //存储节点的容器
    private val components = arrayListOf<Component>()
    override fun doSomething() {
        println("枝干节点名称:$name")
        for (component in components) {
            component.doSomething()
        }
    }

    /**
     * 添加子节点
     * @param c 子节点
     */
    fun addChild(c: Component) {
        components.add(c)
    }

    /**
     * 获取子节点
     * @param index 子节点对应下标
     */
    fun getChildren(index: Int) {
        components[index]
    }

    /**
     * 移除子节点
     * @param c 子节点
     */
    fun removeChild(c: Component) {
        components.remove(c)
    }

}
  • 定义叶子节点,Leaf
class Leaf(name: String) : Component(name) {

    override fun doSomething() {
        println("叶子节点名称:$name")
    }
}
  • 编写调用测试类
object Test {

    @JvmStatic
    fun main(args: Array<String>) {
        //构造一个根节点
        val root = Composite("root")
        //构造两个枝干节点
        val branch1 = Composite("branch1")
        val branch2 = Composite("branch2")
        //构造叶子节点
        val leaf1 = Leaf("leaf1")
        val leaf2 = Leaf("leaf2")
        val leaf3 = Leaf("leaf3")
        val leaf4 = Leaf("leaf4")
        //添加叶子节点
        branch1.addChild(leaf1)
        branch1.addChild(leaf2)
        branch2.addChild(leaf3)
        branch2.addChild(leaf4)
        //添加枝干节点
        root.addChild(branch1)
        root.addChild(branch2)
        root.doSomething()
    }

}

结果输出:

枝干节点名称:root
枝干节点名称:branch1
叶子节点名称:leaf1
叶子节点名称:leaf2
枝干节点名称:branch2
叶子节点名称:leaf3
叶子节点名称:leaf4

优点:结构清晰明了,逻辑容易理解;

缺点:违背依赖倒置原则,定义的抽象Component在调用时并没有起到作用,而是直接依赖的具体细节类;

我们将组合所使用到的方法addChild、removeChild、getChild定义到抽象类中,得到的是透明的组合模式

透明的组合模式

透明组合模式UML类图:
透明组合模式UML类图

模板代码

  • 定义抽象根节点,Component
abstract class Component(val name: String) {

    /**
     * 具体的逻辑交给子节点实现
     */
    abstract fun doSomething()

    /**
     * 添加子节点
     */
    abstract fun addChild(c: Component)

    /**
     * 移除子节点
     */
    abstract fun removeChild(c: Component)

    /**
     * 获取子节点
     */
    abstract fun getChildren(index: Int)
}
  • 定义具体枝干节点,Composite
class Composite(name: String) : Component(name) {
    //存储节点的容器
    private val components = arrayListOf<Component>()
    override fun doSomething() {
        println("枝干节点名称:$name")
        for (component in components) {
            component.doSomething()
        }
    }

    /**
     * 添加子节点
     * @param c 子节点
     */
    override fun addChild(c: Component) {
        components.add(c)
    }

    /**
     * 获取子节点
     * @param index 子节点对应下标
     */
    override fun getChildren(index: Int) {
        components[index]
    }

    /**
     * 移除子节点
     * @param c 子节点
     */
    override fun removeChild(c: Component) {
        components.remove(c)
    }

}
  • 定义叶子节点,Leaf
class Leaf(name: String) : Component(name) {

    override fun doSomething() {
        println("叶子节点名称:$name")
    }

    override fun addChild(c: Component) {
        throw  UnsupportedOperationException("叶子节点没有子节点")
    }

    override fun removeChild(c: Component) {
        throw  UnsupportedOperationException("叶子节点没有子节点")
    }

    override fun getChildren(index: Int) {
        throw  UnsupportedOperationException("叶子节点没有子节点")
    }
}
  • 编写测试类
object Test {

   @JvmStatic
   fun main(args: Array<String>) {
       //构造一个根节点
       val root = Composite("root") as Component
       //构造两个枝干节点
       val branch1 = Composite("branch1") as Component
       val branch2 = Composite("branch2") as Component
       //构造叶子节点
       val leaf1 = Leaf("leaf1") as Component
       val leaf2 = Leaf("leaf2") as Component
       val leaf3 = Leaf("leaf3") as Component
       val leaf4 = Leaf("leaf4") as Component
       //添加叶子节点
       branch1.addChild(leaf1)
       branch1.addChild(leaf2)
       branch2.addChild(leaf3)
       branch2.addChild(leaf4)
       //添加枝干节点
       root.addChild(branch1)
       root.addChild(branch2)
       root.doSomething()
   }

}

结果输出:

枝干节点名称:root
枝干节点名称:branch1
叶子节点名称:leaf1
叶子节点名称:leaf2
枝干节点名称:branch2
叶子节点名称:leaf3
叶子节点名称:leaf4

优点:满足依赖倒置原则,细节依赖于抽象;
缺点:叶子节点没有子节点,无法操作,覆盖的抽象方法是多余的;

Android源码中的组合模式

  • View树结构
    View树UML图

总结

优点:组合模式可以清楚地定义分层次的复杂对象,表示对象的全部或部分层次,它让高层模块忽略了层次的差异,方便对整个层次结构进行控制;

缺点:在新增构件时不好对枝干中的构件类型进行限制,不能依赖类型系统来施加约束,因为大多情况下,他们都来自于相同的抽象层;

结语

如果以上文章对您有一点点帮助,希望您不要吝啬的点个赞加个关注,您每一次小小的举动都是我坚持写作的不懈动力!ღ( ´・ᴗ・` )

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值