工厂方法模式是一种创建型设计模式, 其在父类中提供一个创建对象的方法, 允许子类决定实例化对象的类型。
这里还是拿之前简单工厂模式那个栗子来做
首先我们先创建一个运算类的父类
定义两个属性以及一个获取结果的虚方法
public class Operation { public double NumA { get; set; } public double NumB { get; set; } public virtual double GetResult() { double result = 0; return result; } }
接着,创建一个工厂接口,这个接口目的就是为了让派生类来决定到底要实例化哪一个运算子类
interface IFactory { Operation CreateOperation(); }
然后去创建几个派生自运算基类的具体运算类,如假发、减法等具体实现类
public class OperationAdd : Operation { public override double GetResult() { return NumA + NumB; } } .....
再去构建对应的工厂方法,继承自工厂接口
public class AddFactory : IFactory { public Operation CreateOperation() { return new OperationAdd(); } }
最后,客户端调用,这里写的有点烂,别介意,看主要的就行
IFactory factory; Operation operation = null; switch (oper) { case "+": factory = new AddFactory(); operation = factory.CreateOperation(); operation.NumA = Convert.ToDouble(num1); operation.NumB = Convert.ToDouble(num2); break; case "-": factory = new SubFactory(); operation = factory.CreateOperation(); operation.NumA = Convert.ToDouble(num1); operation.NumB = Convert.ToDouble(num2); break; default: break; }
可以发现,我们在实例工厂接口时,并没有直接去实例化工厂接口,而是实例化它的派生类,然后再实例化运算具体实现类,通过factory.CreateOperation();
让它自己去找对应的工厂类,而不同的工厂类里面又去实例化了对应的运算方法,最终就是通过调用operation.GetResult()
取到运算结果
1、当你在编写代码的过程中,如果无法预知对象确切类别及其依赖关系时,可使用工厂方法。
工厂方法将创建产品的代码与实际使用产品的代码分离, 从而能在不影响其他代码的情况下扩展产品创建部分代码。
例如, 如果需要向应用中添加一种新产品, 你只需要开发新的创建者子类, 然后重写其工厂方法即可。
2、 如果你希望用户能扩展你软件库或框架的内部组件****, 可使用工厂方法****。
继承可能是扩展软件库或框架默认行为的最简单方法。 但是当你使用子类替代标准组件时, 框架如何辨识出该子类?
解决方案是将各框架中构造组件的代码集中到单个工厂方法中, 并在继承该组件之外允许任何人对该方法进行重写。
3、如果你希望复用现有对象来节省系统资源****, 而不是每次都重新创建对象****, 可使用工厂方法****。
在处理大型资源密集型对象 (比如数据库连接、 文件系统和网络资源) 时, 你会经常碰到这种资源需求。
简单工厂模式最大的优点在于工厂类中包含了必要的逻辑判断,根据客户端选择的条件去实例化相关的类,对于客户端来说,去除了与具体产品的依赖,使得客户端无需过多关系底层的具体实现。而在使用工厂方法模式实现时,客户端需要决定到底去实例化哪一个工厂类,大量的罗技分支判断可能还是存在的。简单来说就是把那些判断又搬到了客户端,如果想要扩展新功能,就只需要去创建相关的类和工厂,达到了开闭原则和单一职责原则,但也会使得代码层次可能有点繁杂和冗余。
代码仓库地址:https://github.com/luchong0813/DesignModel