组合模式

1. 组合模式是结合递归技巧

2. 树状结构会用到递归,比如遍历文件夹和它的所有子文件夹。

    递归要有跳出条件,递归消耗资源。

    看递归代码,模拟一个找文件夹的树形结构:

namespace CompsitePattern
{
    /// <summary>
    /// 递归
    /// 递归要有跳出条件
    /// 递归消耗资源
    /// </summary>
    public class Recursion
    {
        /// <summary>
        /// 给一个根目录,获取全部的文件夹
        /// </summary>
        /// <param name="rootPath"></param>
        /// <returns></returns>
        public static List<DirectoryInfo> GetDirectoryList(string rootPath)
        {
            List<DirectoryInfo> dirList = new List<DirectoryInfo>(); 

            DirectoryInfo dirRoot = new DirectoryInfo(rootPath);   //根目录
            dirList.Add(dirRoot);

            GetDirectoryListChild(dirList, dirRoot);

            //DirectoryInfo[] dirList1 = dirRoot.GetDirectories();//一级子目录
            //dirList.AddRange(dirList1);

            //foreach (var dir1 in dirList1 )
            //{
            //    DirectoryInfo[] dirList2 = dir1.GetDirectories();//二级子目录
            //    dirList.AddRange(dirList2);

            //    foreach (var dir2 in dirList2)
            //    {
            //        DirectoryInfo[] dirList3 = dir2.GetDirectories();//三级子目录
            //        dirList.AddRange(dirList2);
            //    }
            //}

            return dirList;
        }

        /// <summary>
        /// 找出当前文件夹的子文件夹,放入结果容器
        /// </summary>
        /// <param name="dirList">结果容器</param>
        /// <param name="dirParent">当前文件夹</param>
        private static void GetDirectoryListChild(List<DirectoryInfo > dirList,DirectoryInfo dirParent)
        {
            DirectoryInfo[] dirListChild = dirParent.GetDirectories();
            dirList.AddRange(dirListChild);
            
            foreach (var dir in dirListChild )
            {
                //DirectoryInfo[] dirListChild1 = dir.GetDirectories();
                //dirList.AddRange(dirListChild1);
                GetDirectoryListChild(dirList, dir);
            }
        }
    }
}
    var list = Recursion.GetDirectoryList(@"D:\tmp");
    Console.WriteLine(list.Count);

 

3. 组合模式: 在一个对象里面又组合了一个集合,一个节点+它的子节点(按照红色和蓝色框存储节点)

  代码演示了一个项目中参与的人员能分到的提成:

namespace CompsitePattern
{
    /// <summary>
    /// 1. 递归的编程技巧
    /// 2. 递归的应用和组合模式
    /// 3. 组合模式:透明和安全
    /// </summary>
    class Program
    {
        static void Main(string[] args)
        {
            try
            {
                double total = 1000000; // 一个100万的项目
                Employee employee = BuildTree();
                employee.Commission(total);
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
            }
            Console.ReadKey();
        }

        private static Employee BuildTree()  //这个数据会来自数据库
        {
            Employee employee = new Employee()//拿项目总金额的10%作为提成
            {
                Name = "能有的提成收入",
                Percent = 10
            };
            Employee employee1 = new Employee()//CEO拿到总提成的30%
            {
                Name = "CEO",
                Percent = 30
            };
            Employee employee2 = new Employee()
            {
                Name = "各部门共有",
                Percent = 70
            };
            Employee employee21 = new Employee()
            {
                Name = "实施部门",
                Percent = 20
            };
            Employee employee22 = new Employee()
            {
                Name = "测试部门",
                Percent = 10
            };
            Employee employee23 = new Employee()
            {
                Name = "销售部门",
                Percent = 30
            };
            Employee employee24 = new Employee()
            {
                Name = "开发部门",
                Percent = 40
            };
            Employee employee241 = new Employee()
            {
                Name = "经理",
                Percent = 20
            };
            Employee employee242 = new Employee()
            {
                Name = "主管",
                Percent = 15
            };
            Employee employee243 = new Employee()
            {
                Name = "开发团队",
                Percent = 65
            };
            Employee employee2431 = new Employee()
            {
                Name = "项目组一",
                Percent = 50
            };
            Employee employee2432 = new Employee()
            {
                Name = "项目组二",
                Percent = 50
            };
            Employee employee24321 = new Employee()
            {
                Name = "项目经理",
                Percent = 20
            };
            Employee employee24322 = new Employee()
            {
                Name = "开发人员",
                Percent = 80
            };
            Employee employee243221 = new Employee()
            {
                Name = "高级开发人员",
                Percent = 40
            };
            Employee employee243222 = new Employee()
            {
                Name = "中级开发人员",
                Percent = 30
            };
            Employee employee243223 = new Employee()
            {
                Name = "初级开发人员",
                Percent = 20
            };
            Employee employee243224 = new Employee()
            {
                Name = "实习生",
                Percent = 10
            };
            Employee employee2432241 = new Employee()
            {
                Name = "实习生1",
                Percent = 25
            };
            Employee employee2432242 = new Employee()
            {
                Name = "实习生2",
                Percent = 25
            };
            Employee employee2432243 = new Employee()
            {
                Name = "实习生3",
                Percent = 25
            };
            Employee employee2432244 = new Employee()
            {
                Name = "实习生4",
                Percent = 25
            };

            //建立一课树
            //实习生
            employee243224.AddChild(employee2432241);
            employee243224.AddChild(employee2432242);
            employee243224.AddChild(employee2432243);
            employee243224.AddChild(employee2432244);

            //发开人员
            employee24322.AddChild(employee243221);
            employee24322.AddChild(employee243222);
            employee24322.AddChild(employee243223);
            employee24322.AddChild(employee243224);

            //项目组2
            employee2432.AddChild(employee24321);
            employee2432.AddChild(employee24322);

            //开发团队
            employee243.AddChild(employee2431);
            employee243.AddChild(employee2432);

            //开发部门
            employee24.AddChild(employee241);
            employee24.AddChild(employee242);
            employee24.AddChild(employee243);

            //各部门共有
            employee2.AddChild(employee21);
            employee2.AddChild(employee22);
            employee2.AddChild(employee23);
            employee2.AddChild(employee24);

            //能提成的总收入
            employee.AddChild(employee1);
            employee.AddChild(employee2);

            return employee;
        }
    }
}
namespace CompsitePattern
{
    /// <summary>
    /// 个人能分到的提成
    /// 组合模式 在一个对象里面又组合了一个集合,一个节点+它的子节点
    /// </summary>
    public class Employee:AbstractEmployee 
    {
        private List<Employee> EmployeeChildList = new List<Employee>();

        public void AddChild(Employee employeechild)
        {
            this.EmployeeChildList.Add(employeechild);
        }
        public override void Commission(double total)  //提成
        {
            double result = total * this.Percent / 100;
            Console.WriteLine("{0} 提成 {1}", this.Name, result);
            foreach (var employeeChild in EmployeeChildList )
            {
                employeeChild.Commission(result);
            }
        }
    }
}

 

posted @ 2016-12-13 14:01  HepburnXiao  阅读(165)  评论(0编辑  收藏  举报