一、常规实现:不安全
/// <summary> /// 产品类 /// </summary> public abstract class Product { public Product(string name) { this.Name = name; } public string Name { get; set; } /// <summary> /// 每个产品都可以工作 /// </summary> public abstract void Work(); /// <summary> /// 每个产品都可以往里面再添加子产品 /// 至于有些产品不能再添加子产品,这里我们一会会详细说,大家先记住这一点 /// </summary> public abstract void Add(Product product); /// <summary> /// 每个产品都可以移除子产品,同上 /// </summary> public abstract void Remove(Product product); } /// <summary> /// CPU产品 /// </summary> public class Cpu : Product { public Cpu(string name) : base(name) { } public override void Work() { Console.WriteLine("Cpu工作啦!"); } /// <summary> /// 由于CPU已经是很小的零件了,不能再有子零件,所有不会有添加和删除的方法,所以先模拟抛出异常 /// 这里大家先这么看,后续我们会详细讲解这里 /// </summary> /// <param name="product"></param> public override void Add(Product product) { Console.WriteLine("不能给CPU添加子产品!"); } public override void Remove(Product product) { Console.WriteLine("不能给CPU移除子产品!"); } } /// <summary> /// 内存条产品 /// </summary> public class MemoryBar : Product { public MemoryBar(string name) : base(name) { } public override void Work() { Console.WriteLine("内存条工作啦!"); } public override void Add(Product product) { Console.WriteLine("不能给内存条添加子产品!"); } public override void Remove(Product product) { Console.WriteLine("不能给内存条移除子产品!"); } } /// <summary> /// 电脑产品 /// </summary> public class Computer : Product { public Computer(string name) : base(name) { } private List<Product> ChildProduct = new List<Product>(); public override void Work() { ChildProduct.ForEach(r => r.Work()); } public override void Add(Product product) { ChildProduct.Add(product); } public override void Remove(Product product) { ChildProduct.Remove(ChildProduct.First(r => r.Name == product.Name)); } } private static void Test1() { //简单零件工作 Product cpu = new Cpu("I7处理器"); cpu.Work(); //简单零件添加 cpu.Add(new MemoryBar("给CPU加内存")); cpu.Work(); //简单零件移除 cpu.Remove(new MemoryBar("给CPU减内存")); cpu.Work(); Console.WriteLine("--------------------------------------------"); //复杂零件工作 Product computer = new Computer("华硕笔记本"); computer.Add(new Cpu("I7处理器")); computer.Work(); //给简单零件添加零件再工作 computer.Add(new MemoryBar("金士顿16G内存条")); computer.Work(); //给复杂零件移除零件再工作 computer.Remove(new MemoryBar("金士顿16G内存条")); computer.Work(); }上述执行完,大家应该也看到了有点不足: 有的产品不能有子零件,但是还是会有添加零件和移除零件的方法,因为是从产品类继承过来的嘛 这样就导致了不安全,因为客户端觉得有这个方法那肯定就是可以使用的,结果不能使用 所以,一种更安全的方式就是: 将添加零件和移除零件的方法只有复杂产品我们才会加上,其他的都没有 有两种方式加: 1.在复杂产品类中多定义两个方法(添加和删除) 2.定义一个添加产品,删除产品接口,复杂产品需要实现这些接口(规范)
二、将复杂和简单区分开:安全
public abstract class ProductNew { public ProductNew(string name) { this.Name = name; } public string Name { get; set; } public abstract void Work(); } public class CpuNew : ProductNew { public CpuNew(string name) : base(name) { } public override void Work() { Console.WriteLine(this.Name + "更加安全的工作啦!"); } } public class MemoryBarNew : ProductNew { public MemoryBarNew(string name) : base(name) { } public override void Work() { Console.WriteLine(this.Name + "更加安全的工作啦!"); } } public class ComputerNew : ProductNew, IComplexProduct { private List<ProductNew> ChildProductList = new List<ProductNew>(); public ComputerNew(string name) : base(name) { } public override void Work() { ChildProductList.ForEach(r => r.Work()); } public void Add(ProductNew product) { ChildProductList.Add(product); } public void Remove(ProductNew product) { ChildProductList.Remove(ChildProductList.First(r => r.Name == product.Name)); } } public interface IComplexProduct { void Add(ProductNew product); void Remove(ProductNew product); } class Program { /// <summary> /// 组合模式: /// 开发中会涉及到简单对象和复杂对象,但是我们又希望能够一致性的对待他们 /// 比如:电脑的文件夹,每个文件夹下面有文件(简单对象),也有文件夹(复杂对象), /// 我们往往都要做判断然后对待他们,一般来说,我们会想到树结构tree /// 此时我们希望能够对待他们一致,就需要使用到组合模式了 /// /// 组合模式的特征: /// 1.简单对象和复杂对象,复杂对象由多个简单对象构成 /// 2.容器特征:既是对象,也是容器 /// /// 此文中的例子: /// 电脑是一个产品,电脑由CPU,硬盘,内存条,电源,电池等等...构成,这些零件也都是产品 /// 电脑既是产品,也是容器 /// </summary> /// <param name="args"></param> static void Main(string[] args) { //Test1(); //上述执行完,大家应该也看到了有点不足: //有的产品不能有子零件,但是还是会有添加零件和移除零件的方法,因为是从产品类继承过来的嘛 //这样就导致了不安全,因为客户端觉得有这个方法那肯定就是可以使用的,结果不能使用 //所以,一种更安全的方式就是: //将添加零件和移除零件的方法只有复杂产品我们才会加上,其他的都没有 //有两种方式加: //1.在复杂产品类中多定义两个方法(添加和删除) //2.定义一个添加产品,删除产品接口,复杂产品需要实现这些接口(规范) Test2(); Console.WriteLine("End"); Console.ReadKey(); } private static void Test1() { //简单零件工作 Product cpu = new Cpu("I7处理器"); cpu.Work(); //简单零件添加 cpu.Add(new MemoryBar("给CPU加内存")); cpu.Work(); //简单零件移除 cpu.Remove(new MemoryBar("给CPU减内存")); cpu.Work(); Console.WriteLine("--------------------------------------------"); //复杂零件工作 Product computer = new Computer("华硕笔记本"); computer.Add(new Cpu("I7处理器")); computer.Work(); //给简单零件添加零件再工作 computer.Add(new MemoryBar("金士顿16G内存条")); computer.Work(); //给复杂零件移除零件再工作 computer.Remove(new MemoryBar("金士顿16G内存条")); computer.Work(); } private static void Test2() { //简单零件工作 ProductNew cpu = new CpuNew("I7处理器"); cpu.Work(); ProductNew memoryBar = new MemoryBarNew("金士顿16G内存条"); memoryBar.Work(); Console.WriteLine("--------------------------------------------"); //复杂零件工作 ComputerNew computer = new ComputerNew("华硕笔记本"); computer.Add(new CpuNew("I7处理器")); computer.Work(); Console.WriteLine("--------------------------------------------"); //给简单零件添加零件再工作 computer.Add(new MemoryBarNew("金士顿16G内存条")); computer.Work(); Console.WriteLine("--------------------------------------------"); //给复杂零件移除零件再工作 computer.Remove(new MemoryBarNew("金士顿16G内存条")); computer.Work(); } }