分享

C#实现桥接模式

 goodwangLib 2014-05-03

图1

 

 

 

图2

 

 

我们在面象对象设计中,要遵循依赖倒置原则,也就是说,抽象不依赖于实现细节,而实现细节要依赖于抽象 , 下面两副图中,图1是抽象A依赖实现B,这在某中情况下就是一个不好的做法,比如,我们有这样一个需求,有一个人事系统,我们做一个用来计算工资的类,然后我们把员工对象当参数传入,来计算他的工资。

如果按图1的做法,代码很容易就写成了这样..

 

  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;

  5. namespace 设计模式
  6. {
  7.     class CountMoney
  8.     {
  9.         public static void Main()
  10.         {
  11.             Employee emp = new Employee() ;
  12.             Manager man = new Manager() ;

  13.             Console.WriteLine( "普通员工的工资:{0}" , CountSalary( PersonType.EmployeeType , emp ) ) ;
  14.             Console.WriteLine( "管理人员工的工资:{0}" , CountSalary( PersonType.ManagerType , man ) ) ;

  15.             Console.ReadLine() ;
  16.         }

  17.         public static float CountSalary( PersonType type , Object per )
  18.         {
  19.             float reFloat = 0.0f ;

  20.             if( PersonType.EmployeeType == type )
  21.             {
  22.                 Employee emp = (Employee) per ;
  23.                 reFloat = emp.daySalary * emp.workDayCount ;
  24.             }
  25.             else if ( PersonType.ManagerType == type )
  26.             {
  27.                 Manager emp = (Manager) per ;
  28.                 //管理人员一天的工资是200块
  29.                 reFloat = emp.daySalary * emp.workDayCount ; 
  30.             }

  31.             return reFloat ;
  32.         }
  33.     }

  34.     public enum PersonType
  35.     {
  36.         EmployeeType = 0 ,
  37.         ManagerType = 1 
  38.     }

  39.     class Employee
  40.     {
  41.         public float workDayCount = 30 ;   
  42.         public float daySalary = 200 ;
  43.     }

  44.     class Manager
  45.     {
  46.         public float workDayCount = 28 ;
  47.         public float daySalary = 300 ;
  48.     }
  49. }

通过以上代码,我们可以看出CountMoney工资计算类中,我传用枚举来判断传入的类型,进行相应的转型,并计算出工次。。这样写本身也并没有什么错,但是它不是一个应对变化的好办法,比如说,除普通员工,管理人员外,我们又要加入别的类型的人员,这时,我们的代码,就不太好扩展,解决办法一定是,在public static float CountSalary( PersonType type , Object per )方法在再多加一条else if来做判断,枚举中再加入一个类型。。这样的改动未免有些太大了。。这里其实就是图1所说的,依赖实现细节,也就是说CountMoney中直接操作了具体的实现类造成了耦合性,所以,我们要依赖倒置。。下面我们按图2的方式来写代码。

 

首先,我们为了解决依赖实现类的问题,我们要加一层抽像,用来描述各类人员的共性,也就是不变处,试想一下,要计算工资,是不是不管什么人员,都需要有出勤天数,这样就行了,至于别的内容,我们是不关心的,所以我们定义一个接口,Person,用来描述出勤天数,其余的不管是员工,还是管理员,都去实现这个接口。而我们的计算类中,中对接口操作,不依赖具体的实现类,比如员工类。

按图2实现之后,我们如果再加入一种类型的人员,只需要加一个类,实现Person接口就行,不需要再改动CountMoney中的代码,这就符合了开闭原则。

 


  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;

  5. namespace 设计模式
  6. {
  7.     class CountMoney2
  8.     {
  9.         public static void Main()
  10.         {
  11.             Employee emp = new Employee() ;
  12.             Manager man = new Manager() ;

  13.             Console.WriteLine( "普通员工的工资:{0}" , CountSalary( emp ) ) ;
  14.             Console.WriteLine( "管理人员工的工资:{0}" , CountSalary( man ) ) ;

  15.             Console.ReadLine() ;
  16.         }

  17.         public static float CountSalary( Person per )
  18.         {
  19.             float reFloat = 0.0f ;

  20.             reFloat = per.DaySalary * per.WorkDayCount ;
  21.             
  22.             return reFloat ;
  23.         }
  24.     }

  25.     interface Person
  26.     {
  27.         float WorkDayCount{ get;} 
  28.         float DaySalary { get;} 
  29.     }

  30.     class Employee : Person
  31.     {
  32.         public float workDayCount = 30 ;

  33.         #region Person 成员

  34.         public float WorkDayCount
  35.         {
  36.             get { return this.workDayCount ; }
  37.         }

  38.         #endregion

  39.         #region Person 成员


  40.         public float DaySalary
  41.         {
  42.             get { return 200.0f ; }
  43.         }

  44.         #endregion
  45.     }

  46.     class Manager : Person
  47.     {
  48.         public float workDayCount = 28 ;

  49.         #region Person 成员

  50.         public float WorkDayCount
  51.         {
  52.             get { return this.workDayCount ; }
  53.         }

  54.         #endregion

  55.         #region Person 成员


  56.         public float DaySalary
  57.         {
  58.             get { return 300.0f ; }
  59.         }

  60.         #endregion
  61.     }
  62. }

 

未完。。。

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多