首页 > 学院 > 开发设计 > 正文

设计模式(14)---组合模式

2019-11-14 16:19:09
字体:
来源:转载
供稿:网友

一、定义

组合模式:将对象组合成树形结构以表示“部分-整体”的层次结构。组合模式使得用户对单个对象和组合对象的使用具有一致性。

解释:简单来说,编写一个类,该类能作用于整体,并且编写整体中的部分时也能使用该类,而不用做大的更改。

 

二、UML类图及基本代码

基本代码:

abstract class Component    {        PRotected string name;        public Component(string name)        {            this.name = name;        }        public abstract void Add(Component component);        public abstract void Remove(Component component);        public abstract void Display(int depth);    }    class Leaf : Component    {        public Leaf(string name)            : base(name)        { }        public override void Add(Component component)        {            Console.WriteLine("cannot add to a leaf");        }        public override void Remove(Component component)        {            Console.WriteLine("cannot remove to a leaf");        }        public override void Display(int depth)        {            Console.WriteLine(new string('-', depth) + name);        }    }    class Composite : Component    {        private IList<Component> children = new List<Component>();        public Composite(string name)            : base(name)        { }        public override void Add(Component component)        {            children.Add(component);        }        public override void Remove(Component component)        {            children.Remove(component);        }        public override void Display(int depth)        {            Console.WriteLine(new string('-', depth) + name);            foreach (Component component in children)            {                component.Display(depth + 2);            }        }    }

 

客户端进行调用:

Composite root = new Composite("root");            root.Add(new Leaf("leaf A"));            root.Add(new Leaf("leaf B"));            Composite composite = new Composite("Composite X");            composite.Add(new Leaf("leaf XA"));            composite.Add(new Leaf("leaf XB"));            root.Add(composite);            Composite composite2 = new Composite("Composite XY");            composite2.Add(new Leaf("leaf XYA"));            composite2.Add(new Leaf("leaf XYB"));            composite.Add(composite2);            root.Add(new Leaf("leaf C"));            Leaf leaf = new Leaf("Leaf D");            root.Add(leaf);            root.Remove(leaf);            root.Display(1);
View Code

结果如图:

 

三、透明方式和安全方式

  基本代码中,leaf类也有add和remove方法,也就是说Component声明所有用来管理子对象的方法,实现了所有子类都具备其方法的目的。这样做的好处就是叶节点和枝节点对于外界没有区别,它们具备完全一致的行为接口。但因为leaf不具备add和remove的功能,所以实现它是没有意义的。这种方式就是透明方式。

  安全方式是叶节点和枝节点不具有相同的接口,由于不够透明,那么客户端调用时需要做相应的判断,带来了不便。所以在实际项目中使用安全方式和透明方式就需要视情况而定。

 

四、举例说明:

  绘制一个图形,该图形由一个复杂图形和两条线段组成。可以自由的移除该图形。

public abstract class Graphics    {        public string Name { get; set; }        public Graphics(string name)        {            this.Name = name;        }        public abstract void Draw();        public abstract void Add(Graphics graphics);        public abstract void Remove(Graphics graphics);    }    public class Line : Graphics    {        public Line(string name)            : base(name)        { }        public override void Draw()        {            Console.WriteLine("" + Name);        }        public override void Add(Graphics graphics)        {            throw new Exception("不能向简单图形line添加图形");        }        public override void Remove(Graphics graphics)        {            throw new Exception("不能向简单图形line移除图形");        }    }    public class Circle : Graphics    {        public Circle(string name)            : base(name)        { }        public override void Draw()        {            Console.WriteLine("" + Name);        }        public override void Add(Graphics g)        {            throw new Exception("不能向简单图形Circle添加其他图形");        }        public override void Remove(Graphics g)        {            throw new Exception("不能向简单图形Circle移除其他图形");        }    }    public class ComplexGraphics : Graphics    {        private IList<Graphics> complexGraphicsList = new List<Graphics>();        public ComplexGraphics(string name)            : base(name)        { }        public override void Draw()        {            foreach (Graphics g in complexGraphicsList)            {                g.Draw();            }        }        public override void Add(Graphics graphics)        {            complexGraphicsList.Add(graphics);        }        public override void Remove(Graphics graphics)        {            complexGraphicsList.Remove(graphics);        }    }

客户端调用:

ComplexGraphics complexGraphics = new ComplexGraphics("一个复杂图形和两条线段组成的复杂图形");            complexGraphics.Add(new Line("线段A"));            ComplexGraphics complexGraphics2 = new ComplexGraphics("一个圆和一条线组成的复杂图形");            complexGraphics2.Add(new Circle(""));            complexGraphics2.Add(new Line("线段B"));            complexGraphics.Add(complexGraphics2);            Line line = new Line("线段C");            complexGraphics.Add(line);            Console.WriteLine("复杂图形的绘制如下:");            Console.WriteLine("----------------------");            complexGraphics.Draw();            Console.WriteLine("复杂图形的绘制完成");            Console.WriteLine("----------------------");            complexGraphics.Remove(line);            Console.WriteLine("移除线段C后,复杂图形的绘制如下:");            Console.WriteLine("---------------------");            complexGraphics.Draw();            Console.WriteLine("复杂图形绘制完成");            Console.WriteLine("---------------------");
View Code

调用结果:

 

五、优缺点及适用场景

优点:

1)组合模式使得客户端可以一致的处理对象和对象容器,既是叶节点和枝节点。

2)更容易的为组合对象添加新的组件

3)解耦了客户端与复杂对象。

缺点:

设计更加复杂。

 

适用场景:

1)需要表示一个对象整体和部分的层次结构

2)用户希望忽略组合对象和单个对象的不同,一致的处理组合对象和单个对象。

 


发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表