好久沒有寫博客啦,因最近在忙於弄自己的一個網站,一直沒有時間寫了,在這裡跟廣大園友說聲抱歉,今天也正好是中秋節,在這裡祝大家節日快樂!廢話少說,接續上節的繼續寫下去。
依賴倒置原則(Dependence Inversion Principle),簡稱DIP:他的核心思想就是在進行業務設計時,高層模塊不應該依賴於底層模塊,兩者應該依賴與抽象,抽象而不依賴於具體實現,具體實現應該依賴與抽象,這樣會使代碼變得更穩定,從而大大提高了程序應對業務變化的能力。
我們來看一下一個例子來更深刻的理解一下上面的核心思想:
1 public class Car
2
3 {
4
5 public string CarName;
6
7
8
9 public Car(string carname)
10
11 {
12
13 this.CarName = carname;
14
15 }
16
17 public void 駕駛()
18
19 {
20
21 Console.WriteLine(CarName + ":駕駛");
22
23 }
24
25
26
27 }
28
29
30
31 public class Person
32
33 {
34
35 public void drive()
36
37 {
38
39 Car bmw=new Car("BMW");
40
41 bmw.駕駛();
42
43 }
44
45 }
從上面的例子看一下能發現Person類依賴與Car類,這樣耦合度高,這樣的話比如說Car類發生變化時很容易出現問題,比如說哪天這個Person類不想開汽車了想開火車或者飛機時怎麼辦,那我們可以改造一下上面的類,Person類不依賴於Car這個具體實現,我們要依賴抽象,依賴與交通工具,我們看看代碼:
1 //交通工具才抽象
2
3 public interface IVehicle
4
5 {
6
7 void 駕駛();
8
9 }
10
11 //汽車
12
13 public class Car : IVehicle
14
15 {
16
17 public string CarName;
18
19
20
21 public Car(string carname)
22
23 {
24
25 this.CarName = carname;
26
27 }
28
29 public void 駕駛()
30
31 {
32
33 Console.WriteLine(CarName + ":駕駛");
34
35 }
36
37
38
39 }
40
41 //飛機
42
43 public class Plane : IVehicle
44
45 {
46
47 public string PlaneName;
48
49
50
51 public Plane(string carname)
52
53 {
54
55 this.PlaneName = carname;
56
57 }
58
59 public void 駕駛()
60
61 {
62
63 Console.WriteLine(PlaneName + ":駕駛");
64
65 }
66
67
68
69 }
70
71 //火車
72
73 public class Train : IVehicle
74
75 {
76
77 public string TrainName;
78
79
80
81 public Train(string carname)
82
83 {
84
85 this.TrainName = carname;
86
87 }
88
89 public void 駕駛()
90
91 {
92
93 Console.WriteLine(TrainName + ":駕駛");
94
95 }
96
97
98
99 }
100
101 public class Person
102
103 {
104
105 private IVehicle machine = null;
106
107 public Person(IVehicle _vehicle)
108
109 {
110
111 machine = _vehicle;
112
113 }
114
115 public void drive()
116
117 {
118
119 machine.駕駛();
120
121 }
122
123 }
類圖如下:
客戶端調用代碼:
1 Person person1=new Person(new Car("寶馬"));
2
3 person1.drive();
4
5 Person person2=new Person(new Plane("飛機"));
6
7 person2.drive();
8
9 Person person3=new Person(new Train("火車"));
10
11 person3.drive();
12
13 Console.ReadLine();
輸出結果如下:

