简单工厂vs工厂方法
简单工厂是第二章讲解的内容,它与工厂方法很相似。
简单工厂模式最大的优点在于工厂类中包含了必要的逻辑判断,根据客户端的选择条件动态实例化相关类,对客户来说去除了对具体产品的依赖。但是,每次要添加算法,都需要的在客户端怎加一个case分支条件,修改了原有的类,违反了开放-封闭原则。
简单工厂模式复习:
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
1 namespace Pattern.FactoryMethod 2 { 3 //首先复习简单工厂 4 class OperationFactory 5 { 6 public static Operation CreateOperation(string type) 7 { 8 Operation opt = null; 9 switch (type) 10 { 11 case "+": opt = new OperationAdd(); break; 12 case "-": opt = new OperationSub(); break; 13 case "*": opt = new OperationMul(); break; 14 case "/": opt = new OperationDiv(); break; 15 } 16 return opt; 17 } 18 } 19 20 abstract class Operation 21 { 22 public double Left { get; set; } 23 public double Right { get; set; } 24 25 public abstract double GetResult(); 26 } 27 28 class OperationAdd : Operation 29 { 30 public override double GetResult() 31 { 32 return Left + Right; 33 } 34 } 35 class OperationSub : Operation 36 { 37 public override double GetResult() 38 { 39 return Left - Right; 40 } 41 } 42 class OperationMul : Operation 43 { 44 public override double GetResult() 45 { 46 return Left * Right; 47 } 48 } 49 class OperationDiv : Operation 50 { 51 public override double GetResult() 52 { 53 return Left / Right; 54 } 55 } 56 }
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
1 namespace Pattern.FactoryMethod 2 { 3 interface IFactory 4 { 5 Operation CreateOperation(); 6 } 7 8 class AddFactory : IFactory 9 { 10 public Operation CreateOperation() 11 { 12 return new OperationAdd(); 13 } 14 } 15 16 class SubFactory : IFactory 17 { 18 public Operation CreateOperation() 19 { 20 return new OperationSub(); 21 } 22 } 23 24 class MulFactory : IFactory 25 { 26 public Operation CreateOperation() 27 { 28 return new OperationMul(); 29 } 30 } 31 32 class DivFactory : IFactory 33 { 34 public Operation CreateOperation() 35 { 36 return new OperationDiv(); 37 } 38 } 39 }
工厂方法(Factory Method),第一个用于创建对象的接口,让子类决定实例化哪一个工厂类。工厂方法使一个类的实例化延迟到其子类[DP]。
工厂方法只是扩展了变化,并没有违反“开放-封闭原则”。工厂方法把简单工厂的内部逻辑移到了客户端代码中进行,你行增加功能,本来是要修改简单工厂类的,而现在是修改客户端代码。工厂方法是对简单工厂的进一步抽象和推广,工厂模式保持了简单工厂的优点,克服了违反“开放-闭包原则”的缺点,但是由于每增加个产品都要增加一个工厂类,增加了额外的开销。
利用反射可以避免分支判断的问题。
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
1 namespace Pattern.FactoryMethod 2 { 3 class LeiFeng 4 { 5 public void Sweep() 6 { 7 Console.WriteLine("帮忙扫地。"); 8 } 9 public void Wash() 10 { 11 Console.WriteLine("洗衣服。"); 12 } 13 public void BuyRice() 14 { 15 Console.WriteLine("买米。"); 16 } 17 18 } 19 //学雷锋的学生 20 class Undergraduate : LeiFeng 21 { 22 } 23 //社区志愿者 24 class Volunteer : LeiFeng 25 { } 26 //雷锋工厂 27 interface IFactoryLF 28 { 29 LeiFeng CreateLeiFeng(); 30 } 31 32 //学雷锋的大学生工厂 33 class UndergraduateFactory : IFactoryLF 34 { 35 public LeiFeng CreateLeiFeng() 36 { 37 return new Undergraduate(); 38 } 39 } 40 //学雷锋的社区志愿者工厂 41 class VolunterFactory:IFactoryLF 42 { 43 public LeiFeng CreateLeiFeng() 44 { 45 return new Volunteer(); 46 } 47 } 48 49 }
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
1 static void NewbieFactoryMethod() 2 { 3 IFactoryLF lfFactory = new VolunterFactory();//new UndergraduateFactory();//这里只需要更改创建工厂即可 4 LeiFeng lf = lfFactory.CreateLeiFeng(); 5 lf.BuyRice(); 6 lf.Wash(); 7 lf.Sweep(); 8 }