C#设计模式:12.组合模式 u3d学习总结笔记本

组合模式(Composite Pattern)

组合模式依据树形结构来组合对象,用来表示部分以及整体层次。这种类型的设计模式属于结构型模式,它创建了对象组的树形结构。

这种模式创建了一个包含自己对象组的类。该类提供了修改相同对象组的方式。

在软件开发中我们经常会遇到处理部分与整体的情况,如我们经常见到的树形菜单,一个菜单项的子节点可以指向具体的内容,也可以是子菜单。类似的情况还有文件夹,文件夹的下级可以是文件夹也可以是文件。

组合模式可以很好地解决这类问题,组合模式通过让树形结构的叶子节点和树枝节点使用同样的接口,结合递归的思想来处理部分与整体关系,这种方式模糊了简单对象(叶子)和对象组(树枝)间的概念,让我们可以像处理单个对象一样去处理对象组。

优点:

  1. 高层模块(客户端)调用简单。组合模式使得客户端代码可以一致地处理单个对象和组合对象,无须关心自己处理的是单个对象,还是组合对象,这简化了客户端代码;
  2. 节点自由增加,更容易在组合体内加入新的对象,客户端不会因为加入了新的对象而更改源代码,满足“开闭原则”;

缺点:

  1. 在使用组合模式时,其叶子和树枝的声明都是实现类,而不是接口,违反了依赖倒置原则
  2. 设计较复杂,客户端需要花更多时间理清类之间的层次关系;
  3. 不容易限制容器中的构件;
  4. 不容易用继承的方法来增加构件的新功能;

组成元素:

  1. 抽象构件角色(Component):是组合中对象声明接口,实现所有类共有接口的默认行为。
  2. 树叶构件角色(_File):上述提到的单个对象,叶节点没有子节点。
  3. 树枝构件角色(_Folder):定义有子部件的组合部件行为,存储子部件,在Component接口中实现与子部件有关的操作。
  4. 客户端(Client):使用 Component 部件的对象。

抽象组合部件:

/// <summary>
/// 抽象组合部件
/// </summary>
public abstract class Component
{
    protected string name; //部件名字

    public Component(string name)
    {
        this.name = name;
    }

    public abstract Component add(Component component);
    public abstract Component Remove(Component component);
    public abstract Component Show(int index = 0);
}

具体组合部件:文件夹(树枝)

/// <summary>
/// 具体组合部件:文件夹
/// </summary>
public class _Folder : Component
{
    List<Component> children = new List<Component>();
    public _Folder(string name) : base(name) { }

    public override Component add(Component component)
    {
        children.Add(component);
        return this;
    }

    public override Component Remove(Component component)
    {
        children.Remove(component);
        return this;
    }

    public override Component Show(int index = 0)
    {
        Debug.Log(new string(' ', index * 4) + "【" + name + "】");

        foreach (Component component in children)
        {
            component.Show(index + 1);
        }
        return this;
    }
}

具体组合部件:文件(树叶)

/// <summary>
/// 具体组合部件:文件
/// </summary>
public class _File : Component
{
    public _File(string name) : base(name) { }

    public override Component add(Component component)
    {
        Debug.Log("文件无此操作");
        return this;

    }
    public override Component Remove(Component component)
    {
        Debug.Log("文件无此操作");
        return this;
    }

    public override Component Show(int index)
    {
        Debug.Log(new string(' ', index * 4) + "=" + name);
        return this;
    }
}

运行测试:

void Start()
{
    Component root = new _Folder("root");

    root
    .add(new _File("Leaf A"))
    .add(new _File("Leaf B"))
    .add(
        new _Folder("Composite X")
        .add(new _File("Leaf A"))
        .add(new _File("Leaf B"))
    )

    .add(
        new _Folder("Composite XY")
        .add(new _File("Leaf XYA"))
        .add(new _File("Leaf XYB"))
    )

    .add(new _File("Leaf C"))
    .add(new _File("Leaf D"))
    .Show()
    ;

}

结果:

猜你喜欢

转载自blog.csdn.net/qq_40346899/article/details/107482244
今日推荐