從以上代碼可以看出Person類的駕駛方法來說不需要依賴具體的交通工具,只依賴抽象,具體的哪一個交通工具是從外部傳入的。這樣其實就是抽象編碼。也是依賴倒置的有點。
組合優於繼承:他的核心思想就是組合比繼承更大的靈活性和穩定結構。
為什麼怎麼說呢,我們來看看他們各自的優缺點:
繼承優點:
1)新的實現很容易,因為大部分是繼承而來的。
2)很容易修改和擴展已有的實現
繼承的缺點:
1)打破了封裝,因為基類想子類暴露額具體的實現細節。
2)白盒重用,因為基類的內部細節通常對子類是可見的。
3)當父類發生改變時子類也做出相應的改變。
4)不能在運行時修改由父類繼承來的實現。
組合優點:
1)被包含對象通過包含他們的類來訪問
2)黑盒重用,因為被包含對象的內部細節是不可見的
3)很好的封裝
4)每一個類都專注於一個任務
5)通過獲得和被包含對象的類型相同的對象引用,可以在運行時動態定義組合的方式
組合缺點:
1)系統可能會包含更過的對象
2)為了使組合時可以使用不同的對象,必須小心的定義接口。
近年來,大家都開始注意設計模式。那麼,到底我們為什麼要用設計模式呢?這麼多設計模式為什麼要這麼設計呢?說實話,以前我還真沒搞清楚。就是看大家一口一個"Design pattern",心就有點發虛。於是就買了本"四人幫"的設計模式,結果看得似懂非懂:看得時候好像是懂了,過一會就忘了。可能是本人比較"愚鈍"吧:))最近,有了點感悟。"獨樂不如眾樂",與大家分享一下,還望指教!
為什麼要提倡"Design Pattern"呢?根本原因是為了代碼復用,增加可維護性。那麼怎麼才能實現代碼復用呢?OO界有前輩的幾個原則:"開-閉"原則(Open Closed Principal)、裡氏代換原則、合成復用原則。設計模式就是實現了這些原則,從而達到了代碼復用、增加可維護性的目的。
一、"開-閉"原則
此原則是由"Bertrand Meyer"提出的。原文是:"Software entities should be open for extension,but closed for modification"。就是說模塊應對擴展開放,而對修改關閉。模塊應盡量在不修改原(是"原",指原來的代碼)代碼的情況下進行擴展。那麼怎麼擴展呢?我們看工廠模式"factory pattern":假設中關村有一個賣盜版盤和毛片的小子,我們給他設計一"光盤銷售管理軟件"。我們應該先設計一"光盤"接口。如圖:
而盜版盤和毛片是其子類。小子通過"DiscFactory"來管理這些光盤。代碼為:
public class DiscFactory{
public static 光盤 getDisc(String name){
return (光盤)Class.forName(name).getInstance();
}}
有人要買盜版盤,怎麼實現呢?
public class 小子{
public static void main(String[] args){
光盤 d=DiscFactory.getDisc("盜版盤");
光盤.賣();
}}
如果有一天,這小子良心發現了,開始賣正版軟件。沒關系,我們只要再創建一個"光盤"的子類"正版軟件"就可以了。不需要修改原結構和代碼。怎麼樣?對擴展開發,對修改關閉。"開-閉原則"
工廠模式是對具體產品進行擴展,有的項目可能需要更多的擴展性,要對這個"工廠"也進行擴展,那就成了"抽象工廠模式"。
二、裡氏代換原則
裡氏代換原則是由"Barbara Liskov"提出的。如果調用的是父類的話,那麼換成子類也完全可以運行。比如:
光盤 d=new 盜版盤();
d.賣();
現在要將"盜版盤"類改為"毛片"類,沒問題,完全可以運行。Java編譯程序會檢查程序是否符合裡氏代換原則。還記得java繼承的一個原則嗎?子類overload方法的訪問權限不能小於父類對應方法的訪問......余下全文>>
歲月沉澱出的流年,無論我怎樣努力都是荒蕪中的一段夢,過去了,再也回不去了。如果說;記憶能將午夜夢回的淚水撥動出幸福的旋律,我想;關於你的到來不管是想起還是淚水,都應該是我最幸福律動,曾聽人說,流浪者,必須要經過一條漂泊中的河橋,這座河橋不戀世俗名利,沒有太多的繁華,只是在左右孤單中寂寞的旅程,只要邁步走過,那便就是幸福的終點。