圖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
- }
- }
未完。。。