1.1问题
实现一个计算器控制台程序,要求输入两个数和运算符号,得到结果
1.2开放封闭原则
问题不难,但是下手之前,先聊一个原则:
开放封闭原则:软件实体类(类,模块,函数等)应该可以扩展,但是不可以修改。
即就是对于扩展是开放的,对于更改是封闭的。
面向对象语言的基本单位是类,面向过程语言的基本单位是函数。一个基本单位就好像一个汉字,当我使用活字印刷写诗的时候,字可以复用,可以添减,可以调整。但是不应该去“涂改”了这个字。每次修改函数,修改类,就是在“涂改”字—“涂改”—真是一个想想都别扭的事。
我理解:应该减少,甚至避免。
1.3 简单工厂模式设计
UML图解如下,接口IOperate的方法operate代表了对两个操作数的操作,Plus(加法)、Minus(减法)具体实现自己的操作(加减)。main函数通过OperateFactory给createOperate传入具体的操作符,来得到具体的对应的“操作”。
1.4 具体代码实现:
/**
* IOperate 接口
*/
public interface IOperate{
int operate(int first,int second);
}
/**
* 加法类
*/
public class Plus implements IOperate{
@Override
public int operate(int first,int second){
return first + second;
}
}
/**
* 减法类
*/
public class Minus implements IOperate{
@Override
public int operate(int first,int second){
return first-second;
}
}
/**
* OperateFactory 类
*/
public class OperateFactory{
public static IOperate createOperate(String opSymbol){
switch(opSymbol){
case "+":
return new Plus();
case "-":
return new Minus();
default:
return null;
}
}
}
/**
* 主类
*/
import java.util.Scanner;
public class Main{
private static int first;
private static int second;
private static String opSymbol;
public static void main(String[] args){
init();
IOperate iOperate = OperateFactory.createOperate(opSymbol);
int result = iOperate.operate(first,second);
System.out.println("结果是: " + result);
}
private static void init(){
Scanner sc = new Scanner(System.in);
System.out.println("请输入第一个运算数:");
first = sc.nextInt();
System.out.println("请输入运算符:");
opSymbol = sc.next();
System.out.println("请输入第二个运算数:");
second = sc.nextInt();
}
}
1.5 我的想法
“运算”这个抽象动作—不,在本例里,应该叫“二元运算”这个抽象动作,可以派生出派生出具体动作:加减乘除。
基本原理是使用
- “继承”:实现接口
- 向上转型:
IOperate iOperate = OperateFactory.createOperate(opSymbol);
int result = iOperate.operate(first,second);
对比写法:
- 不使用任何模式,在main函数里用switch运算符做判断然后进行运算
以下考察均与此写法(以下自称main法)对比
考察扩展性:
- 新增一个运算(比如乘法)时,需要新增乘法类实现IOperate接口。满足开放封闭原则
- 修改OperaFactory,新增一个case语句。违反开放封闭原则
两法均有破坏
考察复用性:
- main法只能用在main里,无法复用
- 简单工厂中的整个工厂部分可以挪作他用:供其他模块使用;打包之后可以跑在服务器,跑在Android…
考察可维护性:
假设加法的运算方式改变了(当然这不可能:))
- main法是过程思维需要从main读起,然后修改
- 简单工厂可以精准找到Plus类进行修改