工厂方法模式--简单工厂的再抽象

来源:互联网 发布:经传软件试用版 编辑:程序博客网 时间:2024/04/29 13:39

又是一个名字里面有工厂的模式,首先一个问题,不免的会和简单工厂模式比较,并且很可能会混淆。

为了更好的与简单工厂模式比较,这里还是以简单工厂时举的计算器的例子例子来说明。

传送门:简单工厂--造啥做啥 

这篇文章中,要求实现一个计算器的功能,我们开始使用了简单工厂的模式,也就是把加减乘除的

各种运算都抽象出来了,并且各司其职,在不同的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{@Overridepublic double getResult() {return numberA + numberB;}}


OperationSub类:

package com.blog.anla.FactoryMethod;/** * 减法运算类 * @author U-ANLA * */public class OperationSub extends Operation{@Overridepublic double getResult() {return numberA -numberB;}}


OperationMul类:

package com.blog.anla.FactoryMethod;/** * 乘法运算 * @author U-ANLA * */public class OperationMul extends Operation{@Overridepublic double getResult() {return numberA * numberB;}}


OperationDiv类:

package com.blog.anla.FactoryMethod;/** * 除法运算 * @author U-ANLA * */public class OperationDiv extends Operation{@Overridepublic 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{@Overridepublic Operation createOperation() {return new OperationAdd();}}


SubFactory类:

package com.blog.anla.FactoryMethod;/** * 创建减法工厂 * @author U-ANLA * */public class SubFactory extends Factory{@Overridepublic Operation createOperation() {return new OperationSub();}}


MulFactory类:

package com.blog.anla.FactoryMethod;/** * 创建乘法工厂 * @author U-ANLA * */public class MulFactory extends Factory{@Overridepublic Operation createOperation() {return new OperationMul();}}


DivFactory类:

package com.blog.anla.FactoryMethod;/** * 创建除法工厂。 * @author U-ANLA * */public class DivFactory extends Factory{@Overridepublic 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)









阅读全文
0 0
原创粉丝点击