设计模式-简单工厂模式


场景
老大:
做个简单的加减乘除功能
我:
好的,那我先用java做个控制台版本的。
老大:
可以
于是,我开始动工,使用 eclipse 新建了一个简单的控制台项目,写下如下的代码:
import java.util.Scanner;
public class SimplePattern {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
System.out.println("目前支持 加、减、乘、除 四种运算 \r加法请输入1,减法请输入2,乘法请输入3,除法请输入4。");
System.out.println("请选择算法:");
String operateNum = scanner.nextLine();
//对 operateNum 的验证略(非空验证,值为1,2,3,4其中一个值的验证)
System.out.println("请输入其中一个数字:");
String oneNumber = scanner.nextLine();
System.out.println("输入的数字是:" + oneNumber);
System.out.println("请输入另外一个数字:");
String anotherNumber = scanner.nextLine();
System.out.println("输入的另外一个数字是:" + anotherNumber);
scanner.close();
//todo:oneNumber 和 anotherNumber 需要验证是否是数字,这里省略
Double one = Double.parseDouble(oneNumber);
Double another = Double.parseDouble(anotherNumber);
Double result = 0d;
if(operateNum.equals("1")) {
result = one + another;
}else if(operateNum.equals("2")) {
result = one - another;
}else if(operateNum.equals("3")) {
result = one * another;
}else if(operateNum.equals("4")) {
if(another.equals(0d)) {
System.out.println("除数不能为0");
return;
}
result = one / another;
}
System.out.println("计算的结果是:" + result);
}
}
搞定了,心想:
总算写完了,老大还没找我,反正写完了,休息一会,聊聊天,逛逛网页。
几分钟过去了…
不行,我要表现的积极些,不能老大找我,我才汇报情况,我得主动出击,去告诉一下我这的情况。
我向老大的工位走去…
我:
老大,东西弄完了,你看下行不行。
我向老大演示了一下,老大说道:
老大:
功能是没问题,你把业务逻辑提取一下,就是封装到一个类中,接下来的项目我们要用到。要做到复用。
我:
好的。
我看着代码,想了想:
目前是控制台版本的,如果集成到项目中,可能是 Web 版本,或其他版本的,和现在的区别就是获取用户输入的信息的方式不同而已。计算逻辑还是一样的,把一样的逻辑提取出来就可以了。
想明白了,动手。
新建了一个计算器类:
package SimplePattern02;
public class Calculator {
public Double getResult(String oneNumber,String anotherNumber,String operateNum) throws Exception {
//对 operateNum 的验证略(非空验证,值为1,2,3,4其中一个值的验证)
//todo:oneNumber 和 anotherNumber 需要验证是否是数字,这里省略
Double one = Double.parseDouble(oneNumber);
Double another = Double.parseDouble(anotherNumber);
Double result = 0d;
if(operateNum.equals("1")) {
result = one + another;
}else if(operateNum.equals("2")) {
result = one - another;
}else if(operateNum.equals("3")) {
result = one * another;
}else if(operateNum.equals("4")) {
if(another.equals(0d)) {
throw new Exception("除数不能为0");
}
result = one / another;
}
return result;
}
}
这样控制台的部分代码就简化了很多:
package SimplePattern02;
import java.util.Scanner;
public class Program {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
System.out.println("目前支持 加、减、乘、除 四种运算 \r加法请输入1,减法请输入2,乘法请输入3,除法请输入4。");
System.out.println("请选择算法:");
String operateNum = scanner.nextLine();
System.out.println("请输入其中一个数字:");
String oneNumber = scanner.nextLine();
System.out.println("输入的数字是:" + oneNumber);
System.out.println("请输入另外一个数字:");
String anotherNumber = scanner.nextLine();
System.out.println("输入的另外一个数字是:" + anotherNumber);
scanner.close();
Calculator cal = new Calculator();
Double result = 0d;
try {
result = cal.getResult(oneNumber, anotherNumber, operateNum);
} catch (Exception e) {
System.out.println(e.getMessage());
return;
}
System.out.println("计算结果为:" + result);
}
}
搞定后,我又去找老大汇报。
我:
老大,我搞完了,你再看下。
老大:
好,我看下。嗯…. 目前而言,差不多了。
你这个计算器类下的业务逻辑还不算复杂,
你这里用到了4个if判断,现在每个判断里面也就1行代码。所以,目前就可以了。
后面如果变复杂的话,你就还需要优化了。比如说,如果你每个if下面都10几行代码,那这个计算器类就显得过于复杂了。这时候,你就可以把每个if的业务逻辑抽离出来了。
我想了想。先提前抽离一下,当需要抽离的时候,自己好轻车熟路。
于是,我将4个if抽离成了4个业务逻辑,加法运算,减法运算,乘法运算,除法运算。
分别为每个运算定义了一个类。这些类都实现一个名为“运算”的接口。
接口
package SimplePattern03;
public interface IOperation {
Double getResult() throws Exception;
}
加法运算
package SimplePattern03;
public class OperationAdd implements IOperation {
private Double one;
private Double another;
public Double getOne() {
return one;
}
public void setOne(Double one) {
this.one = one;
}
public Double getAnother() {
return another;
}
public void setAnother(Double another) {
this.another = another;
}
@Override
public Double getResult() {
return one + another;
}
}
减法运算
package SimplePattern03;
public class OperationSub implements IOperation {
private Double one;
private Double another;
public Double getOne() {
return one;
}
public void setOne(Double one) {
this.one = one;
}
public Double getAnother() {
return another;
}
public void setAnother(Double another) {
this.another = another;
}
@Override
public Double getResult() {
return one - another;
}
}
乘法运算
package SimplePattern03;
public class OperationMul implements IOperation {
private Double one;
private Double another;
public Double getOne() {
return one;
}
public void setOne(Double one) {
this.one = one;
}
public Double getAnother() {
return another;
}
public void setAnother(Double another) {
this.another = another;
}
@Override
public Double getResult() {
return one * another;
}
}
除法运算
package SimplePattern03;
public class OperationDiv implements IOperation {
private Double one;
private Double another;
public Double getOne() {
return one;
}
public void setOne(Double one) {
this.one = one;
}
public Double getAnother() {
return another;
}
public void setAnother(Double another) {
this.another = another;
}
@Override
public Double getResult() throws Exception {
if(another.equals(0d)) {
throw new Exception("除数不能为0");
}
return one / another;
}
}
工厂模式
四个逻辑出来了,这样计算器类中只是根据不同的情况来创建不同的对象实例即可。我把这个根据不同情况创建实例的任务也分离出去吧
package SimplePattern03;
public class OperationFactory {
public static IOperation getOperation(Double one,Double another, String operateNum) {
IOperation operation = null;
if(operateNum.equals("1")) {
OperationAdd oper = new OperationAdd();
oper.setOne(one);
oper.setAnother(another);
operation = oper;
}else if(operateNum.equals("2")) {
OperationSub oper = new OperationSub();
oper.setOne(one);
oper.setAnother(another);
operation = oper;
}else if(operateNum.equals("3")) {
OperationMul oper = new OperationMul();
oper.setOne(one);
oper.setAnother(another);
operation = oper;
}else if(operateNum.equals("4")) {
OperationDiv oper = new OperationDiv();
oper.setOne(one);
oper.setAnother(another);
operation = oper;
}
return operation;
}
}
这里的 OperationFactory 就是简单工厂模式。
这样,计算器类就变成这样了。
package SimplePattern03;
public class Calculator {
public Double getResult(String oneNumber,String anotherNumber,String operateNum) throws Exception {
//对 operateNum 的验证略(非空验证,值为1,2,3,4其中一个值的验证)
//todo:oneNumber 和 anotherNumber 需要验证是否是数字,这里省略
Double one = Double.parseDouble(oneNumber);
Double another = Double.parseDouble(anotherNumber);
Double result = 0d;
IOperation oper = OperationFactory.getOperation(one, another, operateNum);
result = oper.getResult();
return result;
}
}
这样,以后哪个运算逻辑要修改,只改对应的类即可。增加了运算逻辑,也就再新增一个运算类即可。维护起来简单多了。
*昵称:
*邮箱:
个人站点:
*想说的话: