不急着实现功能,先构思一下大概的功能,为了以后方便扩展和维护尽量使用好接口,继承,像我这样的新手菜鸟一般是,想到什么写什么,根本不考虑以后的扩展,一个文件写了几百行代码就感觉很有成就感,通过这个小项目,我要培养自己的架构能力,在此过程中遇到的问题我会一一记录下来和大家(新手)分享,共同学习探讨。
设计方案一:工厂方法
业务逻辑:利用简单工厂模式-->创建各个运算类的对象,各运算类继承自一个抽象基类,暴漏一个公共的接口。
先从简单开始吧。
我先在只是需要实现加减乘除四个功能,我完全可以将这四个功能单独写成各自的算法来实现,但是,如果我将来要为她添加求平方,平方根,平均数的运算时我该怎么办?如果真是这样我得对她进行“大手术”,要修改的代码量会很大,耦合度也很高,显然这样是并不合理的。那么我该选择怎样一个合理的方式呢?首先是一个 运算类,它有两个Number属性,主要用于计算器前后两个数的运算,然后有一个抽象方法getResult(),用于得到结果,然后我把加减乘除都写成了运算类的子类,继承父类后从写getResult()方法,这样的话在后期如果需要修改一个算法就需要提供其他算法代码了,但是我怎么让计算器知道我是希望用哪一个算法呢?这是我开始时遇到的问题,于是,我考虑用简单工厂模式,让工厂根据用户的需求选择合适的算法。
遇到的问题一:怎么让她易于扩展功能?
解决方案:抽象出运算基类,各功能继承该基类。
遇到的问题二:怎么让计算器知道我是希望用哪一个算法呢?
解决方案:用简单工厂模式,让工厂根据用户的需求选择合适的算法;
经过优化后(添加工厂方法):可以根据用户的需求创建运算类对象,用户只需选择运算符类型,即调用工厂方法的createOperate()方法。后面会贴出相应代码。
贴上上图代码及效果:
Operation:运算基类 该类为抽象类
public abstract class Operation { //第一个操作数 private double firstNumber = 0d; //第二个操作数 private double laseNumber = 0d; //获取结果 public abstract double getResult(); public double getFirstNumber() {//取值 return this.firstNumber; } public double getLastNumber() {//取值 return this.laseNumber; } public void setFirstNumber(double firstNumber) {//赋值 this.firstNumber = firstNumber; } public void setLastNumber(double lastNumber) {//赋值 this.laseNumber = lastNumber; } }
OperationAdd:继承自Operation的加法运算类
public class OperationAdd extends Operation { public double getResult() { return getFirstNumber() + getLastNumber(); // TODO Auto-generated method stub } }
OperationMinus:继承自Operation的减法运算类
public class OperationMinus extends Operation{ public double getResult() { // TODO Auto-generated method stub return getFirstNumber()-getLastNumber(); } }
OperationMutiply:继承自Operation的乘法运算类
public class OperationMutiply extends Operation{ public double getResult() { // TODO Auto-generated method stub return getFirstNumber()*getLastNumber(); } }
OperationDevide:继承自Operation的除法运算类
public class OperationDevide extends Operation{ public double getResult() { // TODO Auto-generated method stub if(getLastNumber()!=0){ return getFirstNumber()/getLastNumber(); } return 0.0; } }
OperationFactory:创建运算类对象的工厂类
public class OperationFactory { private static Operation operation = null; public static Operation createOperate(String operate) { switch (operate) { case "+": operation = new OperationAdd(); break; case "-": operation = new OperationMinus(); break; case "*": operation = new OperationMutiply(); break; case "/": operation = new OperationDevide(); break; default: break; } return operation; } }
Test:
public class Test { public static void main(String[] args) { Operation operation = new OperationFactory().createOperate("*"); operation.setFirstNumber(5); operation.setLastNumber(6); double result = operation.getResult(); System.out.println("result = " + result); } }
结果:
先不考虑健壮性,单单从可扩展方面来说,以上就是我的初步想法之一。希望大家可以指出不足,共同探讨。
我会在今后的更新中继续优化,选择更合适的方法。
转载请注明出处:http://my.oschina.net/u/2479171/blog/514499 尊重作者劳动果实