温州网站制作企业,韩国网站加速器,建设电影网站代码,商城网站数据库表关系设计写在前面 Composite组合模式属于设计模式中比较热门的一个#xff0c;相信大家对它一定不像对访问者模式那么陌生#xff0c;毕竟谁又没有遇到过树形结构呢。不过所谓温故而知新#xff0c;我们还是从一个例子出发#xff0c;起底一下这个模式吧。一个简单例子 设想我们… 写在前面 Composite组合模式属于设计模式中比较热门的一个相信大家对它一定不像对访问者模式那么陌生毕竟谁又没有遇到过树形结构呢。不过所谓温故而知新我们还是从一个例子出发起底一下这个模式吧。 一个简单例子 设想我们要建立一个公司的人事架构在一个公司里我们可以简单地分为两种员工一种是经理包括老板另一种是基层员工经理可以有下属而普通员工不行我们写出这样的代码。基层员工类这种员工是最基层的员工没有下属class BasicLevelEmployee //基层员工
{public string ID { get; set; }public void ShowStatus(int indent){string str ID;str str.PadLeft(ID.Length indent, -);Console.WriteLine(str);}
}经理类经理可以有下属下属可能是基层员工也可能是其他经理考虑老板这种情况无疑其他经理也是老板的下属因为比基层员工多了下属所以也多了一些方法维护下属属性class Manager //经理
{public string ID { get; set; }public void ShowStatus(int indent) {string str ID; str str.PadLeft(ID.Length indent, -);Console.WriteLine(str);indent 4;Subordinate.ForEach(s s.ShowStatus(indent));SubordinateManagers.ForEach(m m.ShowStatus(indent));}public ListBasicLevelEmployee Subordinate new ListBasicLevelEmployee();public ListManager SubordinateManagers new ListManager();//下面是经理所属的方法public void AddSubordinate(BasicLevelEmployee e) { Subordinate.Add(e); }public void AddSubordinate(Manager e) { SubordinateManagers.Add(e); }public void RemoveSubordinate(BasicLevelEmployee e) { Subordinate.Remove(e); }public void RemoveSubordinate(Manager e) { SubordinateManagers.Remove(e); }
}公司架构类公司架构类非常简单只需要掌握最大的BOSS整个公司人事架构都可以顺藤摸瓜的展示出来class CompanyHierachy
{public Manager BOSS { get; set; }public void ShowStatus(){BOSS.ShowStatus(0);}
}客户端代码假设这个公司的结构很单纯除了老板就是开发部门和财务部门各个部门分设经理是所以我们写出代码如下class Program
{static void Main(string[] args){//老板Manager boss new Manager() { ID BOSS };//开发部门经理Manager devManager new Manager() { ID Dev Manager };//财务部门经理Manager financeManager new Manager() { ID Finance Manager };//开发组长Manager devLead new Manager() { ID Dev Lead };//测试组长Manager qcLead new Manager() { ID QC Lead };boss.AddSubordinate(devManager);boss.AddSubordinate(financeManager);financeManager.AddSubordinate(new BasicLevelEmployee() { ID Purchase });devManager.AddSubordinate(devLead);devManager.AddSubordinate(qcLead);devLead.AddSubordinate(new BasicLevelEmployee() { ID Developer1 });devLead.AddSubordinate(new BasicLevelEmployee() { ID Developer2 });qcLead.AddSubordinate(new BasicLevelEmployee() { ID QuanityControl1 });qcLead.AddSubordinate(new BasicLevelEmployee() { ID QuanityControl2 });CompanyHierachy company new CompanyHierachy() { CEO boss };company.ShowStatus();}
}代码非常简单不需要更多解释了运行后得到结果一切正常代码是工作的公司架构建立成功了。 再想一下 但是想想这样的代码真的好吗感觉起码有两个地方我们可以改进。1. 基层员工和经理其实有太多的共性属性和方法可以利用抽象思维让他们继承自同一种东西吗2. 在经理类中我们维护了多个下属列表如果以后再加一个实习生是不是我们又得创建更多的列表如果我们使用了继承这个问题还会存在吗基于此利用抽象思维让经理和员工继承自同一个类雇员势在必行。在抽象之后经理类会继承自雇员并且也内含雇员列表可能第一次见到这种包含自身父类列表的设计方式会让人感觉不习惯但不用担心这其实是一种比较常见的设计方式。这种既有继承也有合成的结构就是组合模式的精髓。 使用组合模式进行重构 组合模式属于结构型设计模式它利用类型层级和聚合层级构造更大的复合结构说的更加直白一点当对象的局部结构和对象自身相同的情况下我们可以使用继承加上聚合的方式来组合代码比如刚刚提到的例子中观察一下对于Boss来说它的局部结构即DevManager和FinanceManager与它自己的结构有何区别都是树结构无非就是根节点不一样而已所以于情于理这一块可以用继承加聚合来重构。那么心细的朋友肯定发现了有些操作是经理类独有的这些操作我们是应该抽象到和基层员工共同的父类雇员类吗对于这个问题一般有两种解决方案。透明型在此设计中子类方法的并集被提炼到了共有父类哪怕这些方法对于某些子类根本不需要这样的好处是客户端在使用的时候根本不需要知道对象纠结是哪个子类对客户端透明所以得名。当前设计多采用这种。安全型安全型设计非常保守只会提炼子类交集的方法到父类这样的好处是绝对安全客户端绝对不可能在BasicLevelEmployee对象上面调用AddSubordinate或者RemoveSubordinate。但有时候会面临向下转型的情况。重构后的代码透明型抽象出共同父类雇员类使用透明型所有的子类方法都提炼到这个类abstract class Employee
{public string ID { get; set; }public abstract void ShowStatus(int indent);//因为是透明型所以基层员工用不上的方法也会被抽象到父类public abstract void AddSubordinate(Employee e);public abstract void RemoveSubordinate(Employee e);
}对于基层员工如果客户端无意间调用了不该使用的方法这基本是一个明确的、表明客户端代码出现了逻辑问题的信号这种情况直接抛出异常能更快地暴露出问题class BasicLevelEmployee : Employee
{public override void ShowStatus(int indent){string str ID;str str.PadLeft(ID.Length indent, -);Console.WriteLine(str);}public override void AddSubordinate(Employee e){throw new NotImplementedException();}public override void RemoveSubordinate(Employee e){throw new NotImplementedException();}
}在经理类中得益于共有父类Employee我们可以用一个列表装下所有的下属不论下属是基层员工还是经理抑或是未来可能添加的实习生。毕竟他们都是雇员嘛class Manager : Employee
{public override void ShowStatus(int indent){string str ID;str str.PadLeft(ID.Length indent, -);Console.WriteLine(str);indent 4;Subordinate.ForEach(s s.ShowStatus(indent));}public ListEmployee Subordinate new ListEmployee();//下面是经理所属的方法public override void AddSubordinate(Employee e) { Subordinate.Add(e); }public override void RemoveSubordinate(Employee e) { Subordinate.Remove(e); }
}公司架构类和客户端代码调用保持不变运行结果一致重构成功。可以看到在使用了组合模式之后现在的代码不但消除了冗余不用再去维护多个下属列表也更具有抵御未来变化的能力这样的结构比起原来当然是更加合理的。这就是结构型设计模式的用武之地让对象的结构更加的合理更加的易于扩展。这就是关于Composite组合模式的介绍鉴于笔者能力有限如果大家对于这篇文章中所讲有其他看法欢迎留言讨论。 作者老胡写代码 原文https://www.cnblogs.com/deatharthas/p/16390116.html