又是一个名字里面有工厂的模式,首先一个问题,不免的会和简单工厂模式比较,并且很可能会混淆。
为了更好的与简单工厂模式比较,这里还是以简单工厂时举的计算器的例子例子来说明。
传送门:简单工厂--造啥做啥
这篇文章中,要求实现一个计算器的功能,我们开始使用了简单工厂的模式,也就是把加减乘除的
各种运算都抽象出来了,并且各司其职,在不同的Operation类里面完成不同的操作。
最后,在统一交给OperationFactory进行创建以及调用。
其实,这个模式还是有那么一丁点问题的,比如现在要增加一种新的运算取模,那会进行如下几个步骤:
1、增加一个取模类继承自Operation;
2、修改OperationFactory,增加一个switch分支;
那这样是不是有点问题呢?
对了,它一定程度上违反了“封闭开放原则”,也就是修改了以前的代码。
这样的操作虽然不会有啥问题,但是对于以前的类,我们应该做到尽量不修改,因为说不定你在
修改旧类的同时,一不小心动了一些东西,导致旧类无法使用,这就很尴尬了。
这样一来,如果用工厂方法来写,就会显得好很多,先看看类图理解下大致的类结构:
如上图,我们可以看到,在以前的OperationFactory上,工厂方法又抽象出了一层,
Operation有他的类结构,而Factory也有它的类结构,User知识测试类,
这样一来的好处很明显,同样的条件,当你要添加一个新的运算时,你需要这样的步骤:
1、写一个OperationXXX类,继承Operation;
2、再写一个FactoryXXX类,继承Factory;
3、如果要用,直接更改User类代码就行。
这样一来,就不用栋以前的类,而只需要栋测试类User,这就使得操作符合开放封闭原则了。
下面来看具体代码:
Operation类:
package com.blog.anla.FactoryMethod;
/**
* 运算的统一父类,包含相应规范的抽象类
* @author U-ANLA
*
*/
public abstract class Operation {
protected double numberA;
protected double numberB;
public abstract double getResult();
}
OperationAdd类:
package com.blog.anla.FactoryMethod;
/**
* 加法运算类
* @author U-ANLA
*
*/
public class OperationAdd extends Operation{
@Override
public double getResult() {
return numberA + numberB;
}
}
OperationSub类:
package com.blog.anla.FactoryMethod;
/**
* 减法运算类
* @author U-ANLA
*
*/
public class OperationSub extends Operation{
@Override
public double getResult() {
return numberA -numberB;
}
}
OperationMul类:
package com.blog.anla.FactoryMethod;
/**
* 乘法运算
* @author U-ANLA
*
*/
public class OperationMul extends Operation{
@Override
public double getResult() {
return numberA * numberB;
}
}
OperationDiv类:
package com.blog.anla.FactoryMethod;
/**
* 除法运算
* @author U-ANLA
*
*/
public class OperationDiv extends Operation{
@Override
public double getResult() {
if(numberB == 0){
return 0;
}else{
return numberA / numberB;
}
}
}
Factory类:
package com.blog.anla.FactoryMethod;
/**
* 工厂类,用于定义统一的规范的抽象类
* 即专门用于创建工厂
* @author U-ANLA
*
*/
public abstract class Factory {
public abstract Operation createOperation();
}
AddFactory类:
package com.blog.anla.FactoryMethod;
/**
* 创建加法工厂
* @author U-ANLA
*
*/
public class AddFactory extends Factory{
@Override
public Operation createOperation() {
return new OperationAdd();
}
}
SubFactory类:
package com.blog.anla.FactoryMethod;
/**
* 创建减法工厂
* @author U-ANLA
*
*/
public class SubFactory extends Factory{
@Override
public Operation createOperation() {
return new OperationSub();
}
}
MulFactory类:
package com.blog.anla.FactoryMethod;
/**
* 创建乘法工厂
* @author U-ANLA
*
*/
public class MulFactory extends Factory{
@Override
public Operation createOperation() {
return new OperationMul();
}
}
DivFactory类:
package com.blog.anla.FactoryMethod;
/**
* 创建除法工厂。
* @author U-ANLA
*
*/
public class DivFactory extends Factory{
@Override
public Operation createOperation() {
return new OperationDiv();
}
}
User类:
package com.blog.anla.FactoryMethod;
/**
* 测试类,main方法
* 工厂方法和简单方法的不同之处在于
* 1、工厂方法又向上抽象出来了一层,也就是把运算类从工厂里面抽出来了
* 因而工厂只用于生产
* 2、将switch的语句,从工厂里面抽出来了,放到了客户端的User类里面。
* @author U-ANLA
*
*/
public class User {
public static void main(String[] args) {
Factory factory = myOperation('+');
Operation operation = factory.createOperation();
operation.numberA = 1;
operation.numberB = 2;
System.out.println(operation.getResult());
}
public static Factory myOperation(char operation){
switch (operation) {
case '+':
return new AddFactory();
case '-':
return new SubFactory();
case '*':
return new MulFactory();
case '/':
return new DivFactory();
default:
//默认
return new AddFactory();
}
}
}
赠人玫瑰手留余香,有问题欢迎交流(oo)