emmm......之所以写这个系列,是因为想去进阶,感觉写自己代码不够精简,亢沉臃肿;想写好写优雅写优秀,却不知道是不是优秀,模棱两可的感觉;想去入手源码,却不知道从拿下手,又或者说看不懂,为什么这么写。
所以想入手设计模式系列,当然这些理解或者示例代码是建立在《大话设计模式》——程杰著的基础之上的。感觉这本书还是值得推荐的_
仅属个人理解,如果有误,欢迎各位指正^_^
在未接触到设计模式之前,你的代码或许是这样的:
/**(模拟一个计算器的功能)*/
public class General {
public static void main(String[] args) {
//普通代码
try {
Scanner sc = new Scanner(System.in);
System.out.println("输入数字A:");double strNumberA = sc.nextInt();
System.out.println("输入数字B:");double strNumberB = sc.nextInt();
System.out.println("输入运算符:");String opera = sc.next();
String result = "";
result = getResult(strNumberA, opera, strNumberB, result);
if(Optional.ofNullable(result).isPresent()){//判断是否返回空,false为空
System.out.println("您输出的结果为:"+result);
}else{
System.out.println("请输入正确的运算符");
}
}catch (Exception ex){
System.out.println("您的输入有误"+ex.getMessage());
}
}
public static String getResult(double strNumberA, String opera, double strNumberB, String result) {
switch (opera){
case "+":
result = String.valueOf(strNumberA + strNumberB);
break;
case "-":
result = String.valueOf(strNumberA - strNumberB);
break;
case "*":
result = String.valueOf(strNumberA * strNumberB);
break;
case "/":
result = String.valueOf(strNumberA / strNumberB);
break;
default:
result = null;
break;
}
return result;
}
}
其实,乍一看这段代码也没什么问题,并且也运用到了面向对象三大特征——封装,而且也捕获了异常,按道理也挺完善了,但是,如果让你同时用到面向对象的三大特征呢?又或者说这个代码能否做到灵活的修改和扩展呢?
引入简单工厂模式(工厂模式细分为:简单工厂,工厂模式,抽象工厂)划重点
从以上代码你也可以看出,耦合性很高,每次拓展一个功能(比如我在增加个幂运算),都要在switch加一个分支,从而导致加减乘除运算都得重新编译,而且是在原写好的类上修改,极不利于维护和拓展。
而此时,如果你用到了简单工厂模式,就可以巧妙的避开这些。
优点:
- 解耦:调用方不用负责对象的创建,只需要使用,明确各自的职责;
- 维护方便:后期如果创建对象时需要修改代码,也只需要去工厂方法中修改,易拓展;
运用简单工厂模式改造的思路如下:
- 定义元数据类(抽象类,不需要实例,需要子类重写),运用到了封装;
- 具体实体类(加减乘除类)运用到了继承;
- 简单工厂类(选择传来的是加减乘除哪一个算法)运用到了多态。
具体代码实现:
- 定义元数据类:
public abstract class MetaData {
private double numberA;
private double numberB;
//具体方法,需要子类去重写
public abstract String getResult(double numberA,double numberB);
get/set方法...
}
- 定义具体实现类:
//加法 public class MetaDataAdd extends MetaData{ public String getResult(double numberA,double numberB){ String result = String.valueOf(numberA + numberB); return result; } }
//减法 public class MetaDataReduce extends MetaData{ public String getResult(double numberA,double numberB){ String result = String.valueOf(numberA - numberB); return result; } }
//乘法 public class MetaDataMul extends MetaData{ public String getResult(double numberA,double numberB){ String result = String.valueOf(numberA * numberB); return result; } }
//除法 public class MetaDataDivision extends MetaData{ public String getResult(double numberA,double numberB){ String result = String.valueOf(numberA / numberB); return result; } }
- 简单工厂类
public class MetaDataFactory { public static MetaData getAlgorithm(String operator){ MetaData metaData = null; switch (operator){ case "+": metaData = new MetaDataAdd(); //多态的实现 break; case "-": metaData = new MetaDataReduce();//多态的实现 break; case "*": metaData = new MetaDataMul();//多态的实现 break; case "/": metaData = new MetaDataDivision();//多态的实现 break; default: metaData = null; break; } return metaData; } }
总结
这样下来,如果你增加一个幂运算,直接在工厂类里面添加一个switch分支,在创建一个幂算法。而这样对于日后的维护和扩展会更加友好。