zoukankan      html  css  js  c++  java
  • 窥视设计模式之组合模式(composite)

    经常使用Control,会发现Control有Controls的属性,而Controls集合包含的还是一个Control,类似的还有XmlNode.他们都有一个共有的特性,数据结构都是树行结构,什么是树形模式呢?
    (Tree)n(n≥0)个结点的有限集TT为空时称为空树,否则它满足如下两个条件:
    (1)    有且仅有一个特定的称为根(Root)的结点;
    (2)   其余的结点可分为m(m≥0)个互不相交的子集TlT2Tm,其中每个子集本身又是一棵树,并称其为根的子树(SubTree)上面给出的递归定义刻画了树的固有特性:一棵非空树是由若干棵子树构成的,而子树又可由若干棵更小的子树构成。而这里的子树可以是叶子也可以是分支。
    先看下一幅图,里面的套娃就是一个套着一个的



    这样一堆娃娃,一个大的套一个小的,小的里面还可以套更小的,所以其组织结构为:
    Top Toy
     - Toy
      -- toy
        ----toy
            ----toy
    如果用程序来描述上图,用设计模式的组合模式(Composite)是一个不错的主意
    组合模式在GOF中定义为: 组合(Composite)模式将对象以树形结构组织起来,以达成部分-整体的层次结构,使得客户端对单个对象和组合对象的使用具有一致性。
    类图为:

    可以说,组合模式是比较简单易学的设计模式,我按照其定义和规则,实现一个论坛主题,帖子的组合关系
    论坛中,一个主题可以包括很多帖子 ,一个帖子还可以包括很多回复。关系是:
    Thread
     -- Thread||Message
       -- Thread||Message
    下面是实现文件:


    工厂类为:
     1using System;
     2using System.Collections.Generic;
     3using System.Text;
     4using System.Data;
     5
     6namespace CompositeStudy
     7{
     8    /// <summary>
     9    /// 工厂类
    10    /// </summary>
    11    /// <remarks>工厂类</remarks>

    12    public class ThreadFactory
    13    {
    14        DataTable table = new DataTable();
    15        public ThreadFactory()
    16        {
    17            table.Columns.Add("content");
    18            table.Columns.Add("IsTop");
    19            table.Columns.Add("IsMessage");
    20            table.Columns.Add("ID");
    21            table.Columns.Add("ParentID");
    22
    23            DataRow row = table.NewRow();
    24            row["content"= "test";
    25            row["IsTop"= false;            
    26            row["IsMessage"= false;
    27            row["ID"= 1;
    28            row["ParentID"= 0;
    29            table.Rows.Add(row);
    30
    31            row = table.NewRow();
    32            row["content"= "test1";
    33            row["IsTop"= true;
    34            row["IsMessage"= false;
    35            row["ID"= 0;
    36            row["ParentID"= -1;
    37            table.Rows.Add(row);
    38
    39            row = table.NewRow();
    40            row["content"= "test2";
    41            row["IsTop"= false;
    42            row["IsMessage"= true;
    43            row["ID"= 2;
    44            row["ParentID"= 0;
    45            table.Rows.Add(row);
    46
    47            row = table.NewRow();
    48            row["content"= "test3";
    49            row["IsTop"= false;
    50            row["IsMessage"= true;
    51            row["ID"= 3;
    52            row["ParentID"= 0;
    53            table.Rows.Add(row);
    54        }

    55        public List<IThread> GetTopThreads()
    56        {
    57            List<IThread> list = new List<IThread>();
    58            DataRow[] rows = table.Select("IsTop = true");
    59            foreach (DataRow row in rows)
    60            {
    61                Thread t = new Thread();
    62                t.Content = row["content"].ToString();
    63                t.IsTop = true;
    64                DataRow[] cs = table.Select("ParentID="+Convert.ToInt32(row["ID"]));
    65                foreach (DataRow r in cs)
    66                {
    67                    if (Convert.ToBoolean(r["IsMessage"]))
    68                    {
    69                        Message m = new Message();
    70                        m.Content = r["content"].ToString();
    71                        m.IsTop = false;
    72                        t.Add(m);
    73                    }

    74                    else
    75                    {
    76                        Thread tt = new Thread();
    77                        tt.Content = r["content"].ToString();
    78                        tt.IsTop = false;
    79                        t.Add(tt);
    80                    }

    81                }

    82                list.Add(t);
    83            }

    84            return list;
    85        }

    86    }

    87}

    88

    客户端调用方法为:
     1using System;
     2using System.Collections.Generic;
     3using System.Text;
     4
     5namespace CompositeStudy
     6{
     7    class Program
     8    {
     9        static void Main(string[] args)
    10        {
    11            ThreadFactory factory = new ThreadFactory();
    12            List<IThread> threads = factory.GetTopThreads();
    13            foreach(IThread t in threads)
    14            {
    15                t.RenderContent();
    16            }

    17            Console.Read();
    18        }

    19    }

    20}

    21

    类关系图:

    输结果为:
    通过该事例的调用,就可以知道,组合模式的好处有:

    1)         使客户端调用简单,客户端可以一致的使用组合结构或其中单个对象,用户就不必关心自己处理的是单个对象还是整个组合结构,这就简化了客户端代码。

    2)       更容易在组合体内加入对象部件. 客户端不必因为加入了新的对象部件而更改代码。这一点符合开闭原则的要求,对系统的二次开发和功能扩展很有利!


  • 相关阅读:
    hash_map和map的区别
    STL中map与hash_map容器的选择收藏
    ServletContextListener和ContextLoaderListener的区别
    解决Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.7.0:compile
    详解Tomcat线程池原理及参数释义
    Tomcat使用线程池配置高并发连接
    详解 Tomcat 的连接数与线程池
    ServletContextListener接口用法
    Spring Quartz定时任务如何获得ServletContext对象?
    如何在spring quartz类中拿到ServletContext
  • 原文地址:https://www.cnblogs.com/jillzhang/p/486301.html
Copyright © 2011-2022 走看看