同样以计算器程序为参考对象,上一篇文章中通过业务的封装将业务逻辑和界面逻辑分开
从而降低了他们的耦合度,使得扩展性和维护性提高.但是仅仅这样还不够.因为,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、抽象类的继承类:
完成相应的逻辑功能
简单工厂模式通过工厂类不必管对象如何创建和组织,有利于软件结构的优化。
但是,工厂类中集中了所有实例的创建逻辑,违反了高内聚(类之间关系简单)责任分配原则;他所能创建的类必须
是事先就可以考虑到的,如果添加新类,则必须修改工厂类了。如若产品类不断增加,对系统的维护和扩展十分不利的!因
次该模式使用较少。
?思考:那如何解决简单工厂模式所面临的问题呢?
工厂方法模式!