所有的设计模式,当然是依附于我们的业务开发。先来模拟一个需求,输入两个数字和操作符,实现加减乘除运算的功能,返回结果。看到这个需求,最初级的实现思想应该是下面这样:
//计算器类
public class Operation {
public static void main(String[] args){
System.out.println(getResult("1","2",'+'));
}
public static String getResult(String num1, String num2, char opeType){
String result = "";
switch (opeType){
case '+' :
result = new Double(num1) + new Double(num2) + "";
break;
case '-' :
result = new Double(num1) - new Double(num2) + "";
break;
case '*' :
result = new Double(num1) * new Double(num2) + "";
break;
case '/' :
result = "0".equals(num2) ? "unknown" : new Double(num1) / new Double(num2) + "";
break;
default :
result = "unknown";
}
return result;
}
}
我们来分析一下这么去实现一个计算器有什么优缺点,优点很明显,思想简单容易编写, 缺点呢,其实很多,首先,加减乘除四类操作集中在一起,耦合性很强, 如果要修改加法运算,需要改动的是整个类;其次,如果想要增加一个平方的运算,也需要去改动整个类,不易于拓展,不够灵活。
应该怎去改进呢,《大话设计模式》中活字印刷的例子就很形象,这个类就像一块完整的模具,上面刻有加减乘除四个宋体大字,利用这块模具,只能购印刷出带有加减乘除宋体大字的纸张,字体内容排序都是固定的,如果需要增加另外的文字或者是改变原有文字的字体,都需要舍弃原有的模具重新雕刻,后来我们有了活字印刷技术,将加减乘除四个字分开制作,这样要是想增加一个字,只需要制作相应的单字模具,如果想要修改原有的汉字的字体,也只需要替换掉一个原有的模具即可。
根据这种思想我们可以这样去改进:
//计算器父类
public class Operation {
public String num1;
public String num2;
public String getNum1() {
return num1;
}
public void setNum1(String num1) {
this.num1 = num1;
}
public String getNum2() {
return num2;
}
public void setNum2(String num2) {
this.num2 = num2;
}
//父类方法,需要在子类中重写
public String getResult(){
String result = "";
return result;
}
}
通过一个父类Operation去封装属性
class add extends Operation {
@Override
public String getResult(){
return new Double(num1) + new Double(num2) + ""; //加法业务逻辑
}
}
加法类
public class sub extends Operation {
@Override
public String getResult(){
return new Double(num1) - new Double(num2) + ""; //减法业务逻辑
}
}
减法类
public class mul extends Operation {
@Override
public String getResult(){
return new Double(num1) * new Double(num2) + ""; //乘法业务逻辑
}
}
乘法类
public class div extends Operation {
@Override
public String getResult(){
return new Double(num1) / new Double(num2) + ""; //除法业务逻辑
}
}
除法类
这样就可以降低各个操作类之间的耦合性,且易于修改和拓展。接下来要解决的问题是怎么根据用户输入的操作法来判断是去调用加减乘除哪个类。这里就要引入简单工厂的设计模式了。
//工厂类
public class OperationFactory {
//负责对象的生产
public static Operation getOperation(char opeType){
Operation ope;
switch (opeType){
case '+' :
ope = new add();
break;
case '-' :
ope = new sub();
break;
case '*' :
ope = new mul();
break;
case '/' :
ope = new div();
break;
default :
ope = null;
}
return ope;
}
}
通过这个工厂类,我们可以根据操作符返回相应的上转型对象。
public class Main {
public static void main(String[] args){
Operation ope;
char opeType = '+';
ope = OperationFactory.getOperation(opeType); //获取工厂类生产的对象
ope.num1 = "1";
ope.num2 = "2";
String reslt = ope.getResult();
}
}
这样设计,就可以完全把各个操作拆解开来,通过工厂类去管理对象,实现了低耦合、高灵活、高可拓展性。