一、uml的學習,了解
1.類圖(主要)
2.時序圖(箭頭、生命線--垂直的虛線、激活條)
3.狀態圖
二、設計原則
1.軟件系統的核心的軟件的可維護性(maintainability)和可重用性(Reusability)
I、軟件維護性低的4點原因(過于僵硬Rigidity、過于脆弱Flagility、復用性低Immobility、黏度過高viscosity)
II、設計目標3條:(可擴展性Extensibility、靈活性Flexibility、可插入性Pluggability)
III、面向對象的復用:復用焦點的倒轉說的是復用不再集中到函數和算法的具體實現上,而是集中到最重要的業務邏輯上去。
2.設計原則
I、開閉原則(Open-Closed-Principle) ----> OOD 的根本
定義: 就是軟件實體應該對擴展開放,對修改關閉。
如何實現:關鍵在于抽象化(就是說給系統定義出一個不再更改的抽象設計,此設計允許有無窮無盡的的行為在實現層被實現)
對可變性的封裝原則(Principle of Encapsulation of Variation EVP 這是OCP的另一個角度的說法) :定義是找到一個可變的因素,將其封裝起來。
一種重構做法的討論:
"將條件轉移語句改寫為多態性" 是廣為流傳的代碼重構的做法,要注意使用的場合(從OCP出發)
java.util.Calendar 不符合開閉原則,
II、接口和抽象類
1.抽象類是用來繼承的,具體類不是用來繼承的(認真體會)
2.抽象類應該擁有盡可能多的代碼,盡可能少的數據
3.不要濫用繼承,哪何時使用繼承呢?
滿足4條可使用繼承(
a.子為父的特殊種類,而不是一個角色 是is-a關系,而不是(has-a關系-->聚合Aggregation)
b.永遠不會出現需要將一個子類轉換成另一個子類的情況
c.子類具有擴展超類的責任,而不是置換掉(override)或者 注銷掉(Nullify) 的責任
d.只有在分類學有意義時,才可以使用繼承,不要從工具類繼承
)
III、里氏代換原則(Liskov Substitution Principle LSP)----> 是繼承復用的根本
1.定義:一個軟件實體如果使用的一個超類的話,那么一定適用于子類,而且根本察覺不到超類對象和子類對象的區別。
(換言之---> 父類使用的地方,一定可以替換成子類)
2.Java語言可以在編譯期間可以從無關業務邏輯、語法上檢查一個程序是否符合LSP(比如說:子類中override父類的一個方法時其訪問權限不能更小)
3.LSP說的是超類和子類之間的關系。
IV、依賴倒轉原則(Dependency Inversion Principle)
1.定義: 要依賴于抽象,不要依賴于具體
2.依賴(耦合)關系
a.零耦合(Nil Coupling)兩個類沒有耦合關系
b.具體耦合(Concrete Coupling)兩個具體類之間,一個類對另一個類直接調用造成
c.抽象耦合(Abstract Coupling) 一個抽象類和一個具體類之間
3.具體說明:
a.DIP 要求客戶端依賴于抽象耦合
b.表述一: 抽象不應該依賴于細節,細節應該依賴于抽象(Abstractions should not depend upon details,Details should depend upon abstractions)
c.表述二:要針對于接口編程,不要針對于實現編程(Program to an interface not an implementation)
具體來說:針對于接口編程,就是使用Java接口和抽象Java類進行 變量的類型聲明、參數的類型聲明、方法返回值的類型聲明、數據類型的轉換
反之,就是不使用 如何做到呢??一個具體的Java類應該只實現Java接口和抽象Java類中聲明過的方法,而不應該寫其他多余的方法
4.變量的靜態類型和變量的實際類型
a.靜態類型(Static Type): 變量被聲明時的類型,又稱明顯類型(Apparent Type)
b.實際類型(Actual Type): 變量所引用對象的真實類型
比如: List employees = new Vector(); //List為靜態類型,Vector為實際類型
c.作用: 要引用對象的抽象類型--> 如果一個對象有一個抽象類型的話,應該使用此抽象類型作為對象的靜態類型.
List employees = new Vector(); // 代替 Vector employees = new Vector();
List employees = new ArrayList(); //面向抽象編程 這里有一定的問題,其構造還是具體類的構造,需要通過模式改進。
5.如何做到依賴倒轉?
a.關鍵點:以抽象方式耦合
6.Java對抽象類型的支持
a.提供了兩種支持:接口和抽象類
b.接口和抽象類區別
1.抽象類可以提供部分方法的實現,而接口不可以
2.子類只能繼承1個抽象類,而接口的實現類卻可以實現多個接口
3.從代碼重構的角度看,將一個具體類重構成一個接口的實現很容易,而抽象類卻比較復雜
4.Java接口是定義混合類型(Mixin Type) 的理想工具
比如Hashtable 其主類型是Map 次類型為Clonable Serializable
7.聯合使用Java接口和Java抽象類
具體說明:聲明一個接口,給出一個抽象類實現此接口,在抽象類中具體實現此接口中的方法,可以程序就可以選擇實現接口或者繼承此抽象類
稱為“缺省適配模式(Default Adapter)”
參看Java API (abstract + 接口名) 就使用這樣的 Default Adapter 比如Collection --> AbstractCollection
8.優缺點:
a.強大,但不容易實現(需要很好的oop思想)
b.DIP:假定所有的具體類都是變化的,這不太準確,有些具體類是相對穩定的,就不需要再使用抽象了~·
V、接口隔離原則(Interface Segeration Principle ISP)
1.定義: 使用多個專門的接口比使用單一的總接口要好~,但不要提供不必要的接口,否則可能造成接口污染(interface Contamination)
2.“接口”的理解:
a.一個類中所有方法的集合(角色隔離原則)
b.真正意義上的接口(interface)(定制服務原則:Customized Service)
VI、組合/聚合復用原則(Composition/Aggregation Reuse Principle CARP)
1.定義:在一個新的對象里面使用一些已有的對象,使之稱為新對象的一部分,新的對象通過向這些對象委派達到復用已有功能的目的
簡言之:盡量使用聚合組合,不要使用繼承
2.復用
a.組合/聚合
b.繼承
VII、迪米特法則(Law of Demeter LOD)--> Least Knowledge Principle 最少知識原則
1.定義:一個對象應該對另一個對象有盡可能少的了解
2.如果兩個類不必彼此通信,那么這兩個類也不必發生相互作用,如果其中一個類需要調用另一個類的方法,可以通過第三者轉發這種調用.
3.使用說明:
a.優先考慮將一個類設置為不變類
b.盡量降低一個類的訪問權限
c.慎用Serializable
d.盡量降低成員的訪問權限