雷锋依然在人间 工厂方法模式
8.1 再现活雷锋
8.2 简单工厂模式实现
class OperationFactory { public static Operation createOperate(string operate) { Operation oper = null; switch (operate) { case "+": { oper = new OperationAdd(); break; } case "-": { oper = new OperationSub(); break; } case "*": { oper = new OperationMul(); break; } case "/": { oper = new OperationDiv(); break; } } return oper; } }
Operation oper; oper = OperationFactory.createOperate(strOperate); oper.NumberA = Convert.ToDouble(strNumberA); oper.NumberB = Convert.ToDouble(strNumberB); string strResult = oper.GetResult().ToString();
8.3 工厂模式实现
namespace 工厂方法_计算器 { /// <summary> /// 运算类 /// </summary> class Operation { private double _numberA = 0; private double _numberB = 0; public double NumberA { get { return _numberA; } set { _numberA = value; } } public double NumberB { get { return _numberB; } set { _numberB = value; } } /// <summary> /// 得到运算结果 /// </summary> /// <returns></returns> public virtual double GetResult() { double result = 0; return result; } } /// <summary> /// 加法类 /// </summary> class OperationAdd : Operation { public override double GetResult() { double result = 0; result = NumberA + NumberB; return result; } } /// <summary> /// 减法类 /// </summary> class OperationSub : Operation { public override double GetResult() { double result = 0; result = NumberA - NumberB; return result; } } /// <summary> /// 乘法类 /// </summary> class OperationMul : Operation { public override double GetResult() { double result = 0; result = NumberA * NumberB; return result; } } /// <summary> /// 除法类 /// </summary> class OperationDiv : Operation { public override double GetResult() { double result = 0; if (NumberB == 0) throw new Exception("除数不能为0。"); result = NumberA / NumberB; return result; } } /// <summary> /// 工厂方法 /// </summary> interface IFactory { Operation CreateOperation(); } /// <summary> /// 专门负责生产“+”的工厂 /// </summary> class AddFactory : IFactory { public Operation CreateOperation() { return new OperationAdd(); } } /// <summary> /// 专门负责生产“-”的工厂 /// </summary> class SubFactory : IFactory { public Operation CreateOperation() { return new OperationSub(); } } /// <summary> /// 专门负责生产“*”的工厂 /// </summary> class MulFactory : IFactory { public Operation CreateOperation() { return new OperationMul(); } } /// <summary> /// 专门负责生产“/”的工厂 /// </summary> class DivFactory : IFactory { public Operation CreateOperation() { return new OperationDiv(); } } }
namespace 工厂方法_计算器 { class Program { static void Main(string[] args) { IFactory operFactory = new AddFactory(); Operation oper = operFactory.CreateOperation(); oper.NumberA = 1; oper.NumberB = 2; double result = oper.GetResult(); Console.WriteLine(result); Console.Read(); } } }
8.4 简单工厂VS工厂方法
在简单工厂里,先是增加功能类,在更改工厂类中方法,当中加"case"语句来作判断,在工厂方法里,先是增加功能类没问题,在加相关工厂类也没问题,但要在去更改客户端代码时,等于没有减化难度反而复杂性增加了,为什么要这样?
简单工厂模式的最大优点在于工厂类中包含了必要的逻辑判断,根据客户端的选择条件动态实例化相关的类,对于客户端来说,去除了与具体产品的依赖,
但是在对"case"语句进行修改时,违背了开放封闭原则,
工厂方法模式:定义了一个用于创建对象的接口,让子类决定实例化哪一个类,工厂方法使一个类的实例化延迟到其子类,
根据依赖倒置原则,把工厂类抽象出一个接口,这个接口只有一个方法,就是创建抽象产品的工厂方法,
工厂方法模式实现时,客户端需要决定实例化哪一个工厂来实现运算类,选择判断的问题还是存在的,也就是说,工厂方法把简单工厂的内部逻辑判断移动到了客户端代码来进行,你想要加功能,本来是修改工厂类的,而现在是修改客户端!
8.5 雷锋工厂
namespace 工厂方法_雷锋工厂 { class Program { static void Main(string[] args) { //基本方式:薛磊风代表大学生学习雷锋 LeiFeng xueleifeng = new Undergraduate(); xueleifeng.BuyRice(); xueleifeng.Sweep(); xueleifeng.Wash(); LeiFeng student1 = new Undergraduate(); student1.BuyRice(); LeiFeng student2 = new Undergraduate(); student2.Sweep(); LeiFeng student3 = new Undergraduate(); student3.Wash(); //简单工厂模式 LeiFeng studentA = SimpleFactory.CreateLeiFeng("学雷锋的大学生"); studentA.BuyRice(); LeiFeng studentB = SimpleFactory.CreateLeiFeng("社区志愿者"); studentB.Sweep(); LeiFeng studentC = SimpleFactory.CreateLeiFeng("学雷锋的大学生"); studentC.Wash(); //工厂方法模式 IFactory factory = new UndergraduateFactory(); LeiFeng student = factory.CreateLeiFeng(); student.BuyRice(); student.Sweep(); student.Wash(); Console.Read(); } } //雷锋 class LeiFeng { public void Sweep() { Console.WriteLine("扫地"); } public void Wash() { Console.WriteLine("洗衣"); } public void BuyRice() { Console.WriteLine("买米"); } } //学雷锋的大学生 class Undergraduate : LeiFeng { } //社区志愿者 class Volunteer : LeiFeng { } //简单雷锋工厂 class SimpleFactory { public static LeiFeng CreateLeiFeng(string type) { LeiFeng result = null; switch (type) { case "学雷锋的大学生": result = new Undergraduate(); break; case "社区志愿者": result = new Volunteer(); break; } return result; } } //雷锋工厂 interface IFactory { LeiFeng CreateLeiFeng(); } //学雷锋的大学生工厂 class UndergraduateFactory : IFactory { public LeiFeng CreateLeiFeng() { return new Undergraduate(); } } //社区志愿者工厂 class VolunteerFactory : IFactory { public LeiFeng CreateLeiFeng() { return new Volunteer(); } } }
工厂方法克服了简单工厂违背开放封闭原则的特点,又保持了封装对象创建过程的有点,
工厂方法模式是简单工厂模式的进一步抽象和推广,由于使用了多态性,工厂方法模式保持了简单工厂模式的有点,而且克服了它的缺点,但是由于每增加一个产品,就需要增加一个产品工厂的类,增加了额外的开发量,