Head First设计模式之组合模式

一、定义

将对象组合成树形结构来表现"整体-部分"层次结构。 组合能让客户以一致的方法处理个别对象以及组合对象。

主要部分可以被一致对待问题.

在使用组合模式中需要注意一点也是组合模式最关键的地方:叶子对象和组合对象实现相同的接口。这就是组合模式能够将叶子节点和对象节点进行一致处理的原因。

二、结构

 

组合模式主要包含三个角色

1.Component(抽象构件) : 为参加组合的对象定义了公共接口和默认行为,声明一个接口用于访问和管理Component子部件。 

2.Composite(容器构件):容器节点包含子节点,其子节点可以是叶子节点,也可以是容器节点,它提供一个集合用于存储子节点,实现了在抽象构件中定义的行为,包括那些访问及管理子构件的方法,在其业务方法中可以递归调用其子节点的业务方法。

3.Leaf(叶子构件):  代表参加组合的叶子对象(叶子没有后继)。定义组成原始对象的行为。

三、实现

 class Program
    {
        static void Main(string[] args)
        {
            MenuComponent menuComponent = new MenuItem("网站");
            MenuComponent menuComponent1 = new MenuItem("主页");
            MenuComponent menuComponent2 = new MenuItem("产品页");
            MenuComponent menuComponent21 = new MenuLeaf("CRM");
            MenuComponent menuComponent22 = new MenuLeaf("ERP");

            menuComponent.Add(menuComponent1);
            menuComponent.Add(menuComponent2);
            menuComponent2.Add(menuComponent21);
            menuComponent2.Add(menuComponent22);
            menuComponent2.Remove(menuComponent21);
        }
    }


    public abstract class MenuComponent
    {
        protected MenuComponent(string name)
        {
            Name = name;
        }
        public string Name { get; set; }

        public abstract void Add(MenuComponent menuComponent);
        public abstract void Remove(MenuComponent menuComponent);

    }

    public class MenuItem : MenuComponent
    {
        public MenuItem(string name) : base(name)
        {

        }

        public override void Add(MenuComponent menuComponent)
        {
            Console.WriteLine(Name + "增加: " + menuComponent.Name);
        }

        public override void Remove(MenuComponent menuComponent)
        {
            Console.WriteLine(Name + "移除: " + menuComponent.Name);
        }
    }
    public class MenuLeaf : MenuComponent
    {
        public MenuLeaf(string name) : base(name)
        {

        }

        public override void Add(MenuComponent menuComponent)
        {
            throw new Exception("不能增加");
        }

        public override void Remove(MenuComponent menuComponent)
        {
            throw new Exception("不能移除");
        }
    }

网站菜单的简单实现

 

四、适用场景

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

  1、 在对象具有部分-整体层次结构,可以选用组合模式,把整体和部分的操作统一起来,使得层次结构实现更简单,从外部来使用这个层次结构也简单。

  2、 系统中需要处理一个树形结构。

  3、 在一个系统中能够分离出叶子对象和容器对象,而且它们的类型不固定,需要增加一些新的类型。
  实际应用:  XML解析 、织结构树处理、 件系统设计 

 

五、优缺点

优点: 

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

缺点:

  1.在增加新构件时很难对容器中的构件类型进行限制。

  2.使设计变得更加抽象、复杂

六、模式扩展

  组合模式在.NET 中最典型的应用就是应用与WinForms和Web的开发中,在.NET类库中,都为这两个平台提供了很多现有的控件,然而System.Windows.Forms.dll中System.Windows.Forms.Control类就应用了组合模式,因为控件包括Label、TextBox等这样的简单控件,同时也包括GroupBox、DataGrid这样复合的控件,每个控件都需要调用OnPaint方法来进行控件显示,为了表示这种对象之间整体与部分的层次结构,微软把Control类的实现应用了组合模式(确切地说应用了透明式的组合模式)。

  

 

posted @ 2017-07-30 00:13  心存善念  阅读(395)  评论(0编辑  收藏  举报