从一个示例谈起
示例场景:
我们需要设计一个人事管理系统,其中的一个功能是对各种不同类型的员工,计算其当月的工资——不同类型的员工,拥有不同的薪金计算制度。
结构化做法
1.获得人事系统中所有可能的员工类型
2.根据不同的员工类型所对应的不同的薪金制度,计算其工资
enumEmployeeType
{
Engineer;
Sales;
Manager;
…
}
// 计算工资程序
if ( type == EmployeeType.Engineer)
{
……
}
else if (type == Employeetype.Sales)
{
……
}
面向对象设计
1.根据不同的员工类型设计不同的类,并使这些类继承自一个Employee抽象类,其中有一个抽象方法GetSalary。
2.在各个不同的员工类中,根据自己的薪金制度,重写(override)GetSalary方法。
abstract class Employee
{
…
public abstract int GetSalary();
}
class Engineer: Employee
{
…
public override int GetSalary()
{
…
}
}
class Sales: Employee
{
…
public override int GetSalary()
{
…
}
}
// 显示工资程序
Employee e = emFactory.GetEmployee(id);
MessageBox.Show( e.GetSalary());
示例场景:
现在需求改变了……随着客户公司业务规模的拓展,又出现了更多类型的员工,比如钟点工、计件工……等等,这对人事管理系统提出了挑战——原有的程序必须改变。
结构化做法
几乎所有涉及到员工类型的地方(当然包括“计算工资程序”)都需要做改变……这些代码都需要重新编译,重新部署…….
面向对象做法
只需要在新的文件里增添新的员工类,让其继承自Employee抽象类,并重写GetSalary()方法,然后在 EmployeeFactory.GetEmployee方法中根据相关条件,产生新的员工类型就可以了。其他地方(显示工资程序、Engineer类、 Sales类等)则不需要做任何改变。