图1
图2
我们在面象对象设计中,要遵循依赖倒置原则,也就是说,抽象不依赖于实现细节,而实现细节要依赖于抽象 , 下面两副图中,图1是抽象A依赖实现B,这在某中情况下就是一个不好的做法,比如,我们有这样一个需求,有一个人事系统,我们做一个用来计算工资的类,然后我们把员工对象当参数传入,来计算他的工资。
如果按图1的做法,代码很容易就写成了这样..
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Text;
- namespace 设计模式
- {
- class CountMoney
- {
- public static void Main()
- {
- Employee emp = new Employee() ;
- Manager man = new Manager() ;
- Console.WriteLine( "普通员工的工资:{0}" , CountSalary( PersonType.EmployeeType , emp ) ) ;
- Console.WriteLine( "管理人员工的工资:{0}" , CountSalary( PersonType.ManagerType , man ) ) ;
- Console.ReadLine() ;
- }
- public static float CountSalary( PersonType type , Object per )
- {
- float reFloat = 0.0f ;
- if( PersonType.EmployeeType == type )
- {
- Employee emp = (Employee) per ;
- reFloat = emp.daySalary * emp.workDayCount ;
- }
- else if ( PersonType.ManagerType == type )
- {
- Manager emp = (Manager) per ;
- //管理人员一天的工资是200块
- reFloat = emp.daySalary * emp.workDayCount ;
- }
- return reFloat ;
- }
- }
- public enum PersonType
- {
- EmployeeType = 0 ,
- ManagerType = 1
- }
- class Employee
- {
- public float workDayCount = 30 ;
- public float daySalary = 200 ;
- }
- class Manager
- {
- public float workDayCount = 28 ;
- public float daySalary = 300 ;
- }
- }
通过以上代码,我们可以看出CountMoney工资计算类中,我传用枚举来判断传入的类型,进行相应的转型,并计算出工次。。这样写本身也并没有什么错,但是它不是一个应对变化的好办法,比如说,除普通员工,管理人员外,我们又要加入别的类型的人员,这时,我们的代码,就不太好扩展,解决办法一定是,在public static float CountSalary( PersonType type , Object per )方法在再多加一条else if来做判断,枚举中再加入一个类型。。这样的改动未免有些太大了。。这里其实就是图1所说的,依赖实现细节,也就是说CountMoney中直接操作了具体的实现类造成了耦合性,所以,我们要依赖倒置。。下面我们按图2的方式来写代码。
首先,我们为了解决依赖实现类的问题,我们要加一层抽像,用来描述各类人员的共性,也就是不变处,试想一下,要计算工资,是不是不管什么人员,都需要有出勤天数,这样就行了,至于别的内容,我们是不关心的,所以我们定义一个接口,Person,用来描述出勤天数,其余的不管是员工,还是管理员,都去实现这个接口。而我们的计算类中,中对接口操作,不依赖具体的实现类,比如员工类。
按图2实现之后,我们如果再加入一种类型的人员,只需要加一个类,实现Person接口就行,不需要再改动CountMoney中的代码,这就符合了开闭原则。
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Text;
- namespace 设计模式
- {
- class CountMoney2
- {
- public static void Main()
- {
- Employee emp = new Employee() ;
- Manager man = new Manager() ;
- Console.WriteLine( "普通员工的工资:{0}" , CountSalary( emp ) ) ;
- Console.WriteLine( "管理人员工的工资:{0}" , CountSalary( man ) ) ;
- Console.ReadLine() ;
- }
- public static float CountSalary( Person per )
- {
- float reFloat = 0.0f ;
- reFloat = per.DaySalary * per.WorkDayCount ;
-
- return reFloat ;
- }
- }
- interface Person
- {
- float WorkDayCount{ get;}
- float DaySalary { get;}
- }
- class Employee : Person
- {
- public float workDayCount = 30 ;
- #region Person 成员
- public float WorkDayCount
- {
- get { return this.workDayCount ; }
- }
- #endregion
- #region Person 成员
- public float DaySalary
- {
- get { return 200.0f ; }
- }
- #endregion
- }
- class Manager : Person
- {
- public float workDayCount = 28 ;
- #region Person 成员
- public float WorkDayCount
- {
- get { return this.workDayCount ; }
- }
- #endregion
- #region Person 成员
- public float DaySalary
- {
- get { return 300.0f ; }
- }
- #endregion
- }
- }
未完。。。
|