定义
工厂方法模式:一个用于创建对象的接口,让子类决定实例化哪一个类。工厂方法使一个类的实例化延迟到其子类。
优点
工厂方法克服了简单工厂违反开发-封闭原则的缺点,既保持了封装对象创建过程的优点。
缺点
工厂方法模式实现时,客户端需要决定实例化哪一个工厂来实现运算类,选择判断的问题还是存在的,也就是说工厂方法把简单工厂的内部逻辑判断转移到了客户端代码中进行。你想要加功能,本来是改工厂类的而现在是修改客户端。
结构图
Creator:工厂类接口,将创建各个产品的具体的工厂抽象出来成一个接口。
ConcreteCreateor:具体的工厂类,不同的工厂类创建不同的产品。
Product:产品的接口,将各个产品抽象出来成一个抽象类。
ConcreteProduct:具体的产品。
实例
还是和上篇的简单工厂模式是同一个实例。
实现一个计算器程序,要求输入两个数和运算符号,得到结果。
类图:
编码实现:
IFactory接口:
将加减乘除运算类的各个工厂类抽象成一个抽象工厂类。
public interface IFactory {
Operation CreateOperation();
}
加法工厂类:
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 MulFactory implements IFactory{
@Override
public Operation CreateOperation() {
return new OperationMul();
}
}
除法工厂类:
public class DivFactory implements IFactory{
@Override
public Operation CreateOperation() {
return new OperationDiv();
}
}
操作抽象类:
public abstract class Operation {
protected double numberA;
protected double numberB;
public double getNumberA() {
return numberA;
}
public void setNumberA(double numberA) {
this.numberA = numberA;
}
public double getNumberB() {
return numberB;
}
public void setNumberB(double numberB) {
this.numberB = numberB;
}
public abstract double getResult();
}
加法操作类:
public class OperationAdd extends Operation{
@Override
public double getResult() {
return numberA+numberB;
}
}
减法操作类:
public class OperationSub extends Operation{
@Override
public double getResult() {
return numberA-numberB;
}
}
乘法操作类:
public class OperationMul extends Operation{
@Override
public double getResult() {
return numberA * numberB;
}
}
除法操作类:
public class OperationDiv extends Operation{
@Override
public double getResult() {
if(numberB==0){
try {
throw new Exception("除数不能为0");
} catch (Exception e) {
e.printStackTrace();
}
}
double result = numberA/numberB;
return result;
}
}
客户端代码:
public class Client {
public static void main(String[] args) {
IFactory factory = new AddFactory();
Operation oper = factory.CreateOperation();
oper.setNumberA(10);
oper.setNumberB(20);
System.out.println("result="+oper.getResult());;
}
}
和简单工厂模式相比较,克服每次扩展时需要更改简单工厂类的缺点(克服了简单工厂类违反了开闭-原则的缺点),但是现在客户端需要知道更多的类。之前客户端只需要知道简单工厂类、抽象产品类。现在需要知道抽象工厂类、具体工厂类、抽象产品类。多了一个具体产品类。之前在简单的判断逻辑转移到了客户端中,由客户端选择实例化哪一个工厂类 。
客户端需要知道的类
抽象工厂类、具体工厂类、抽象产品类
最后
通常创建型模式的设计是从工厂方法开始,当设计者发现需要更大的灵活性时,设计便会向其他设计模式演化。