记得去年看了一遍大话设计模式,很有感触,现在再看第二遍,又收获良多,这里记录一下自己的理解。
注:语言为java
一、简单工程模式
根据套路来,假如面试官让你设计一个计算器,你会怎么写代码,能加减乘除即可,自己写一套再往下看吧。
新嫩一般就是直接开干,这点我也是,也很喜欢能立马动手这种精神,但结果往往不太理想。
于是代码结果可能就是在一个类里,一个main方法解决问题。
然后仔细想想?哦,耦合太高了,得解耦,至少调用类和运算类要分开,于是第二次结果就是这两个类。
接着再想想?调用方如果希望增加新的运算方法,怎么扩展,直接在运算类里添加?no,no,这可不安全,修改代码的家伙也许一时手贱修改了源码呢!
所以,每个运算功能都分开吧,改为加法类,减法类,乘法类,除法类,然后都去继承运算类,新添什么运算只要继承父类即可。
嗯,似乎完美了,现在还需要解决的就是调用问题,必须只给出获得结果的方法,不能让人直接调用具体的运算方法(不然就暴露了,也显得麻烦了),所以前辈想出了简单工厂模式!
调用类如下:
package com.gcc.factoryModel;
/**
* 简单工厂模式:解决对象创建问题,根据某个条件实例化所需的对象
*
*/
public class TestOperation {
public static void main(String[] args) {
Operation operadd = OperationFactory.createOperation('+');
Double result1 = operadd.getResult(4.0,5.0);
System.out.println("Operation加法结果为:"+result1);
Operation opersub = OperationFactory.createOperation('-');
Double result2 = opersub.getResult(4.0,5.0);
System.out.println("Operation减法结果为:"+result2);
Operation opermul = OperationFactory.createOperation('*');
Double result3 = opermul.getResult(4.0,5.0);
System.out.println("Operation乘法结果为:"+result3);
Operation operdivi = OperationFactory.createOperation('/');
Double result4 = operdivi.getResult(4.0,5.0);
System.out.println("Operation除法结果为:"+result4);
}
}
工厂类如下:
package com.gcc.factoryModel;
public class OperationFactory {
public static Operation createOperation(char operation) {
Operation oper = null;
switch (operation) {
case '+':
oper=new OperationAdd();
break;
case '-':
oper=new OperationSub();
break;
case '*':
oper=new OperationMul();
break;
case '/':
oper=new OperationDivi();
break;
default:
break;
}
return oper;
}
}
运算类以及子类如下:
package com.gcc.factoryModel;
public abstract class Operation {
public abstract Double getResult(Double numberA,Double numberB);
}
package com.gcc.factoryModel;
public class OperationAdd extends Operation {
@Override
public Double getResult(Double numberA,Double numberB) {
Double result=numberA+numberB;
return result;
}
}
package com.gcc.factoryModel;
public class OperationSub extends Operation {
@Override
public Double getResult(Double numberA,Double numberB) {
Double result=numberA-numberB;
return result;
}
}
package com.gcc.factoryModel;
public class OperationMul extends Operation {
@Override
public Double getResult(Double numberA,Double numberB) {
Double result=numberA*numberB;
return result;
}
}
package com.gcc.factoryModel;
public class OperationDivi extends Operation {
@Override
public Double getResult(Double numberA,Double numberB) {
Double result=null;
if(numberB!=0.0){
result=numberA/numberB;
}
return result;
}
}
简单工厂的巧妙就在于,在调用方是完全不用关心底层是怎么实现的,只要关心我需要哪个功能的对象,再使用这个对象的方法即可,回顾想想,是不是在开发中也会经常遇到人家写好的工厂类。
这里再补充一下java基础,运算类的运算方法设计为抽象方法,这样继承这个类的子类就必须实现这个方法,当然也可以改为运算接口。
工厂生成对象方法为静态方法,这样调用时候就可以直接类名.方法名
下面附上原书的UML图:
另外附上UML图的常见内容以及解释:
矩形框:表示类,类图分三层,+号表示public,-号表示private,#号表示protected
矩形框带interface的,表示接口图;另一种表现方式就是加棒棒糖,如上图唐老鸭接口
空心三角形加实线表示继承关系
空心三角形加虚线表示实现接口
箭头加实现表示关联关系,即一个类知道(实例化或调用方法)另一个类
空心的菱形加实线箭头表示聚合关系,聚合的意思是整体和部分的关系,是可以分割的,如上图大雁和雁群,大雁可以属于雁群A也可以属于雁群B,这是大雁个体的自由,大雁和雁群的生命周期也不同
实心的菱形加实线箭头表示组合关系,组合的意思是强的整体和部分的关系,不可分割,如上图的鸟和翅膀;再解释两端的数字,叫做基数,表面一段的类可以有几个实例。
虚线箭头表示依赖关系,依赖表示类内某个方法(功能),必须要使用其他的对象(类),如上图动物的新陈代谢方法必须要氧气和水