一、简单工厂模式
我们以简单的计算器为例
level 1
拿到一个计算器的题目,大家一定会想到,使用switch判断符号,进入分支后计算
demo:
Operation.java
public static Operation getResult(double numberA,double numberB,String operate){
double result = 0;
//判断类型,创建对象
switch (operate){
case "+":
result = numberA + numberB;
break;
case "-":
result = numberA - numberB;
break;
case "*":
result = numberA * numberB;
break;
case "/":
result = numberA / numberB;
break;
default:
System.out.println("输入有误!请检查后重新输入!");
}
return result;
}
Client.java
public static void main(String[] args){
//此处略去输入赋值
double result = Operation.getResult(numberA,numberB,operate);
System.out.println("计算结果为:"+result);
}
这样一个简单的计算器就行写好了,但是你有没有发现一个问题,虽然将服务端和客户端进行了分离,但是如果需要完善这个计算器,增加新的运算方式,比如开平方的sqrt运算???如何解决??
解决方案:
更改Operation.java文件,在switch中增加一个分支。
结果:
1、这样仅仅是增加一个新的算法,却要使所有的算法都重新进行编译,也就是一个算法可以影响到所有的算法,这样使代码的
耦合度太高,不利于再次开发与维护。
2、另一方面就是每次增加功能点,你需要在集合了所有的算法的类中进行修改,一个失误操作可以让整个项目陷入泥潭
level 2
我们在level 1中的方案已经发现了他的利弊,那么如何来让自己的项目更加完善,使代码的耦合度降低,增大代码的可用性,可伸展性
我们可以试一试继承:
Operation.java
package designpatterns.simplefactorymode.service;
/**
* @author :DengSiYuan
* @date :2018/12/2 10:47
* @desc : 该类是对数字的封装以及运算结果的处理
*/
public class Operation {
private double numberA = 0;
private double numberB = 0;
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 double getResult() throws Exception {
double result = 0;
return result;
}
}
OperationAdd.java
package designpatterns.simplefactorymode.service;
/**
* @author :DengSiYuan
* @date :2018/12/2 11:37
* @desc :加法运算
*/
public class OperationAdd extends Operation {
@Override
public double getResult(){
double result = 0;
result = getNumberA() + getNumberB();
return result;
}
}
剩下的乘除亦然
这样使用继承,我们将所有运算共同需要的属性:两个数字和一个方法:算出结果,放入到他们共同的父类中,这样每次需要增加新的运算方式,只需要去继承这个Operation,如有其他特殊要求,进行扩展即可。
那么问题又来了:我们每次如何去判断这次是使用的什么运算方式(+?-?*?/),然后去创建相应的对象,这样我们就需要一个"工厂"来管理,举个例子:
我们去工厂告诉工厂主管说我们需要一个IPhone X,这时候他们知道了你所需要的手机类型后,告诉下面的工程师,创建了一个实体IPhone X对象。
程序中的工厂和现实中的一样,我们需要在程序的入口给工厂一个Type,他会根据你所告诉他的Type,创建一个你所需要使用的匹配的对象实体,调用使用他的方法
接下来我们来看Level 3
level 3
到了我们的重点:简单工厂模式
先看一下他的UML图吧
这是一个简单的设计
start ---> OperationFactory ---> 判断类型,动态创建对象 ---> 确切的知道那个类,使用其方法
Operation.java(所有运算的父类)
package designpatterns.simplefactorymode.service;
/**
* @author :DengSiYuan
* @date :2018/12/2 10:47
* @desc : 该类是对数字的封装以及运算结果的处理
*/
public class Operation {
private double numberA = 0;
private double numberB = 0;
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 double getResult() throws Exception {
double result = 0;
return result;
}
}
OperationFactory.java(管理对象的生成的工厂类)
package designpatterns.simplefactorymode.service;
/**
* @author :DengSiYuan
* @date :2018/12/2 12:19
* @desc :工厂模式,程序的入口,动态创建符合类型的对象
*/
public class OperationFactory {
public static Operation createOperation(String type){
Operation operation = null;
//判断类型,创建对象
switch (type){
case "+":
operation = new OperationAdd();
break;
case "-":
operation = new OperationSub();
break;
case "*":
operation = new OperationMul();
break;
case "/":
operation = new OperationDiv();
break;
default:
System.out.println("输入有误!请检查后重新输入!");
}
return operation;
}
}
OperationAdd.java(加法类)
package designpatterns.simplefactorymode.service;
/**
* @author :DengSiYuan
* @date :2018/12/2 11:37
* @desc :加法运算
*/
public class OperationAdd extends Operation {
@Override
public double getResult(){
double result = 0;
result = getNumberA() + getNumberB();
return result;
}
}
Client.java(客户端)大家可以去实现更加通用的,用户输入运算式,判断符号(封装成一个方法)
package designpatterns.simplefactorymode.client;
import designpatterns.simplefactorymode.InputDeal;
import designpatterns.simplefactorymode.service.Operation;
import designpatterns.simplefactorymode.service.OperationFactory;
import java.util.Scanner;
/**
* @author :DengSiYuan
* @date :2018/12/2 12:27
* @desc :用户端
*/
public class UserClient {
public static void main(String[] args) throws Exception {
String[] test = {"5","+","8"};
String input = InputDeal.getEveryValue(test);
Operation operation = OperationFactory.createOperation(input);
operation.setNumberA(Integer.parseInt(test[0]));
operation.setNumberB(Integer.parseInt(test[2]));
System.out.println(operation.getResult());
}
}
大家可以看到一个初级的使用简单工厂模式的计算器,根据一步一步的level比较,可以清楚的看到简单工厂模式存在的必要性以及他的优点。
持续更新设计模式!!