组合模式学习总结

目录

 

组合模式

引言

定义

组合模式结构图

组合模式实例-产品生产准备

实例描述

实例类图

代码实现

组合模式的扩展

透明组合模式

安全组合模式

抽象叶子类和抽象容器类

总结

模式优点

模式缺点


组合模式

引言

在面向对象系统中,我们常常会遇到一类具有“容器”特征的对象,它们在充当普通对象的同时,又可以作为其他对象的容器,这些对象称为容器对象,而那些只能充当普通对象的对象则称为叶子对象。如Windows操作系统中,文件包括不同类型的具体文件和文件夹俩类对象,其中文件夹中可以包含子文件夹,也可以包含文件。文件夹是容器类,而不同类型的的各种文件是叶子类。组合模式将容器对象和叶子对象进行递归组合,用户在使用时无需对他们进行区分,可以一致的对待容器对象和叶子对象。

组合模式重要等级★★★★☆          组合模式难度等级★★★☆☆

定义

英文定义:"Compose object into tree structure to represent part-whole hierarchies. Composite lets clients treat individual objects and compositions of objects uniformly.".

组合多个对象形成树形结构以表示“整体-部分”的结构层次。客户端对单个对象(叶子对象)和组合对象(容器对象)的使用具有一致性。

组合模式结构图

组合模式主要包含以下角色:

(1)Conponent(抽象构件):可以是接口或者抽象类,为叶子构件和容器构件对象声明接口,在该角色中可以包含所有子类共有行为的声明和实现。

(2)Leaf(叶子构件):叶子构件在组合模式中标识叶子节点对象,没有子节点。

(3)Composite(容器构件):容器构件包含子节点,子节点既可以是叶子构件,也可以是容器构件。

组合模式实例-产品生产准备

实例描述

生产某种产品(Product)之前,需要将指定的物料和资源(Resource)准备好,其中物料也可能是某种产品。用组合模式设计该系统。

实例类图

通过分析,该实例类图如下图所示。

 

代码实现

抽象构件类

abstract class AbstractComponent
{
    private string name;

    protected List<AbstractComponent> childs = new List<AbstractComponent>();

    public string Name { get => name; set => name = value; }

    protected AbstractComponent(string name)
    {
        this.Name = name;
    }

    public void AddChild(AbstractComponent child)
    {
        childs.Add(child);
    }

    public void RemoveChild(AbstractComponent child)
    {
        childs.Remove(child);
    }

    public abstract void Produce();
}

产品类Product

class Product : AbstractComponent
{
    public Product(string name) : base(name) { }

    public override void Produce()
    {
        Console.WriteLine("[{0}]开始生产", this.Name);
        foreach (AbstractComponent c in childs)
        {
            c.Produce();
        }
        Console.WriteLine("[{0}]生产完成",this.Name);
    }
}

设备资源类Resource

class Resource : AbstractComponent
{
    public Resource(string name) : base(name) { }

    public override void Produce()
    {
        Console.WriteLine("生产过程中使用设备:[{0}]",this.Name);
    }
}

测试代码

class Program
{
    static void Main(string[] args)
    {
        AbstractComponent p1 = new Product("自行车");
        AbstractComponent p2 = new Product("车轮");
        AbstractComponent p3 = new Product("车架");
        AbstractComponent r1 = new Resource("扳手");
        AbstractComponent r2 = new Resource("螺丝刀");
        AbstractComponent r3 = new Resource("抛光枪");

        p1.AddChild(p2);
        p1.AddChild(p3);

        p1.AddChild(r3);

        p2.AddChild(r2);
        p2.AddChild(r1);

        p1.Produce();
        Console.WriteLine("--------------------------");
        p2.Produce();

        Console.ReadKey();
    }

}

运行结果

组合模式的扩展

透明组合模式

叶子对象和容器对象提供的方法是完全一致的。客户端在使用的时候无需区分构件的类型。客户端在使用的时候可以完全面向抽象编程(即透明)。透明组合模式如下图所示:

安全组合模式

叶子对象和容器对象在本质上是不同的,对于叶子对象,客户端不应该调用任何用于管理成员对象的方法(如AddChild(),RemoveChild()等)。这些方法在运行阶段如果调用,是无意义的,可能会出错。因此,安全组合模式在抽象构件中没有声明任何管理成员对象的方法,而是在容器类中声明,这种做法是安全的,缺点就是不够透明,客户端无法完全面向抽象层编程。安全组合模式如下图所示:

抽象叶子类和抽象容器类

如下图所示,我们对叶子节点和容器节点进行抽象,得到抽象叶子节点和抽象容器节点构件。在这样的结构下,因为我们对节点进行更具体的分类,所以可以将透明组合模式和安全组合模式混合使用,构建出更合理的层次结构。在JAVA AWT/Swing中存在类似结构,很多叶子构件和容器构件都拥有子类,如叶子构件TextComponent又有子类TextField、TextArea等,而容器构件Container又有Panel、Windows等子类;

总结

模式优点

(1)组合模式可以清楚地定义分层次的复杂对象,表示对象的全部或部分层次,使得增加新构件也更容易,因为它让客户忽略了层次的差异,而它的结构又是动态的,提供了对象管理的灵活接口,因此组合模式可以方便地对层次结构进行控制。

(2)客户端调用简单,因为组合模式使客户端对单个对象和组合对象的使用具有一致性。

(3)可以形成复杂的树形结构

(4)更容易在组合体中加入对象构件,客户端不必因为加入了新对象构件而更改原有代码。

模式缺点

(1)设计较抽象,如果对象的业务规则很复杂,则实现组合模式具有很大的挑战性,而且不是所有的方法都与叶子对象子类有关联。

(2)很难对容器中的构件进行限制,因为他们来自相同的抽象层,在这种情况下,必须通过在运行时进行类型检查来实现,这个实现过程较为复杂。


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值