工厂方法模式(Factory Method),定义一个用于创建对象的接口,让子类决定实例化哪一个类。工厂方法使一个类的实例化延迟到其子类。
用之前简单工厂模式做的计算器举例,先看简单工厂模式的实现:
//计算接口
public interface Operation {
public double getResult(double _numberA, double _numberB);
}
//加法运算
public class OperationAdd implements Operation {
@Override
public double getResult(double _numberA, double _numberB) {
return _numberA + _numberB;
}
}
//减法运算
public class OperationSub implements Operation {
@Override
public double getResult(double _numberA, double _numberB) {
return _numberA - _numberB;
}
}
//乘法运算
public class OperationMul implements Operation {
@Override
public double getResult(double _numberA, double _numberB) {
return _numberA * _numberB;
}
}
//除法运算
public class OperationDiv implements Operation {
@Override
public double getResult(double _numberA, double _numberB) {
if (_numberB == 0) {
throw new RuntimeException("除数B不能为0.");
}
return _numberA / _numberB;
}
}
//运算类工厂
public class OperationFactory1 {
Operation oper = null;
public Operation createOperate(String operate) {
switch (operate) {
case "+":
oper = new OperationAdd();
break;
case "-":
oper = new OperationSub();
break;
case "*":
oper = new OperationMul();
break;
case "/":
oper = new OperationDiv();
break;
default:
break;
}
return oper;
}
}
工厂模式就是将之前的工厂类OperFactory变为一个工厂接口,然后加减乘除各建一个具体工厂去实现这个接口:
//运算类工厂
public class OperationFactory2 {
IFactory oper = null;
public IFactory createOperate(String operate) {
switch (operate) {
case "+":
oper = new AddFactory();
break;
case "-":
oper = new SubFactory();
break;
case "*":
oper = new MulFactory();
break;
case "/":
oper = new DivFactory();
break;
default:
break;
}
return oper;
}
}
//加法运算
public class AddFactory implements IFactory {
@Override
public Operation createOperation() {
return new OperationAdd();
}
}
//减法运算
public class SubFactory implements IFactory {
@Override
public Operation createOperation() {
return new OperationSub();
}
}
//除法运算
public class DivFactory implements IFactory {
@Override
public Operation createOperation() {
return new OperationDiv();
}
}
//乘法运算
public class MulFactory implements IFactory {
@Override
public Operation createOperation() {
return new OperationMul();
}
}
//除法运算
public class OperationDiv implements Operation {
@Override
public double getResult(double _numberA, double _numberB) {
if (_numberB == 0) {
throw new RuntimeException("除数B不能为0.");
}
return _numberA / _numberB;
}
}
下面来对比一下简单工厂模式和工厂模式的实现计算器:
import java.util.Scanner;
//简单工厂模式实现计算器
public class Calculator {
public static void main(String[] args) {
double numberA = 0d;
double numberB = 0d;
String operate = "";
double result = 0d;
try {郑州人流手术多少钱 http://www.zzzzyy120.com/
Scanner sc = new Scanner(System.in);
System.out.println("Java简单工厂模式计算器:");
System.out.println("请输入数字A:");
numberA = sc.nextDouble();
System.out.println("请选择运算符号(+、-、*、/):");
operate = sc.next();
System.out.println("请输入数字B:");
numberB = sc.nextDouble();
Operation operation = new OperationFactory().createOperate(operate);
if (operation == null) {
System.out.println("请在“+、-、*、/”选择正确的运算符");
} else {
result = operation.getResult(numberA, numberB);
System.out.println(String.format("您的计算结果是:%s %s %s = %s", numberA, operate, numberB, result));
}
sc.close();
} catch (Exception e) {
System.out.println(String.format("您的输入有误:%s", e.getMessage()));
}
}
}
import java.util.Scanner;
//工厂模式实现计算器
public class Calculator {
public static void main(String[] args) {
double numberA = 0d;
double numberB = 0d;
String operate = "";
double result = 0d;
try {
Scanner sc = new Scanner(System.in);
System.out.println("Java简单工厂模式计算器:");
System.out.println("请输入数字A:");
numberA = sc.nextDouble();
System.out.println("请选择运算符号(+、-、*、/):");
operate = sc.next();
System.out.println("请输入数字B:");
numberB = sc.nextDouble();
IFactory operation = new OperationFactory2().createOperate(operate);
if (operation == null) {
System.out.println("请在“+、-、*、/”选择正确的运算符");
} else {
result = operation.createOperation().getResult(numberA, numberB);
System.out.println(String.format("您的计算结果是:%s %s %s = %s", numberA, operate, numberB, result));
}
sc.close();
} catch (Exception e) {
System.out.println(String.format("您的输入有误:%s", e.getMessage()));
}
}
}
可以看出来,如果需要增加其他的运算方法,使用简单工厂模式时,工厂类OperationFactory2需要对原有的代码进行修改,就违背了开放-封闭原则。而采用工厂模式时,只需要增加一个新算法的工厂实现类,在调用时采用new OperationFactory2()就可以采用新的算法进行计算了。
工厂方法模式实现时,客户端需要决定实例化哪一个工厂来实现运算类,选择判断的问题还是存在的,也就是说,工厂方法把简单工厂的内容逻辑判断移到了客户端代码来进行。你想要加功能,本来是改工厂的,而现在是修改客户端。