軟件工程六大設計原則總結,案例演示 軟件工程六大設計原則總結,案例演示

摘自:https://www.cnblogs.com/cicada-smile/p/11974550.html

軟件工程六大設計原則總結,案例演示

 

本文源碼:GitHub·點這裏 || GitEE·點這裏

一、單一職責原則

1、概念描述

對類來說的,即一個類應該只負責一項職責。如果一個類負責兩個職責,可能存在職責1變化,引起職責2變化的情況。可以基於抽象邏輯,或者業務邏輯對類進行細化。

2、案例演示

這裏基於方法和類的細化都可以,可以根據實際業務選擇。

class Animal {
    public void dogVoice (){
        System.out.println("狗叫聲:旺旺");
    }
    public void cowVoice (){
        System.out.println("牛叫聲:哞哞");
    }
}
class DogVoice {
    public String getDogVoice (){
        return "旺旺" ;
    }
}
class CowVoice {
    public String getCowVoice (){
        return "哞哞" ;
    }
}

3、注意事項

減少代碼一處變更引起的程序大規模改動情況,降低類的複雜度,提高類的可讀性,可維護性。通常情況下,需要遵守單一職責原則,可以適當違反單一職責原則。

二、接口隔離原則

1、概念描述

客戶端不應該依賴它不需要的接口,一個類對另一個類的依賴,應該建立在最小的接口上。

2、案例演示

interface ReadBlog {
    String getBlog () ;
}
interface AdminBlog {
    Boolean insertBlog () ;
    Boolean updateBlog () ;
    Boolean deleteBlog () ;
}
/**
 * 讀者只開放博客閱讀接口
 */
class Reader implements ReadBlog {
    @Override
    public String getBlog() {
        return null;
    }
}
/**
 * 管理員有博客全部的管理權限
 */
class AdminUser implements AdminBlog,ReadBlog {
    @Override
    public String getBlog() {
        return null;
    }
    @Override
    public Boolean insertBlog() {
        return null;
    }
    @Override
    public Boolean updateBlog() {
        return null;
    }
    @Override
    public Boolean deleteBlog() {
        return null;
    }
}

3、注意事項

接口的設計粒度越小,則應用系統程序越靈活,程序變得靈活也就意味同時結構複雜性提高,開發開發和理解的難度也會變大,可維護性降低。

三、依賴倒轉原則

1、概念描述

高層模塊不應該依賴低層模塊,兩者應依賴其抽象;抽象不應該依賴細節,細節應該依賴抽象;中心思想是面向接口編程。

2、案例演示

public class C01_FarmFactory {
    public static void main(String[] args) {
        Animal animal = new Dog() ;
        FarmFactory farm = new Farming() ;
        farm.breed(animal) ;
        animal = new Pig() ;
        farm.breed(animal) ;
    }
}
/**
 * 接口聲明依賴對象
 */
interface FarmFactory {
    void breed (Animal animal) ;
}
class Farming implements FarmFactory {
    @Override
    public void breed(Animal animal) {
        System.out.println("農場飼養:"+animal.getAnimalName());
    }
}
interface Animal {
    String getAnimalName () ;
}
class Dog implements Animal {
    @Override
    public String getAnimalName() {
        return "牧羊犬";
    }
}
class Pig implements Animal {
    @Override
    public String getAnimalName() {
        return "土豬一號";
    }
}

3、注意事項

相對於系統開發的多變性,抽象的相對穩定。以抽象爲基礎搭建的架構比以細節爲基礎的架構要穩定靈活。下層模塊儘量都要有抽象類或接口,程序穩定性更好。變量的聲明類型儘量是抽象類或接口,這樣變量引用和實際對象之間存在一個過渡空間,利於程序擴展和優化。

四、里氏替換原則

1、概念描述

假設如下場景:

  • 存在,一個類型T1,和實例的對象O1
  • 存在,一個類型T2,和實例的對象O2

如果將所有類型爲T1的對象O1都替換成類型T2的對象O2,程序的行爲不發生改變。那麼類型T2是類型T1的子類型。換句話說,所有引用基類的地方必須能透明地使用其子類的對象。

2、案例演示

public class C01_Calculate {
    public static void main(String[] args) {
        BizCalculate bizCalculate = new BizCalculate() ;
        System.out.println(bizCalculate.add(2,3));
    }
}
class Calculate { }
class BaseCalculate extends Calculate {
    public int add (int a,int b){
        return a+b;
    }
}
/**
 * 這裏使用組合的方式完成計算
 */
class BizCalculate extends Calculate {
    private BaseCalculate baseCalculate = new BaseCalculate() ;
    public int add (int a,int b){
        return this.baseCalculate.add(a,b);
    }
}

3、注意事項

使用繼承時,遵循里氏替換原則,在子類中儘量不要重寫父類的方法;子類可以擴展父類的功能,但不能改變原有父類的功能;在適當的情況下,可以通過聚合,組合,依賴等方式解決問題。

五、開閉原則

1、概念描述

開閉原則是編程中最基礎、最重要的設計原則,在代碼結構的設計設計時,應該考慮對擴展開放,對修改關閉,抽象思維搭建結構,具體實現擴展細節。

