設計模式七大原則
一、設計模式的目的
編寫軟體過程中,程式設計師面臨著來自 耦合性,內聚性以及可維護性,可擴充套件性,重用性,靈活性 等多方面的挑戰,設計模式是為了讓程式(軟體),具有更好
- 程式碼重用性 (即:相同功能的程式碼,不用多次編寫)
- 可讀性 (即:程式設計規範性, 便於其他程式設計師的閱讀和理解)
- 可擴充套件性 (即:當需要增加新的功能時,非常的方便,稱為可維護)
- 可靠性 (即:當我們增加新的功能後,對原來的功能沒有影響)
- 使程式呈現高內聚,低耦合的特性
二、設計模式七大原則
設計模式原則,其實就是程式設計師在程式設計時,應當遵守的原則,也是各種設計模式的基礎(即:設計模式為什麼這樣設計的依據)
1. 單一職責原則
基本介紹:
對類來說的,即一個類應該只負責一項職責。如類A負責兩個不同職責:職責1,職責2。當職責1需求變更而改變A時,可能造成職責2執行錯誤,所以需要將類A的粒度分解為 A1,A2。
應用例項:交通工具案例
方案1 [分析說明]
package com.lhc.principle.singleresponsibility;
public class SingleResponsibility {
public static void main(String[] args) {
// TODO Auto-generated method stub
Vehicle vehicle = new Vehicle();
vehicle.run("摩托車");
vehicle.run("汽車");
vehicle.run("飛機");
}
}
//1.違反單一職責原則
//解決方案:根據交通工具執行方法不同,分解成不同類即可
class Vehicle{
public void run(String vehicle) {
System.out.println(vehicle + "在公路上執行...");
}
}
方案2 [分析說明]
package com.lhc.principle.singleresponsibility;
public class SingleResponsibility2 {
public static void main(String[] args) {
// TODO Auto-generated method stub
RoadVehicle roadVehicle = new RoadVehicle();
roadVehicle.run("摩托車");
roadVehicle.run("汽車");
AirVehicle airVehicle = new AirVehicle();
airVehicle.run("飛機");
}
}
//遵守單一職責原則
//改動很大,即將類分解,同時修改客戶端
//解決方案,直接修改Vehicle類,改動的程式碼會比較少
class RoadVehicle{
public void run(String vehicle) {
System.out.println(vehicle + "公路執行");
}
}
class AirVehicle{
public void run(String vehicle) {
System.out.println(vehicle + "空中執行");
}
}
方案3 [分析說明]
package com.lhc.principle.singleresponsibility;
public class SingleResponsibility3 {
public static void main(String[] args) {
// TODO Auto-generated method stub
Vehicle2 vehicle2 = new Vehicle2();
vehicle2.run("摩托車");
vehicle2.run("汽車");
vehicle2.runAir("飛機");
}
}
//這種方法沒有對原來的類做大的修改,只是增加了方法
//
class Vehicle2{
public void run(String vehicle) {
System.out.println(vehicle + "在公路上執行...");
}
public void runAir(String vehicle) {
System.out.println(vehicle + "在空中執行...");
}
}
單一職責原則注意事項和細節:
- 降低類的複雜度,一個類只負責一項職責。
- 提高類的可讀性,可維護性
- 降低變更引起的風險
- 通常情況下,我們應當遵守單一職責原則,只有邏輯足夠簡單,才可以在程式碼級違反單一職責原則;只有類中方法數量足夠少,可以在方法級別保持單一職責原則
2.介面隔離原則
基本介紹:
-
客戶端不應該依賴它不需要的介面,即一個類對另一個類的依賴應該建立在最小的介面上
-
先看一張圖:
-
類A通過介面Interface1依賴類B,類C通過介面Interface1依賴類D,如果介面Interface1對於類A和類C來說不是最小介面,那麼類B和類D必須去實現他們不需要的方法。
-
按隔離原則應當這樣處理:將介面Interface1拆分為獨立的幾個介面,類A和類C分別與他們需要的介面建立依賴關係。也就是採用介面隔離原則。
應用例項:
未使用介面隔離的程式碼:
package com.lhc.principle.segregation;
public class Segregation1 {
public static void main(String[] args) {
}
}
interface Interface1{
void operation1();
void operation2();
void operation3();
void operation4();
void operation5();
}
class B implements Interface1{
public void operation1() {
System.out.println("B 實現了 operation1");
}
public void operation2() {
System.out.println("B 實現了 operation2");
}
public void operation3() {
System.out.println("B 實現了 operation3");
}
public void operation4() {
System.out.println("B 實現了 operation4");
}
public void operation5() {
System.out.println("B 實現了 operation5");
}
}
class D implements Interface1{
public void operation1() {
System.out.println("D 實現了 operation1");
}
public void operation2() {
System.out.println("D 實現了 operation2");
}
public void operation3() {
System.out.println("D 實現了 operation3");
}
public void operation4() {
System.out.println("D 實現了 operation4");
}
public void operation5() {
System.out.println("D 實現了 operation5");
}
}
class A{
public void depend1(Interface1 i) {
i.operation1();
}
public void depend2(Interface1 i) {
i.operation2();
}
public void depend3(Interface1 i) {
i.operation3();
}
}
class C{
public void depend1(Interface1 i) {
i.operation1();
}
public void depend4(Interface1 i) {
i.operation4();
}
public void depend5(Interface1 i) {
i.operation5();
}
}
類A通過介面Interface1依賴類B, 類C通過介面Interface1依賴類D。
使用介面隔離後的程式碼:
package com.lhc.principle.segregation1;
public class Segregation1 {
public static void main(String[] args) {
// TODO Auto-generated method stub
// 使用一把
A a = new A();
a.depend1(new B()); // A類通過介面去依賴B類
a.depend2(new B());
a.depend3(new B());
C c = new C();
c.depend1(new D()); // C類通過介面去依賴(使用)D類
c.depend4(new D());
c.depend5(new D());
}
}
// 介面1
interface Interface1 {
void operation1();
}
// 介面2
interface Interface2 {
void operation2();
void operation3();
}
// 介面3
interface Interface3 {
void operation4();
void operation5();
}
class B implements Interface1, Interface2 {
public void operation1() {
System.out.println("B 實現了 operation1");
}
public void operation2() {
System.out.println("B 實現了 operation2");
}
public void operation3() {
System.out.println("B 實現了 operation3");
}
}
class D implements Interface1, Interface3 {
public void operation1() {
System.out.println("D 實現了 operation1");
}
public void operation4() {
System.out.println("D 實現了 operation4");
}
public void operation5() {
System.out.println("D 實現了 operation5");
}
}
class A { // A 類通過介面Interface1,Interface2 依賴(使用) B類,但是隻會用到1,2,3方法
public void depend1(Interface1 i) {
i.operation1();
}
public void depend2(Interface2 i) {
i.operation2();
}
public void depend3(Interface2 i) {
i.operation3();
}
}
class C { // C 類通過介面Interface1,Interface3 依賴(使用) D類,但是隻會用到1,4,5方法
public void depend1(Interface1 i) {
i.operation1();
}
public void depend4(Interface3 i) {
i.operation4();
}
public void depend5(Interface3 i) {
i.operation5();
}
}
3.依賴倒轉原則
基本介紹:
- 高層模組不應該依賴低層模組,二者都應該依賴其抽象
- 抽象不應該依賴細節,細節應該依賴抽象
- 依賴倒轉(倒置)的中心思想是面向介面程式設計
- 依賴倒轉原則是基於這樣的設計理念:相對於細節的多變性,抽象的東西要穩定的多。以抽象為基礎搭建的架構比以細節為基礎的架構要穩定的多。在java中,抽象指的是介面或抽象類,細節就是具體的實現類
- 使用介面或抽象類的目的是制定好規範,而不涉及任何具體的操作,把展現細節的任務交給他們的實現類去完成
依賴倒轉原則的注意事項和細節
- 低層模組儘量都要有抽象類或介面,或者兩者都有,程式穩定性更好.
- 變數的宣告型別儘量是抽象類或介面, 這樣我們的變數引用和實際物件間,就存在
一個緩衝層,利於程式擴充套件和優化 - 繼承時遵循里氏替換原則
4.里氏替換原則
基本介紹:
- 里氏替換原則(Liskov Substitution Principle)在1988年,由麻省理工學院的以為姓裡的女士提出的。
- 如果對每個型別為T1的物件o1,都有型別為T2的物件o2,使得以T1定義的所有程式P在所有的物件o1都代換成o2時,程式P的行為沒有發生變化,那麼型別T2是型別T1的子型別。換句話說,所有引用基類的地方必須能透明地使用其子類的物件。
- 在使用繼承時,遵循里氏替換原則,在子類中儘量不要重寫父類的方法
- 里氏替換原則告訴我們,繼承實際上讓兩個類耦合性增強了,在適當的情況下,可以通過聚合,組合,依賴 來解決問題。.
5.開閉原則
基本介紹:
- 開閉原則(Open Closed Principle)是程式設計中最基礎、最重要的設計原則
- 一個軟體實體如類,模組和函式應該對擴充套件開放(對提供方),對修改關閉(對使用方)。用抽象構建框架,用實現擴充套件細節。
- 當軟體需要變化時,儘量通過擴充套件軟體實體的行為來實現變化,而不是通過修改已有的程式碼來實現變化。
- 程式設計中遵循其它原則,以及使用設計模式的目的就是遵循開閉原則。
6.迪米特法則
基本介紹:
- 一個物件應該對其他物件保持最少的瞭解
- 類與類關係越密切,耦合度越大
- 迪米特法則(Demeter Principle)又叫最少知道原則,即一個類對自己依賴的類知道的越少越好。也就是說,對於被依賴的類不管多麼複雜,都儘量將邏輯封裝在類的內部。對外除了提供的public 方法,不對外洩露任何資訊
- 迪米特法則還有個更簡單的定義:只與直接的朋友通訊
- 直接的朋友:每個物件都會與其他物件有耦合關係,只要兩個物件之間有耦合關係,我們就說這兩個物件之間是朋友關係。耦合的方式很多,依賴,關聯,組合,聚合等。其中,我們稱出現成員變數,方法引數,方法返回值中的類為直接的朋友,而出現在區域性變數中的類不是直接的朋友。也就是說,陌生的類最好不要以區域性變數的形式出現在類的內部。
迪米特法則注意事項和細節:
- 迪米特法則的核心是降低類之間的耦合
- 但是注意:由於每個類都減少了不必要的依賴,因此迪米特法則只是要求降低類間(物件間)耦合關係, 並不是要求完全沒有依賴關係
7.合成複用原則
基本介紹:
原則是儘量使用合成/聚合的方式,而不是使用繼承
設計原則核心思想
- 找出應用中可能需要變化之處,把它們獨立出來,不要和那些不需要變化的程式碼混在一起。
- 針對介面程式設計,而不是針對實現程式設計。
- 為了互動物件之間的鬆耦合設計而努力
相關文章
- 設計模式 -- 設計模式七大原則設計模式
- 設計模式的七大原則設計模式
- 設計模式“6”大原則!設計模式
- 設計模式的七大原則詳解設計模式
- 設計模式的七大原則(5) --開閉原則設計模式
- 設計模式的七大原則(6) --迪米特法則設計模式
- 設計模式的七大原則(4) --里氏替換原則設計模式
- 設計模式的七大原則(2) --介面隔離原則設計模式
- 設計模式的七大原則(1) --單一職責原則設計模式
- 設計模式之7大原則設計模式
- 設計模式-六大原則設計模式
- 設計模式——六大原則設計模式
- 設計模式六大原則設計模式
- 通俗簡潔概括設計模式的七大原則的宗旨設計模式
- 設計模式之六大原則設計模式
- 設計模式的六大原則設計模式
- Python設計模式六大原則!Python設計模式
- 設計模式六大原則詳解設計模式
- Java的設計模式和6大原則Java設計模式
- 設計模式六大原則(六)----開閉原則設計模式
- 設計模式六大原則(四)----介面隔離原則設計模式
- 設計模式六大原則(五)----迪米特法則設計模式
- 物件導向程式設計(OOP)的七大原則物件程式設計OOP
- 聊一聊設計模式(一)-- 六大原則設計模式
- 設計模式的分類和六大原則設計模式
- 設計模式六大原則(二)----裡式替換原則設計模式
- 設計模式六大原則(一)----單一職責原則設計模式
- 好程式設計師Java教程分享Java設計模式的6大原則程式設計師Java設計模式
- 物件導向的7大原則與23種設計模式物件設計模式
- 設計模式:物件導向設計的六大原則 (絕對詳細)設計模式物件
- 設計類六大原則
- 軟體設計7大原則
- 【設計模式筆記】(零)- 物件導向的六大原則設計模式筆記物件
- 婚戀app原始碼設計模式六大原則有哪些?APP原始碼設計模式
- Python設計模式的六大原則分別是什麼?Python設計模式
- 好程式設計師Java培訓分享Java設計模式的六大原則程式設計師Java設計模式
- 【設計模式】第一篇:概述、耦合、UML、七大原則,詳細分析總結(基於Java)設計模式Java
- 遊戲設計的三大原則遊戲設計