本篇文章主要讲解工厂方法模式。工厂方法模式:定义一个用于创建对象的接口,让子类去决定实例化哪一个类。工厂方法使一个类的实例化延迟到其子类。
在看工厂方法模式之前先写个简单的计算器看下简单工厂。
先看下结构图。
接着看下代码实现。
首先创建一个运算抽象类。
package com.lwx.factory; /** * Created with IntelliJ IDEA. * Description: 运算抽象类 * User: lwx * Date: 2019-03-09 * Time: 20:45 */ public abstract class Operation { double numberA = 0; double numberB = 0; abstract double getResult(); }
然后是四种运算的实现类。
package com.lwx.factory; /** * Created with IntelliJ IDEA. * Description: 加法实现类 * User: lwx * Date: 2019-03-09 * Time: 20:47 */ public class OperationAdd extends Operation { double getResult() { return numberA + numberB; } }
package com.lwx.factory; /** * Created with IntelliJ IDEA. * Description: 减法实现类 * User: lwx * Date: 2019-03-09 * Time: 20:48 */ public class OperationSub extends Operation { double getResult() { return numberA - numberB; } }
package com.lwx.factory; /** * Created with IntelliJ IDEA. * Description: 乘法实现类 * User: lwx * Date: 2019-03-09 * Time: 20:49 */ public class OperationMul extends Operation { double getResult() { return numberA * numberB; } }
package com.lwx.factory; /** * Created with IntelliJ IDEA. * Description: 除法实现类 * User: lwx * Date: 2019-03-09 * Time: 20:51 */ public class OperationDiv extends Operation { double getResult() { if (numberB == 0){ throw new ArithmeticException("除数不能为0"); } return numberA / numberB; } }
接着创建运算工厂类,根据运算符去创建对应的实现类。
package com.lwx.factory; /** * Created with IntelliJ IDEA. * Description: 运算工厂类 * User: lwx * Date: 2019-03-09 * Time: 21:06 */ public class OperationFactory { public static Operation createOperation(String operate) { Operation operation = null; switch (operate) { case "+": operation = new OperationAdd(); break; case "-": operation = new OperationSub(); break; case "*": operation = new OperationMul(); break; case "/": operation = new OperationDiv(); break; } return operation; } }
最后是测试类和测试结果。
package com.lwx.factory; /** * Created with IntelliJ IDEA. * Description: * User: lwx * Date: 2019-03-09 * Time: 20:59 */ public class OperationTest { public static void main(String[] args) { Operation operation = OperationFactory.createOperation("+"); operation.numberA = 5; operation.numberB = 10; System.out.println(operation.getResult()); } }
以上就是简单工厂的示例代码,只需要传入运算符号工厂类就可以自动返回对应的计算实现类。
接下来把上面的计算器改成工厂方法模式。
老规矩先看下结构图。
在上面代码的基础上加入工厂接口类以及具体实现类,上面的运算工厂类就不用了。
先创建一个工厂接口。
package com.lwx.factory; /** * Created with IntelliJ IDEA. * Description: 工厂接口 * User: lwx * Date: 2019-03-09 * Time: 21:15 */ public interface Factory { Operation createOperation(); }
然后是四种运算的具体实现工厂类。
package com.lwx.factory; /** * Created with IntelliJ IDEA. * Description: 加法类工厂 * User: lwx * Date: 2019-03-09 * Time: 21:16 */ public class AddFactory implements Factory { @Override public Operation createOperation() { return new OperationAdd(); } }
package com.lwx.factory; /** * Created with IntelliJ IDEA. * Description: 减法工厂类 * User: lwx * Date: 2019-03-09 * Time: 21:17 */ public class SubFactory implements Factory { @Override public Operation createOperation() { return new OperationSub(); } }
package com.lwx.factory; /** * Created with IntelliJ IDEA. * Description: 乘法工厂类 * User: lwx * Date: 2019-03-09 * Time: 21:18 */ public class MulFactory implements Factory { @Override public Operation createOperation() { return new OperationMul(); } }
package com.lwx.factory; /** * Created with IntelliJ IDEA. * Description: 除法工厂类 * User: lwx * Date: 2019-03-09 * Time: 21:19 */ public class DivFactory implements Factory { @Override public Operation createOperation() { return new OperationDiv(); } }
最后看下工厂方法模式的测试类和运行结果。
package com.lwx.factory; /** * Created with IntelliJ IDEA. * Description: * User: lwx * Date: 2019-03-09 * Time: 21:58 */ public class FactoryTest { public static void main(String[] args) { Factory factory = new DivFactory(); Operation operation = factory.createOperation(); operation.numberA = 8; operation.numberB = 10; System.out.println(operation.getResult()); } }
简单工厂模式的优缺点:
优点:
1.简单工厂包含必要的逻辑判断,简单工厂实现了对象的创建和使用的分离。
2.客户端无需知道所创建的集体产品类的类名,只需要知道具体产品类对应的参数即可。
3.在不修改客户端代码的情况下更换和增加新的具体产品类,在一定程度上提高了系统的灵活性。
缺点:
1.工厂类职责过重,从代码中可以看出简单工厂包含加减乘除的逻辑判断语句,它一旦有问题,整个系统都要出问题。
2.再添加新类的时候,简单工厂类就要修改,违反了开放———封闭原则,这样不利于系统的扩展和维护。
所以出现了工厂方法,工厂方法是简单工厂的进一步延伸,完美解决了开放——封闭原则的问题。
工厂方法模式的优缺点:
优点:
1.工厂方法用来创建客户所需的产品,同时隐藏了哪种具体产品类被实例化的细节,用户只需要关注工厂,不需要关注创建的细节。
2.在增加新的运算类时不用修改代码,只需要增加对应的工厂就好,完全符合开放——封闭原则。
缺点:
1.在增加新的产品时,也必须增加新的工厂类,会带来额外的开销。
俩个工厂各有利弊,简单工厂违反了最基本的原则,工厂方法完美解决了简单工厂的弊端,但是工厂方法的工厂个数过多,导致系统庞大。
最后附上demo的githup地址:https://github.com/yijinqincai/design_patterns