2、案例演示

public class C01_BookPrice {
    public static void main(String[] args) {
        ParityBook parityBook = new DiscountBook("Java",100.00) ;
        System.out.println(parityBook.getPrice());
    }
}
interface Book {
    String getName () ;
    Double getPrice () ;
}
/**
 * 平價書籍
 */
class ParityBook implements Book {
    private String name ;
    private Double price ;
    public ParityBook(String name, Double price) {
        this.name = name;
        this.price = price;
    }
    @Override
    public String getName() {
        return this.name ;
    }
    @Override
    public Double getPrice() {
        return this.price ;
    }
}
/**
 * 打折數據擴展價格計算策略
 */
class DiscountBook extends ParityBook {
    public DiscountBook(String name, Double price) {
        super(name, price);
    }
    @Override
    public Double getPrice() {
        double oldPrice = super.getPrice();
        return oldPrice * 0.8 ;
    }
}

3、注意事項

基於開閉原則設計的代碼結構可以提高複用性和可維護性,通過接口或抽象類可以約束類的變化行爲,基於指定策略對變化行爲進行封裝,並且能夠實現對擴展開放,使用設計模式的基本原則就是遵循開閉原則。

六、迪米特原則

1、概念描述

迪米特原則又叫最少知道原則,即一個類對自己依賴的類知道的越少越好。也就是說,對於被依賴的類不管多麼複雜,都儘量將邏輯封裝在類的內部。對外除了提供的public方法,不對外開放任何信息。類與類關係越密切,耦合度越大,耦合的方式很多,依賴,關聯,組合,聚合等。

  • 直接朋友概念

兩個對象之間有耦合關係,就說這兩個對象之間是朋友關係。其中出現成員變量,方法參數,方法返回值中的類稱爲直接朋友,而出現在局部變量中的類不是直接朋友。從原則上說,陌生的類最好不要以局部變量的形式出現在類的內部。

2、案例演示

public class C01_Employee {
    public static void main(String[] args) {
        HeadCompanyEmpManage empManage = new HeadCompanyEmpManage() ;
        BranchCompanyEmpManage branchEmp = new BranchCompanyEmpManage() ;
        empManage.printEmp(branchEmp);
    }
}
/**
 * 總公司員工
 */
class HeadCompanyEmp {
    public String name ;
    public HeadCompanyEmp(String name) {
        this.name = name;
    }
    @Override
    public String toString() {
        return "HeadCompanyEmp{name='" + name + '}';
    }
}
/**
 * 分公司員工
 */
class BranchCompanyEmp {
    public String name ;
    public BranchCompanyEmp(String name) {
        this.name = name;
    }
    @Override
    public String toString() {
        return "BranchCompanyEmp{name='" + name + '}';
    }
}
/**
 * 分公司員工管理
 */
class BranchCompanyEmpManage {
    // 添加分公司員工
    public List<BranchCompanyEmp> addEmp (){
        List<BranchCompanyEmp> list = new ArrayList<>() ;
        for (int i = 1 ; i <= 3 ; i++){
            list.add(new BranchCompanyEmp("分公司員工"+i)) ;
        }
        return list ;
    }
    // 獲取分公司員工
    public void printBranchCompanyEmp (){
        List<BranchCompanyEmp> list = addEmp () ;
        for (BranchCompanyEmp emp:list){
            System.out.println(emp);
        }
    }
}
/**
 * 總公司員工管理,基於迪米特原則,不出現陌生類
 */
class HeadCompanyEmpManage {
    // 添加總公司員工
    public List<HeadCompanyEmp> addHeadEmp (){
        List<HeadCompanyEmp> list = new ArrayList<>() ;
        for (int i = 1 ; i <= 3 ; i++){
            list.add(new HeadCompanyEmp("總公司員工"+i)) ;
        }
        return list ;
    }
    public void printEmp (BranchCompanyEmpManage empManage){
        // 打印分公司員工
        empManage.printBranchCompanyEmp();
        List<HeadCompanyEmp> headEmpList = addHeadEmp () ;
        for (HeadCompanyEmp headCompanyEmp:headEmpList){
            System.out.println(headCompanyEmp);
        }
    }
}

3、注意事項

迪米特原則的初衷是降低類之間的耦合,由於每個類都減少了不必要的依賴,因此可以降低耦合關係。降低耦合關係,並不是要求完全沒有依賴關係,過度的使用迪米特原則,容易產生大量的中間類,導致複雜度變大。所以在使用迪米特原則時要根據實際業務權衡。

七、設計原則總結

設計模式和設計原則的核心思想都是:判斷業務應用中可能會變化模塊,並且把這些模塊獨立出來,基於指定的策略進行封裝,不要和那些變化的不大的模塊耦合在一起,封裝思想上基於接口和抽象類,而不是針對具體的實現編程。核心目的就是降低交互對象之間的鬆耦合度。設計模式和原則都不是可以生搬硬套的公式,個人理解:只要形似,神韻就自然不差。

八、源代碼地址

GitHub·地址
https://github.com/cicadasmile/model-arithmetic-parent
GitEE·地址
https://gitee.com/cicadasmile/model-arithmetic-parent

 
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章