zoukankan      html  css  js  c++  java
  • C#设计模式——组合模式(Composite Pattern)

    一、概述

    在软件开发中,我们往往会遇上类似树形结构的对象体系。即某一对象既可能在树形结构中作为叶节点存在,也可能作为分支节点存在。比如在文件系统中,文件是作为叶节点存在,而文件夹就是分支节点。在设计这类对象时,如果将叶节点和分支节点区别对待,那么在实际开发中会带来较大的复杂性。比如客户端调用时可能会频繁的使用转型操作,同时代码的可维护性和扩展性也较差。在设计中使用组合模式可以解决这一系列弊端。

    二、组合模式

    组合模式定义了叶节点和分支节点的一致的接口,将客户端代码与复杂的对象结构解耦,大大降低了客户端调用的复杂性。其结构图如下:

    Component定义了所有对象的共同接口,可以在Component中定义管理Component组件的接口以保证一致性,也可以将管理接口下放至Composite中以提高系统调用的安全性。

    Leaf表示叶节点。

    Composite定义了分支节点对象的行为,并提供一个容器用户存储其子节点。

    Client通过Component来处理所有对象。

    三、示例

    我们利用组合模式来实现一个绘图系统。在该系统中具有Line、Circle、Picture等多种元素,其中Picture可以含有各类子元素。

    首先定义Component。

     1     public abstract class Graphic
     2     {
     3         private string _name;
     4 
     5         public Graphic(string name)
     6         {
     7             _name = name;
     8         }
     9 
    10         public abstract void Add(Graphic graphic);
    11         public abstract void Remove(Graphic graphic);
    12 
    13         public virtual void Draw()
    14         {
    15             Console.WriteLine("Draw {0} {1}", GetType().Name, _name);
    16         }
    17     }

    接着定义Picture对象。

     1     public class Picture : Graphic
     2     {
     3         private List<Graphic> _graphic = new List<Graphic>();
     4         public Picture(string name)
     5             : base(name)
     6         {
     7         }
     8 
     9         public override void Add(Graphic graphic)
    10         {
    11             _graphic.Add(graphic);
    12         }
    13         public override void Remove(Graphic graphic)
    14         {
    15             _graphic.Remove(graphic);
    16         }
    17         
    18         public override void Draw()
    19         {
    20             base.Draw();
    21             foreach (Graphic graphic in _graphic)
    22             {
    23                 graphic.Draw();
    24             }
    25         }
    26     }

    再定义Line和Circle。

     1     public class Line : Graphic
     2     {
     3         public Line(string name)
     4             : base(name)
     5         {
     6         }
     7 
     8         public override void Add(Graphic graphic)
     9         {
    10             throw new Exception("Line can't add graphic");
    11         }
    12         public override void Remove(Graphic graphic)
    13         {
    14             throw new Exception("Line can't remove graphic");
    15         }
    16     }
    17 
    18     public class Circle : Graphic
    19     {
    20         public Circle(string name)
    21             : base(name)
    22         {
    23         }
    24 
    25         public override void Add(Graphic graphic)
    26         {
    27             throw new Exception("Circle can't add graphic");
    28         }
    29         public override void Remove(Graphic graphic)
    30         {
    31             throw new Exception("Circle can't remove graphic");
    32         }
    33     }

    这样就可以通过统一的Draw接口画出整幅图画。

  • 相关阅读:
    毕业设计记录——3.5
    毕业设计记录——3.4
    毕业设计记录——3.3
    阿里云申请SSL 配置https
    毕业设计记录——3.2
    毕业设计(2.25-3.1)周工作计划
    远程连接阿里云ecs 服务器Ubuntu 16.04报错 解决
    基于springboot的ajax异步文件上传
    《需求工程-软件建模与分析之读书笔记之四》
    《需求工程-软件建模与分析之读书笔记之三》
  • 原文地址:https://www.cnblogs.com/saville/p/2765574.html
Copyright © 2011-2022 走看看