在学校的时候就看到一本书——《大话设计模式》,就觉得是一本好书,只是大略的浏览了一下,在青岛培训的时候,也看了一半左右,时间一长就忘了,重新看一遍,写写学习笔记。
简单工厂模式
问题:使用Java面向对象语言实现计算器控制台程序。
import java.util.Scanner;
public class Calculator {
public static void main(String[] args) {
String number_A = "";
String number_B = "";
String oper = "";
double result = 0d;
System.out.println("请输入数字A:");
@SuppressWarnings("resource")
Scanner input = new Scanner(System.in);
number_A = input.next();
System.out.println("请输入运算符号(+,-,*,/):");
oper = input.next();
System.out.println("请输入数字B:");
number_B = input.next();
switch (oper) {
case "+":
result = Double.parseDouble(number_A) + Double.parseDouble(number_B);
break;
case "-":
result = Double.parseDouble(number_A) - Double.parseDouble(number_B);
break;
case "*":
result = Double.parseDouble(number_A) * Double.parseDouble(number_B);
break;
case "/":
result = Double.parseDouble(number_A) / Double.parseDouble(number_B);
break;
}
System.out.println("结果为:" + result);
}
}
上面代码没有考虑除数不能为0的问题,并且没有实现业务和界面的分离。
要求1:业务和界面的分离:
/**
* @author xukai 业务的封装
*/
public class Operation {
public static double getResult(double number_A, double number_B, String operate) {
double result = 0d;
switch (operate) {
case "+":
result = number_A + number_B;
break;
case "-":
result = number_A - number_B;
break;
case "*":
if (number_B == 0) {
break;
} else {
result = number_A * number_B;
}
break;
case "/":
if (number_B == 0) {
break;
} else {
result = number_A / number_B;
}
break;
}
return result;
}
}
测试类:
package com.xk.night1225.factory.simple.calculator.factory;
import java.util.Scanner;
public class OperationTest {
public static void main(String[] args) {
String number_A = "";
String number_B = "";
String oper = "";
double result = 0d;
System.out.println("请输入数字A:");
@SuppressWarnings("resource")
Scanner input = new Scanner(System.in);
number_A = input.next();
System.out.println("请输入运算符号(+,-,*,/):");
oper = input.next();
System.out.println("请输入数字B:");
number_B = input.next();
result = Operation.getResult(Double.parseDouble(number_A), Double.parseDouble(number_B), oper);
System.out.println("结果为:" + result);
}
}
要求2:新增开根(sqrt)运算。
如果想要添加开根操作,需要在Operation类中添加一个case分支,也就相当于要更改源码,这样是不可取的,因为其他运算也会暴露给修改者,不安全。
引进简单工厂模式:
引进简单工厂模式:
创建一个Operation类:
public class Operation {
private double numberA;
private double numberB;
public double getResult() {
double result = 0.0;
return result;
}
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;
}
}
对应不同的运算,创建不同的运算类,如加法运算:
/**
* @author xukai
* 加法操作
*/
public class OperationAdd extends Operation {
@Override
public double getResult() {
return getNumberA() + getNumberB();
}
}
创建工厂:
/**
* @author xukai
* 运算工厂
*/
public class OperationFactory {
public static Operation createOperate(String operate){
Operation oper = null;
switch (operate) {
case "+":
oper = new OperationAdd();
break;
case "-":
oper = new OperationSub();
break;
case "*":
oper = new OperationMul();
break;
case "/":
oper = new OperationDiv();
break;
}
return oper;
}
}
通过工厂实例化需要的运算类对象,使用多态,实现了计算器的运算结果。
测试:
public class OperationTest {
public static void main(String[] args) {
double a = 1.0;
double b = 2.0;
Operation oper = OperationFactory.createOperate("+");
oper.setNumberA(a);
oper.setNumberB(b);
System.out.println(oper.getResult());
}
}
现在需要实现开方运算,只需要添加Sqrt类继承Operation类,对返回结果进行方法实现,和在OperationFactory工厂添加case分支判断。
总结
使用设计模式需要达到的目的:
1.可维护,程序可以被修改。
2.可复用,程序可以被重复使用。
3.可扩展,程序有新功能产生,可以扩展、实现该功能。
4.灵活性好,程序执行方式可以改变。
例:印刷“对酒当歌,人生几何”
1.印刷的每个字都可以被修改(可维护)。
2.可以多次印刷(可复用)。
3.可以在中间添字(可扩展)。
4.可以横着印刷,也可以竖着印刷(灵活性好)。