同样以计算器程序为参考对象,上一篇文章中通过业务的封装将业务逻辑和界面逻辑分开
从而降低了他们的耦合度,使得扩展性和维护性提高.但是仅仅这样还不够.因为,Operation类中,加
法、减法、乘法、除法的运算是在一起的,如若需要加入一种新的运算方式(开根)就势必去修
原有的代码,不加注意就会造成问题.
因此,加减乘除运算有必要分离出来,降低各类运算之间的耦合度,这就要使用继承的方式
来实现。首先需要一个运算的基类,之后再继承该基类(并且重写方法)
Operation类
package com.kiritor; /** * 运算基类*/ public class Operation { private double num1 = 0.0; private double num2 = 0.0; public double getNum1() { return num1; } public void setNum1(double num1) { this.num1 = num1; } public double getNum2() { return num2; } public void setNum2(double num2) { this.num2 = num2; } public double getResult(double numA ,double numB) throws Throwable { double result =0.0; return result; } }
OperationAdd类
package com.kiritor; /** * 加法运算*/ public class OperationAdd extends Operation{ @Override public double getResult(double numA, double numB) { double result = 0.0; result = numA+numB; return result; } }
OperationSub类
package com.kiritor; /** * 减法类*/ public class OperationSub extends Operation{ @Override public double getResult(double numA, double numB) { double result = 0.0; result = numA-numB; return result; } }
OperationMul类
package com.kiritor; /** * 乘法类*/ public class OperationMul extends Operation{ @Override public double getResult(double numA, double numB) { double result = 0.0; result = numA * numB; return result; } }
OperationDiv类
package com.kiritor; /** * 除法类*/ public class OperationDiv extends Operation{ @Override public double getResult(double numA, double numB) throws Throwable { double result = 0.0; if(numB==0) throw new Exception("除数不能为零!"); result = numA / numB ; return result ; } }
这里通过继承与方法的重写使得各方法分开了,因此在修改某个方法的代码的
时候就不会接触到其他方法的代码。而且若有新的运算方式的时候,直接继承在重
写,减少了出错的可能,程序逻辑结构更加的清晰!
不过问题也来了,实际运用中我们如何知道应该调用何种方法呢?也就是如何
实例化对象的问题
可以使用“简单工厂模式”予以实现,用一个单独的类来创造实例的过程,也就是
工厂
OperationFactory类:package com.kiritor; /** * 生产运算类的工厂*/ public class OperationFactory { public static Operation bulidOperation(String opr) { Operation operation = null; switch (opr) { case "+": operation = new OperationAdd(); break; case "-": operation = new OperationSub(); break; case "*": operation = new OperationMul(); break; case "/": operation = new OperationDiv(); break; } return operation; } }
主类:
Operation operation =null; operation = OperationFactory.bulidOperation("+"); try { System.out.println(operation.getResult(1.2, 2.1)); } catch (Throwable e) { // TODO Auto-generated catch block e.printStackTrace(); }
经过上述的变换,若果需要添加一个开根运算,
只需要实现一个运算子类,之后再修改工厂
就可以了
大大降低了程序的耦合度!
类图结构为:
从设计模式的类型上来说,简单工厂模式属于创建型模型(关于设计模式的具体分类在下一篇博文中会归纳),
也称其为静态工厂方法模式,但是不属于23中GOF设计模式之一,简单工厂模式采用工厂对象决定创建类的实例。实质上
就是有一个工厂类根据传入的参数,动态决定应该创建类(该类必须继承父类或者接口)的实例。
简单工厂模式包含的角色;
1、工厂类:
该模式的核心,实现创建所有实例,该类可以直接被外界调用,创建对象。
2、抽象类:
工厂所能创建的所有对象的父类,是所有实例的公共接口
3、抽象类的继承类:
完成相应的逻辑功能
简单工厂模式通过工厂类不必管对象如何创建和组织,有利于软件结构的优化。
但是,工厂类中集中了所有实例的创建逻辑,违反了高内聚(类之间关系简单)责任分配原则;他所能创建的类必须
是事先就可以考虑到的,如果添加新类,则必须修改工厂类了。如若产品类不断增加,对系统的维护和扩展十分不利的!因
次该模式使用较少。
?思考:那如何解决简单工厂模式所面临的问题呢?
工厂方法模式!
转载于:https://blog.51cto.com/kiritor/1226706