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

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

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

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

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

各种运算都抽象出来了,并且各司其职,在不同的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)









  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值