(声明:本系列所用的模式都来自GOF23中,本系列并不是讲23种经典设计模式,而是如何去使用这些模式)   

 

(由于篇幅有限,部分代码请看如何使用设计模式来构造系统--(1) )

 

上一篇我们分析了员工,工资,以及绩效奖金三个类,并且使用了Bridge和Stratege两种模式,对他们之间的组合和行为进行了设计,但是我们的设计并不完善。我们知道员工的基本工资可能每年都不一样,甚至有可能随时地根据公司的制度发生变化,而设计的根本意图就是去封装变化,让我们的系统更加的长寿,不会因为变化而大量的重造,我们怎么去避免工资变化时,员工类不改变呢??

先看一下,上次设计的员工类的代码:

 

 

Code

 

这里我们看到在初始化员工工资时出现了new SttafSalary(),这就使Person与SttafSalary产生了紧耦合,也就是说SttafSalary的变化会影响Person类的稳定。那么使用何种设计模式来封装这种创建时的变化呢?

GOF23中的Factory Method(工厂方法): 定义一个用于创建对象的接口,让子类决定实例化哪一个类。Factory Method 使一个类的实例化延迟到其子类。

工厂方法的意图和我们要封装的变化意图相同,那么我们就用它来设计吧,看看类图:

 

 

 

我们使用两个同接口的工厂来封装创建时的变化,这样你在各个工厂中去添加或修改你的业务都不会影响到Person,当然原来的那种直接new的方法也不会改变,但是当你的员工类包含的工资类发生变化时(比方说现在InterShip的工资升级为正式员工的工资,而正式员工的工资重新定义),就不能应对变化了,但是将创建工作封装到Factory,就可以避免这种变化引起的Person类的修改,而只需要去添加Salary的子类,修改Factory的子类,就可以完成了。

我们来看代码。

 

工厂部分的实现:

 

Code

 

Person类的实现:

 

Code

 

OK,这样我们就完成了这种变化的封装。在实际项目中你可以把Person中创建具体那个工厂,在配置文件中存储,然后做个Switch ,就可以让他们的结合更松散了,这里就不多说了。

 

接下来我们还有一个问题,Prize绩效的制度,上一篇的设计,每一个员工的工资都会创建一个Prize,而Prize只是固定的制度,员工都是遵守和共享这个制度的,这样就造成了内存的浪费,怎么去解决这个问题呢,让系统中只存在我们想要的固定数目的Prize的实例呢?

Singleton(单件):保证一个类仅有一个实例,并提供一个访问它的全局访问点。和我们的意图一样,那就用它吧。

 

Code

 

这样我们就保证了,在系统运行时BadPrize和GoodPrize都只有一个实例,完成了我们的设计。

 

现在来看看调用程序:

 

Code

 

 

输出结果:

 

 

由于这个月干的不好,绩效工资被扣一半.....:(

 

 

我们使用了两种设计模式Factory Method和Singleton ,来封装了员工的工资创建和绩效工资的单件,好了这样我们就设计完成了用户的需求,下一篇中可恶的客户要添加需求了。。(在实际开发中这种事情的发生频率,地球上的程序员都知道啦。)

 

         下一篇: 如何使用设计模式来构造系统--(3)

 

 

posted on 2008-08-11 13:57  徐 磊  阅读(4392)  评论(18编辑  收藏  举报