前面两篇中,完成了客户所提的"我们的系统要管理人员的工资.(为了模拟真实的开发场景,这里暂时先定义一个功能)人员分为实习员工和正式员工,他们的基本工资是不同的,工资包括基本工资和绩效工资."这样的一个系统需求.我们设计并完成了他,今天客户由于公司要给员工福利,而来追加需求"按照不同的职位,给与不同的福利,一个人可能身兼几个职位".
(声明:本系列所用的模式都来自GOF23中,本系列并不是讲23种经典设计模式,而是如何去使用这些模式)
(由于篇幅有限,部分代码请看 如何使用设计模式来构造系统--(1) )
前面两篇中,完成了客户所提的"我们的系统要管理人员的工资.(为了模拟真实的开发场景,这里暂时先定义一个功能)人员分为实习员工和正式员工,他们的基本工资是不同的,工资包括基本工资和绩效工资."这样的一个系统需求.我们设计并完成了他,今天客户由于公司要给员工福利,而来追加需求"按照不同的职位,给与不同的福利,一个人可能身兼几个职位".OK,明确了需求,我们还是按照第一篇的方式来完成它.
1.分析
我们用"名词分析法"来分析需求里面的类(第一篇有讲解),这里出现了职位和福利. 那么我们就得到两个类Duty(职位)和Welfare(福利).
2.过滤
好,我们通过分析得到了Person(人员),Duty(职位)和Welfare(福利),这里的福利我们就简化他只是个数字(如果很复杂,可以把它单独做一个类,然后用我们第一篇提到的Bridge模式去把职位和福利联系起来),Person类我们已经有了,这样最终我们要添加一个包含Welfare的Duty类.
3.设计
我们来看客户的话:"按照人们不同的职位,给与不同的福利,一个人可能身兼几个职位",也就是说我们的Person可能要维护一个职位的列表,然后把它们的福利加起来最后生成员工的最终福利.这样设计是可以完成用户的需求,可是当职位发生变的时候,或者职位需要去添加一些比如权限之类的操作,这样就不是简单的叠加问题了,而且当用户说我们公司现在不要福利了,那么我们的Person类就要修改(当然我们也不能去派生Person的子类,因为职位何其多,这样做子类的数目是不可想象的).我们的目的就是让系统更长寿,避免修改,所以我们要采取其他的方式来设计.总结一下我们的设计意图:要不修改原有类,给这个类去添加一些方法,而且可以无限的去添加.并且不能通过派生子类来实现人员的职位.什么模式与之匹配呢??
GOF23中的Decorator(装饰):在不影响其他对象的情况下,以动态、透明的方式给单个对象添加职责.
4.类图
Duty这个类层次是新加的,AbstractPerson和他的两个子类Staff和InterShip是第一篇中设计完成的.
在这里Person,没有任何改动.相关代码请察看第一篇.
我们来看看Duty的类层次的代码:
Code
public abstract class Duty : AbstractPerson //Is-a 的关系
{
protected AbstractPerson _person; //Has-a的关系
protected string _dutyName;
public Duty(AbstractPerson person) //将客户代码传来的Person,重新装饰,成为新的Person
{
this._person=person;
this._personName = person.PersonName;
this._personSalary = person.PersonSalary;
}
public string DutyName
{
get{return _dutyName;}
set{_dutyName=value;}
}
public abstract double GetWelfare();//GetWelfare方法为抽象方法,留给子类实现
}
public class BaseDuty : Duty //员工基本福利
{
public BaseDuty(AbstractPerson person)
: base(person)
{
}
public override double GetWelfare()
{
Duty duty = _person as Duty;
if (!Equals(duty, null)) //如果Person是已经被装饰过的,则将原有的福利进行装饰
{
return 200 + duty.GetWelfare();
}
return 200;//午餐费
}
public override double GetShouldpaid(IPrize prize)
{
return _person.GetShouldpaid(prize);
}
}
public class TeamLeader:Duty //组长的福利
{
public TeamLeader(AbstractPerson person)
: base(person)
{
}
public override double GetWelfare()
{
Duty duty = _person as Duty;
if (!Equals(duty, null))
{
return 500 + duty.GetWelfare();
}
return 500;//话补
}
public override double GetShouldpaid(IPrize prize)
{
return _person.GetShouldpaid(prize);
}
}
public class DepartmentManager:Duty //部门经理的福利
{
public DepartmentManager(AbstractPerson person)
: base(person)
{
}
public override double GetWelfare()
{
Duty duty = _person as Duty;
if (!Equals(duty, null))
{
return 1000 + duty.GetWelfare();
}
return 1000;//车补
}
public override double GetShouldpaid(IPrize prize)
{
return _person.GetShouldpaid(prize);
}
}
Duty继承了Person,那么就是说在装饰一个Person后他还是一个Person,这很合理,而且可以无限添加。
调用程序:
Code
class Program
{
static void Main(string[] args)
{
Staff staff = new Staff();
staff.PersonName="涵舍愚人";
BaseDuty bd = new BaseDuty(staff);
TeamLeader tl = new TeamLeader(bd);
DepartmentManager dm = new DepartmentManager(tl);
Console.Write(dm.PersonName+"本月赢得工资="+dm.GetShouldpaid(BadPrize.badPrize)+" 应发福利="+ dm.GetWelfare());
Console.Read();
}
}
输出结果:
这样我们就完成了不修改Person,而给人员添加了职位,这个职位可以无限的加,你可以自己成立一个公司,公司就你一个人,去担当所有的职位。。呵呵
下一篇 :如何使用设计模式来构造系统--(4)