• 组合模式(Composite Pattern)


    一、 组合(Composite)模式

    组合模式允许你将对象组合成树形结构来表现”部分-整体“的层次结构,使得客户以一致的方式处理单个对象以及对象的组合。下面我们用绘制的例子来详细介绍组合模式,图形可以由一些基本图形元素组成(如直线,圆等),也可以由一些复杂图形组成(由基本图形元素组合而成),为了使客户对基本图形和复杂图形的调用保持一致,我们使用组合模式来达到整个目的。

    组合模式实现的最关键的地方是——简单对象和复合对象必须实现相同的接口。这就是组合模式能够将组合对象和简单对象进行一致处理的原因。

    二、组合模式的结构

    Component为组合中的对象声明接口,在适当情况下,实现所有类共有接口的默认行为。声明一个接口用于访问和管理Component的子部件。

        abstract class Component
        {
            protected string name;
    
            public Component(string name)
            {
                this.name = name;
            }
    
            public abstract void Add(Component c);
            public abstract void Remove(Component c);
            public abstract void Display(int depth);
        }

    Leaf在组合中标识叶节点对象,叶节点没有子节点。

        class Leaf : Component
        {
            public Leaf(string name)
                : base(name)
            { }
    
            public override void Add(Component c)
            {
                Console.WriteLine("Cannot add to a leaf");
            }
    
            public override void Remove(Component c)
            {
                Console.WriteLine("Cannot remove from a leaf");
            }
    
            public override void Display(int depth)
            {
                Console.WriteLine(new String('-', depth) + name);
            }
        }

    Composite定义有枝节点行为,用来存储子部件,在Composite接口中实现与子部件有关的操作,比如增加ADD和删除Remove。

        class Composite : Component
        {
            private List<Component> children = new List<Component>();
    
            public Composite(string name)
                : base(name)
            { }
    
            public override void Add(Component c)
            {
                children.Add(c);
            }
    
            public override void Remove(Component c)
            {
                children.Remove(c);
            }
    
            public override void Display(int depth)
            {
                Console.WriteLine(new String('-', depth) + name);
    
                foreach (Component component in children)
                {
                    component.Display(depth + 2);
                }
            }
        }

    客户端代码:

       class Program
        {
            static void Main(string[] args)
            {
                Composite root = new Composite("root");
                root.Add(new Leaf("Leaf A"));
                root.Add(new Leaf("Leaf B"));
    
                Composite comp = new Composite("Composite X");
                comp.Add(new Leaf("Leaf XA"));
                comp.Add(new Leaf("Leaf XB"));
    
                root.Add(comp);
    
                Composite comp2 = new Composite("Composite XY");
                comp2.Add(new Leaf("Leaf XYA"));
                comp2.Add(new Leaf("Leaf XYB"));
    
                comp.Add(comp2);
    
                root.Add(new Leaf("Leaf C"));
    
                Leaf leaf = new Leaf("Leaf D");
                root.Add(leaf);
                root.Remove(leaf);
    
                root.Display(1);
    
                Console.Read();
            }
        }

    结果显示:

    三、透明方式与安全方式

    透明方式:在Ccomponent中声明所有用来管理子对象的方法,其中包括ADD,Remove等。这样实现Component接口的所有子类都具备了Add,Remove。这样做的好处就是叶节点和枝节点对于外界没有区别,他们具备完全一致的行为接口。但为题也很明显,因为Leaf类本身不具备Add(),Remove()方法功能,所以实现他是没有意义。

    安全方式:在Component接口中不去声音Add,Remove 方法,那么子类的Left就不需要去实现它,而是在Compostie生硬所有用来管理子类对象的方法,这样做就不会出现上面的问题,不过由于不够透明,所有树叶和树枝类将不具有相同的接口,客户端调用需要做相应的判断,带来的不方便。

    四、组合模式的优缺点

    优点:

    1. 组合模式使得客户端代码可以一致地处理对象和对象容器,无需关系处理的单个对象,还是组合的对象容器。
    2. 将”客户代码与复杂的对象容器结构“解耦。
    3. 可以更容易地往组合对象中加入新的构件。

    缺点:使得设计更加复杂。客户端需要花更多时间理清类之间的层次关系。(这个是几乎所有设计模式所面临的问题)。

    五、组合模式的使用场景

    在以下情况下应该考虑使用组合模式:

    1. 需要表示一个对象整体或部分的层次结构。
    2. 希望用户忽略组合对象与单个对象的不同,用户将统一地使用组合结构中的所有对象。
  • 相关阅读:
    centos nginx 405错误
    使用Python自带模块发送邮件
    centos 文件权限问题chmod
    Python发送企业微信群机器人消息
    centos 如何查看用户
    linux中的.bashrc文件
    gunicorn的用法
    测试内容上线之后,要进行线上验证和持续的跟进,这应该变成一个职业习惯,这是为了自己的事情负责
    测试平台使用git+Jenkins进行持续集成
    Nginx配置使用详解
  • 原文地址:https://www.cnblogs.com/gzskys/p/5743045.html
Copyright © 2020-2023  润新知