設計模式描述了軟體設計過程中某一類常見問題的一般性的解決方案。
物件導向設計模式描述了物件導向設計過程中、特定情境下、類與相互連信的對象之間常見的組織關係。
樣本情境:
我們需要設計一個人事管理系統,其中的一個功能是對各種不同類型的員工,計算其當月的工資——不同類型的員工,擁有不同的薪金計算制度。
結構化做法
1。獲得人事系統中所有可能的員工類型
2。根據不同的員工類型所對應的不同的薪金制度,計算其工資
enum EmployeeType{
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類等)則不需要做任何改變。
從宏觀層面來看,物件導向的構建方式更能適應軟體的變化,能將變化所帶來的影響減為最小。
從微觀層面來看,物件導向的方式更強調各個類的“責任”,新增員工類型不會影響原來員工類型的實現代碼——這更符合真實的世界,也更能控制變化所影響的範圍,畢竟Engineer類不應該為新增的“鐘點工”來買單……
• 對象是什嗎?
– 從概念層面講,對象是某種擁有責任的抽象。
– 從規格層面講,對象是一系列可以被其他對象使用的公用介面。
– 從語言實現層面來看,對象封裝了代碼和資料。
從設計原則到設計模式
1、針對介面編程,而不是針對實現編程;
2、優先使用對象組合,而不是類繼承;
3、封裝變化點
使用重構得到模式!!!
幾條更具體的設計原則
• 單一職責原則(SRP):
– 一個類應該僅有一個引起它變化的原因。
• 開放封閉原則(OCP):
– 類別模組應該是可擴充的,但是不可修改(對擴充開放,對更改封閉)
• Liskov 替換原則(LSP):
– 子類必須能夠替換它們的基類
• 依賴倒置原則(DIP):
– 高層模組不應該依賴於低層模組,二者都應該依賴於抽象。
– 抽象不應該依賴於實現細節,實現細節應該依賴於抽象。
• 介面隔離原則(ISP):
– 不應該強迫客戶程式依賴於它們不用的方法。