设计模式----组合模式

      学习一些东西,我总感觉不整理一下笔记,总是感觉在脑海里没有记忆,我喜欢在学习完一定时间内,整理一下自己的

 

笔记,我感觉这是一笔很大的财富.

 

     今天我就贴贴我的设计模式---组合模式的笔记!

 

     我们先来看一下在我们使用电脑中常用到的一些组合关系,不知道大家平时注意了没有!

 

第一组,打开电脑,左侧栏的显示:

 

2,OneNote右侧的页,父页与子页

 

 

     学习总是会想到生活中的一些常用的事物,学习离不开生活,在我们的生活中,还有很多地方用到组合模式,比如说公

 

司与子公司,提高班的公司制度等,

 

    这些都是在生活中的组合模式,我们来认识一下官方的组合模式.

 

     组合模式(Composite),将对象组合成树形结构以表示'部分--整体'的层次结构.组合模式使得用户对单个对

 

象的使用具有一致性.

 

要点:

 

1.组合模式以不遵守单一责任原则换取透明性,让Client将组合和叶节点一视同仁.

 

2.在实现组合 模式时,有哦获得设计上的折衷,要根据需求平衡透明性和安全性.

 

3.有时候系统需要遍历一个树枝构件的子构件很多次,这时候可以把遍历结构缓存起来,

 

4.组合模式的实现中,可以让子对象持有父对象的引用进行反向追溯

 

类图:

 

Component(抽象构建角色):是组合中的对象声明接口,在适当情况下,实现所有类共有接口的默认行为,声明一个接口用

 

于访问和管理Component的子部件.这个接口可以用来管理所有的子对象.

 

Leaf(树叶结构):在组合中表示叶节点对象,叶节点没有子节点.并在组合中定义图元对象的行为.

 

Composite(树枝结构):定义有子部件的那些部件的行为,存储子部件.在Component接口中实现与子部件有关的操作.

 

Client(客户端):通过compnonent接口操纵组合部件的对象.

 

实现代码:

 

namespace 组合模式
{
    /// <summary>
    /// Component为组合中的对象声明接口,在适当情况下,是吸纳素有类共有接口的默认行为.
    /// </summary>
    /// 声明一个接口用于访问Component的子部件
    /// 
    abstract class Compnonent
    {
        protected string name;

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

        public abstract void Add(Compnonent c);
        public abstract void Remove(Compnonent c);
        public abstract void Display(int  depth);
        
    }

    /// <summary>
    /// Leaf类,表示叶节点对象,叶节点没有子节点.
    /// </summary>
    /// 
    class Leaf : Compnonent
    {
        public Leaf(string name)
            : base(name)
        {
        }

        public override void Add(Compnonent c)
        {
            Console.WriteLine("Cannot add to a leaf");
        }

        public override void Remove(Compnonent c)
        {
            Console.WriteLine("Cannot remove from a leaf");
        }

        public override void Display(int depth)
        {
            Console.WriteLine(new String('-', depth) + name);
        }
    }


    /// <summary>
    /// Composite定义有枝节点行为,用存储子部件.
    /// </summary>
    /// 
    class COmposite : Compnonent
    {
        private List<Compnonent> children = new List<Compnonent>();

        public COmposite(string name)
            : base(name)
        {
        }

        public override void Add(Compnonent c)
        {

            children.Add(c);
        }

        public override void Remove(Compnonent c)
        {
            children.Remove(c);
        }

        public override void Display(int depth)
        {
            Console.WriteLine(new string('-', depth) + name);

            foreach( Compnonent  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 comp1 = new COmposite("Composite XY");
            comp1.Add(new Leaf("Leaf XYA"));
            comp1.Add(new Leaf("Leaf XYB"));

            comp.Add(comp1);

            root .Add (new Leaf ("leaf  C"));

            Leaf leaf = new Leaf("Leaf D");
            root.Add(leaf);
            root.Remove(leaf);

            root.Display(1);

            Console.Read();
            
        }
    }
}


结果:

优点:

 

1.组合模式可以清楚地定义分层次的复杂对象,表示对象的全部或部分层次,它让客户端忽略了层次的差异,方便对整个

 

层次结构进行控制.

 

2.客户端可以一致地使用一个组合结构或其中单个对象,不必关心处理的是单个对象还是整个组合结构,简化了客户端

 

代码.

 

3.在组合模式中增加新的容器构件和叶子构件都很方便,无须对现有类库进行任何修改,符号"开放-封闭原则".

 

4.组合模式为树形结构的面向对象实现提供了一种灵活的解决方案,通过叶子对象和容器对象的递归组合,可以形成复

 

杂的树形结构,但对树形结构的控制却非常简单.

 

缺点:

 

1.使用组合模式后,控制树枝构件的类型不太容易.,有时候我们希望一个容器中只能有某些特定类型的对象.使用组合模

 

式时,不能依赖类型系统来施加约束,因为它们都来自于相同的抽象层,在这种情况下,必须通过在运行时进行类型检查来

 

实现,这个过程比较复杂.

 

2.用继承的方法来增加新的行为很困难.

 

使用组合模式的情况:

 

 1.在具体整体和部分的层次结构中,希望通过一种方式忽略整体与部分的差异,客户端可以一致地对待它们.

 

2.在一个使用面向对象语言开发的系统中需要处理一个树形结构.

 

3.在一个系统中能够分理出叶子对象和容器对象,而且它们的类型不固定需要增加一些新的类型.

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

弯_弯

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值