好久没有写东西,最近由于休息在家,准备抽点时间写点东西,写点什么呢?犹豫再三,决定把设计模式重新琢磨下,也算自己琢磨过程的一个记录和总结吧。准备每天写一点,一一把23种设计模式进行梳理,由于本人能力有限,难免有不妥之处,望各位积极指正。废话少说,开始步入正题,首先从工厂模式开始。
个人认识:
工厂模式:见名之意,工厂是干什么的?当然制造产品的了,以供需要的人使用。现在社会分工越来越细了,工厂生产产品,需要的人们使用产品,没有人会自己生产所有的产品来使用。在我们软件领域里来说就是创建“对象”了,提到创建对象,我们马上会想到“new 类()”,软件设计里有一个“职责单一”的原则,建议创建和使用分类,职责分明,所以我们创建对象和使用应分开进行了。。
需求:某零售公司,下设多个代理商代理公司产品,而下属代理商财务是独立核算,自负盈亏,总公司为了更好的监管下属各个代理商,要求每月向其提交财务流水报告,总部根据其财务情况,来确定代理商的级别。但下属各个代理商的工资核算规则都不一样,现设计一套薪资系统,我们该如何设计呢?
我们的做法是将“工资核算规则”独立抽取出来,作为“全局规则”组件来设计。代码如下:
1.薪资计算接口
package com.baihao.sampleFactory;
public interface Salary {
public void computerSalary();
}
2.具体代理商1
package com.baihao.sampleFactory;
public class ShanXiSalary implements Salary {
private int level = 0;//代理级别
public int getLevel() {
return level;
}
public void setLevel(int level) {
this.level = level;
}
@Override
public void computerSalary() {
System.out.println("陕西工资计算");
}
}
3.具体代理商2
package com.baihao.sampleFactory;
public class HeBeiSalary implements Salary {
private int level = 0;//代理级别
public int getLevel() {
return level;
}
public void setLevel(int level) {
this.level = level;
}
@Override
public void computerSalary() {
System.out.println("河北工资计算");
}
}
4.工厂类
package com.baihao.sampleFactory;
public class SimpleFactory {
public static Salary getSalary(String name){
if(name.equals("HeBei")){
return new HeBeiSalary();
}else if(name.equals("ShanXi")){
return new ShanXiSalary();
}
return null;
}
}
5.高端调用模块:
package com.baihao.sampleFactory;
public class Client {
/**
* @param args
*/
public static void main(String[] args) {
Salary salary = SimpleFactory.getSalary("HeBei");
salary.computerSalary();
System.out.println("----------------------------------");
salary = SimpleFactory.getSalary("ShanXi");
salary.computerSalary();
}
}
这样在调用模块并不负责对象的创建,只是调去使用而已,具体的对象创建有工厂类来实现,这样类职责更明确,结构更清晰。此模式为“简单工厂”也称之为“静态工厂”。
大家有没有发现才方案是存在一定的问题的?假如随着公司的扩展,代理商越来越多,有没有发现这样的设计,工厂类会迅速扩张,越来越臃肿,而且后期的维护也更加困难,代理商的增加,需要对工厂类进行修改,这样也违背了“迪米特原则”于是乎,我们对工厂进行改造:
改造后的工厂(利用java的放射机制):
package com.baihao.sampleFactory;
public static Salary getSalary1(String className) throws ClassNotFoundException, InstantiationException, IllegalAccessException{
Class c = Class.forName(className);
Salary salary = (Salary)c.newInstance();
return salary;
}
}
我们这样改造之后,没有在出现IF ELSE这样的判断,假如增加了一个代理商,我们只需要增加一个代理商类即可,原来的代码无需任何改动。扩展性是不是比以前好点呢?
朋友们这样改造依然存在问题,大家想:假如总部要求,根据代理商的财务流水情况,相应的赋予其级别,而代理商为了更好刺激其员工工作,工资直接更代理级别挂钩,一级代理工资全发,二级代理发工资的90%,三级代理发工资的80%。。。。。且各个代理商的比例有其自定。这样的话,就是在计算工资的时候,需要得到其当前的代理级别才可以。这样的话我们现在的方案可以满足吗?有!我们每创建一个对象后,直接向其对应的级别付值给它,大家想想,如果这样的话,工厂类同样会迅速膨胀,有没有更好的办法呢?我们用工厂方法试试。。
下次“工厂方法模式”继续改造。。