设计模式学习总结——工厂方法模式
今天来讲述一下关于工厂方法模式的问题,以及使用的地方。
关于工厂方法模式的介绍如下:
工厂方法(Factory Method)模式,定义一个创建产品对象的工厂接口,将实际创建工作推迟到子类当中。核心工厂类不再负责产品的创建,这样核心类成为一个抽象工厂角色,仅负责具体工厂子类必须实现的接口,这样进一步抽象化的好处是使得工厂方法模式可以使系统在不修改具体工厂角色的情况下引进新的产品。
上面这句话,怎么理解呢?
很好理解,我们都知道,简单工厂模式,违背了一个原则,就是我们著名的开放-封闭原则,也就是说,简单工厂模式,是扩展进行了开放,但是也对修改进行了开放。
按照上一篇我们所讲述的简单工厂模式的计算器来举例:
实现步骤如下:
1.创建一个操作类,用来保存,对应数字,以及得到最终结果:
/**
* 具体的操作类
* */
public class Operate {
public double numberA;
public double numberB;
public double getResult() throws Exception {
double resultNumber = 0d;
return resultNumber;
}
}
具体的加减乘除对应的操作类:
public class OperateAdd extends Operate {
@Override
public double getResult() throws Exception {
double result = 0d;
result = numberA + numberB;
return result;
}
}
public class OperateSub extends Operate {
@Override
public double getResult() throws Exception {
double result = 0d;
result = numberA - numberB;
return result;
}
}
public class OperateMul extends Operate {
@Override
public double getResult() throws Exception {
double result = 0d;
result = numberA * numberB;
return result;
}
}
public class OperateDiv extends Operate {
@Override
public double getResult() throws Exception {
double result = 0d;
if (numberB != 0) {
result = numberA / numberB;
} else {
throw new Exception("除数不能为0");
}
return result;
}
}
简单工厂类:
public class OperateFactory {
/**
* 让工厂知道使用哪一个对象。
* @param strOperate
* @return
*/
public static Operate createOperate(String strOperate){
Operate operate = null;
switch (strOperate){
case "+":
operate = new OperateAdd();
break;
case "-":
operate = new OperateSub();
break;
case "*":
operate = new OperateMul();
break;
case "/":
operate = new OperateDiv();
break;
}
return operate;
}
}
客户端类:
public class Calc {
public static void main(String[] args) throws Exception {
Operate operate = null;
operate = OperateFactory.createOperate("+");
operate.numberA = 1;
operate.numberB = 1;
double result = operate.getResult();
System.out.println("最终结果如下:"+result);
}
}
上面这段代码的实现就是简单工厂对于计算器的实现,如果我们这时有一个新的需求:要求加一个求M数的N次方,我们是一定需要在简单工厂类的switch中增加新的case分支。相当于我们已经提供了对于简单工厂类的修改功能,那么就违背了开放扩展-封闭修改的原则了。所以,这个时候,工厂方法模式就来了。
工厂方法模式,很好理解,就是定义一个基本工厂接口,然后创建一个工厂继承这个接口,然后通过新的工厂去创建你所需要的类。完了。。。
拿上面的计算器来举例:
1.首先定义一个基本工厂:
public interface MyFactory {
public Operate createFactory();
}
2.定义你所需要的加法,减法,乘法,除法的工厂,这几个工厂都实现了基本工厂接口。
public class FactoryAdd implements MyFactory {
@Override
public Operate createFactory() {
return new OperateAdd();
}
}
public class FactorySub implements MyFactory{
@Override
public Operate createFactory() {
return new OperateSub();
}
}
public class FactoryMul implements MyFactory {
@Override
public Operate createFactory() {
return new OperateMul();
}
}
public class FactoryDiv implements MyFactory {
@Override
public Operate createFactory() {
return new OperateDiv();
}
}
3.客户端类:
public class TestMain {
public static void main(String[] args) throws Exception {
//
MyFactory myFactory = new FactoryAdd();
Operate operate = myFactory.createFactory();
operate.numberA = 1;
operate.numberB = 2;
System.out.println("我是结果:"+operate.getResult());
}
}
输出结果:
我是结果:3.0
类比于简单工厂模式:
相同点:
- 都是集中封装了对象的创建,使得需要更换对象的时候,不需要做很大的改动就可以实现。
- 降低了客户程序与产品对象的耦合。
不同点:
- 工厂方法模式是简单工厂模式的进一步抽象和推广,由于使用了多态性,工厂方法模式,保存了简单工厂模式的优点:开放拓展性。克服了它的缺点:开放了修改性。
缺点:
- 工厂方法模式,在增加每一个产品,就必须增加一个产品工厂的类,增加了额外的开发量。
至此,工厂方法模式总结完毕,后面LZ会使用反射对工厂方法模式的缺点进行优化。。。。