设计模式——简单工厂 VS 工厂方法
?简单工厂模式:
它最大优点在于工厂类中包含了必要的逻辑判断,根据客户端的选择条件动态的实例化相关的类, 对于客户端来说,去除了与具体产品的依赖。
?
使用了封装、继承、多态面向对象的三大特性,能做到灵活的修改和扩展,如要修改加法运算,或添加开根号运算,只需添加一个开根号运算的类,并在工厂中的switch case加一分支即可

?
工厂方法模式:
工厂方法模式,定义一个用于创建对象的接口,让子类决定实例化哪一个类,使得一个类的实例化延迟到其子类。
?
工厂方法模式实现时,客户端需要决定实例化那个工厂来实现运算类,选择判断的问题还是存在的,也就是说,工厂方法把简单工厂的内部逻辑判断移到了客户端代码来进行。想要加功能,本来是改工厂类的,而现在是修改客户端。
?
工厂方法模式是简单工厂的进一步抽象和推广,由于使用了多态性,工厂方法模式保持了简单工厂模式的优点,而且克服了它的缺点。但缺点是由于每加一个产品都需要加一个产品工厂类,增加了额外的开发量。

?
实例
实现加减乘除运算

Operation类:
package cn.edu.tju.simpleFactoryPattern;public class Operation {protected double a = 0;protected double b = 0;public double getA() {return a;}public void setA(double a) {this.a = a;}public double getB() {return b;}public void setB(double b) {this.b = b;}public double getResult() throws Exception{return 0;}}?继承Operation类,覆盖getResult方法
加法:
package cn.edu.tju.simpleFactoryPattern;public class AddOperation extends Operation{public double getResult(){return a + b;}}?减法:
package cn.edu.tju.simpleFactoryPattern;public class SubtractOperation extends Operation{public double getResult(){return a - b;}}?乘法:
package cn.edu.tju.simpleFactoryPatern;public class MultiplyOperation extends Operation{public double getResult(){return a * b;}}?除法:
package cn.edu.tju.simpleFactoryPattern;public class DivideOperation extends Operation{public double getResult() throws Exception{if (b == 0){throw new Exception("b can not be zero!");}return a / b;}}?工厂类,包含必要的逻辑判断
package cn.edu.tju.simpleFactoryPattern;public class OperationFactory {public static Operation createOperation(char type){Operation oper = null;switch(type){case '+':oper = new AddOperation();break;case '-':oper = new SubtractOperation();break;case '*':oper = new MultiplyOperation();break;case '/':oper = new DivideOperation();break;}return oper;}}?测试类
package cn.edu.tju.simpleFactoryPattern;import java.util.Scanner;/* * 简单工厂模式的最大优点在于工厂类中包含了必要的逻辑判断,根据客户端的选择条件动态的实例化相关的类, * 对于客户端来说,去除了与具体产品的依赖。 */public class Test {public static void main(String[] args) throws Exception {Scanner scanner = new Scanner(System.in);while (System.in != null) {System.out.print("Please input the formula: ");double a = scanner.nextDouble();char o = scanner.next().toCharArray()[0];double b = scanner.nextDouble();Operation oper = OperationFactory.createOperation(o);oper.a = a;oper.b = b;double result = oper.getResult();System.out.println("The result is " + result);}}}?工厂方法模式:
运算类不变,把工厂类改为接口,并实现不同的工厂,从而产生不同的产品
工厂接口:
package cn.edu.tju.factoryMethodPattern;public interface OperationFactory {public Operation createOperation();}?加法工厂:
package cn.edu.tju.factoryMethodPattern;public class AddOperationFactory implements OperationFactory{@Overridepublic Operation createOperation() {// TODO Auto-generated method stubreturn new AddOperation();}}?加法工厂:
package cn.edu.tju.factoryMethodPattern;public class SubtractOperationFactory implements OperationFactory{@Overridepublic Operation createOperation() {// TODO Auto-generated method stubreturn new SubtractOperation();}}?乘法工厂:
package cn.edu.tju.factoryMethodPattern;public class MultiplyOperationFactory implements OperationFactory {@Overridepublic Operation createOperation() {// TODO Auto-generated method stubreturn new MultiplyOperation();}}?除法工厂
package cn.edu.tju.factoryMethodPattern;public class DivideOperationFactory implements OperationFactory{@Overridepublic Operation createOperation() {// TODO Auto-generated method stubreturn new DivideOperation();}}?修改测试类
package cn.edu.tju.factoryMethodPattern;import java.util.Scanner;/* * 工厂方法模式,定义一个用于创建对象的接口,让子类决定实例化哪一个类,使得一个类的实例化延迟到其子类。 * * 工厂方法模式实现时,客户端需要决定实例化那个工厂来实现运算类,选择判断的问题还是存在的,也就是说, * 工厂方法把简单工厂的内部逻辑判断移到了客户端代码来进行。想要加功能,本来是改工厂类的,而现在是修改客户端。 * * 工厂方法模式是简单工厂的进一步抽象和推广,由于使用了多态性,工厂方法模式保持了简单工厂模式的优点,而且克服 * 了它的缺点。但缺点是由于每加一个产品都需要加一个产品工厂类,增加了额外的开发量。 */public class Test {public static void main(String[] args) throws Exception {Scanner scanner = new Scanner(System.in);while (System.in != null) {System.out.print("Please input the formula: ");double a = scanner.nextDouble();char o = scanner.next().toCharArray()[0];double b = scanner.nextDouble();OperationFactory operFactory = null;switch(o){case '+':operFactory = new AddOperationFactory();break;case '-':operFactory = new SubtractOperationFactory();break;case '*':operFactory = new MultiplyOperationFactory();break;case '/':operFactory = new DivideOperationFactory();break;}Operation oper = operFactory.createOperation();oper.a = a;oper.b = b;double result = oper.getResult();System.out.println("The result is " + result);}}}??