本章要点如下:
题目:用任意一种面向对象语言实现一个计算器控制台程序。要求输入两个数和运算符号,
得到结果。
程序应该做到:(1)可维护;(2)可复用;(3)可扩展;(4)灵活性好。
可维护:就是说代码一处更改,不能产生连锁反应,不能影响其他地方。
可复用:尽量减少重复性代码。
可扩展:如果要扩展新的功能、新的业务,则只需要增加新的类就好了,不对已有的类和逻辑产生影响。插拔式的应用。
面向对象要点:
面向对象三大特性:封装、继承、多态。
通过封装、继承、多态把程序耦合降低。
业务逻辑和界面逻辑分开。
简单工厂模式实现过程如下:
1. 首先,搞清楚业务中容易发生变化的部分。在本应用中,要求计算两个数的运算结果,那么要进行什么样的运算,这就是一个容易发生变化的部分。例如,我们现在只想实现加减乘除运算,后期又想增加开根或者求余运算。那么如何应对这种需求带来的变化。在程序设计的时候就应该考虑到程序的可维护性、可扩展性、代码的可复用性、灵活性等等。
2. 例如现在这个运算器只有加减乘除四种运算。首先建一个Operation类,这个类是各种具体运算类(加减乘除)的父类,主要是接受用户输入的数值。该类如下:
public class Operation { private double a = 0; private double b = 0; public double getA(){ return this.a; } public double getB(){ return this.b; } public void setA(double a){ this.a = a; } public void setB(double b){ this.b = b; } public double getResult(){ double result = 0; return result; } }
3. 然后是具体的运算类:Add、Sub、Mul、Div。他们都继承了Operation类,并且重写了getResult()方法。这样就可以用多态性降低不同业务逻辑的耦合度,修改任何一种运算类都不会影响其他的运算类。具体类的代码如下:
public class Add extends Operation{ @Override public double getResult(){ double result = 0; result = super.getA() + super.getB(); return result; } } public class Sub extends Operation{ @Override public double getResult(){ double result = 0; result = super.getA() - super.getB(); return result; } } public class Mul extends Operation{ @Override public double getResult(){ double result = 0; result = super.getA() * super.getB(); return result; } } public class Div extends Operation{ @Override public double getResult(){ double result = 0; if(super.getB() == 0) try { throw new Exception("除数不能为0!"); } catch (Exception e) { e.printStackTrace(); } result = super.getA() / super.getB(); return result; } }
4. 那么如何让计算器知道我是要用哪一种运算呢?也就是说到底要实例化哪一个具体的运算类,Add?Sub?Mul?Div?这时就应该考虑用 一个单独的类来做这个创造具体实例的过程,这个类就是工厂类。如下:
public class OperationFactory { public Operation createOperation(String operate){ Operation oper = null; operate = operate.trim(); if("".equals(operate) || operate == null) try { throw new Exception("您还没有输入操作符!"); } catch (Exception e) { e.printStackTrace(); } if(operate.equals("+")) oper = new Add(); if(operate.equals("-")) oper = new Sub(); if(operate.equals("*")) oper = new Mul(); if(operate.equals("/")) oper = new Div(); return oper; } }
5. 这样,用户只要输入运算符,工厂类就可以创建合适的实例,通过多态性,即返回给父类的方式实现运算结果。客户端代码如下:
public class Client { public static void main(String[] args){ try{ double a,b; String operate; System.out.println("请输入数字A:"); BufferedReader buf=new BufferedReader(new InputStreamReader(System.in)); a = Double.valueOf(buf.readLine()).doubleValue(); System.out.println("请输入运算符号(+-*/):"); operate = buf.readLine().trim(); System.out.println("请输入数字B:"); b = Double.valueOf(buf.readLine()).doubleValue(); Operation o = new OperationFactory().createOperation(operate); o.setA(a); o.setB(b); System.out.println(o.getResult()); }catch(Exception e){ e.printStackTrace(); } } }
该应用的UML图(from:《大话设计模式》)如下: