七大設計原則

草草_c發表於2021-01-02

1. 開閉原則

定義

一個軟體實體,如類、模組和函式應該對擴充套件開放,對修改關閉。用抽象構建框架,用實現擴充套件細節。

優點

可以提高軟體系統的可複用性和可維護性

示例:

假設我們有一個課程,課程有名稱和價格。但是現在我們有的時候需要對這個課程進行打折出售。
1. 定義一個課程介面

public interface ICourse {
   Integer getId();
   String getName();
   Double getPrice();
}

2. java課程

public class JavaCourse implements ICourse{

    private Integer Id;
    private String name;
    private Double price;

    public JavaCourse(Integer id, String name,Double price){
        this.Id = id;
        this.name = name;
        this.price = price;
    }

    @Override
    public Integer getId() {
        return this.Id;
    }

    @Override
    public String getName() {
        return this.name;
    }

    @Override
    public Double getPrice() {
        return this.price;
    }
}

3. 定義一個課程優惠的類實現上面那個java課程

public class JavaDiscountCourse extends JavaCourse {

    public JavaDiscountCourse(
            Integer id, String name, Double price) {
         super(id, name, price);
    }

    public Double getDiscountPrice(){        
        return super.getPrice() * 0.6;
    }
}

4. 類圖
在這裡插入圖片描述

2. 依賴倒置原則

定義

高層的模組不應該依賴低層模組,兩者都應該依賴其抽象,抽象不應該依賴細節,細節應該依賴抽象。
總結一句話,針對介面程式設計,不要針對實現程式設計。

優點

  1. 可以減少類之間的耦合
  2. 提高系統的穩定性、可讀性和可維護性
  3. 降低修改程式造成的風險

示例

還是已課程為例,我們現在不僅僅有java課程,還設有其他的如python。那麼應該如何做呢?
1.抽象一個課程介面

public interface ICourse {
    void study();
}

2.java課程的實現

public class JavaCourse implements ICourse {
    @Override
    public void study() { 
        System.out.println("Sinclair正在學習java課程");
    }
}

3.python課程的實現

public class PythonCourse implements ICourse {
    @Override
    public void study() {       
        System.out.println("Sinclair正在學習Python課程");
    }
}

4. 定義一個學生類

public class Student {
//    public void studyJavaCourse(){
//        System.out.println("Student正在學習java課程");
//    }
//
//    public void studyPythonCourse(){
//        System.out.println("Student正在學習Python課程");
//    }
    public void study(ICourse iCourse){
        iCourse.study();
    }
}

5.定義一個測試類

public class DependenceInversionTest {
    public static void main(String[] args) {
        Student stu = new Student();

//        stu.studyJavaCourse();
//        stu.studyPythonCourse();
        stu.study(new JavaCourse());
        stu.study(new PythonCourse());
    }
}

6. 類圖
在這裡插入圖片描述

3. 單一職責則

定義

不要存在多餘一個導致類變更的原因。一個類,介面,方法只負責一項職責。

優點

  1. 降低類的複雜度,提高類的可讀性
  2. 提高系統的可維護性
  3. 降低變更引起的風險

示例

還是已課程為例,我們有一個課程,同時我們還要管理這個課程
1.抽象一個課程資訊介面

public interface ICourseInfo {
    void getCourseName();
    void getCourseVideo();
}

2.抽象一個課程管理介面

public interface ICourseManage {
    void studyCourse();
    void refundCourse();
}

3.定義一個課程類實現這兩個介面

public class CourseImpl implements ICourseInfo, ICourseManage {
    @Override
    public void getCourseName() {

    }

    @Override
    public void getCourseVideo() {

    }

    @Override
    public void studyCourse() {

    }

    @Override
    public void refundCourse() {

    }
}

4.類圖
在這裡插入圖片描述

4. 介面隔離原則

定義

用多個專門的介面,而不是使用單一的介面,客戶端不應該依賴它不需要的介面。
注意:

  1. 一個類對應一個類的依賴應該建立在最小的介面上
  2. 建議單一介面,不要為了解耦而建立龐大臃腫的實現介面依賴
  3. 儘量細化介面,介面中的方法儘量少

優點

  1. 符合高內聚,低耦合的設計思想
  2. 具有很好的可讀性、擴充套件性和可維護性

示例

比如說世界上有很多的動物,地上跑的,水裡遊的
1. 抽象一個動物介面

public interface IAnimal {
    void eat();
}

2. 定義一個飛行動物的子介面

public interface IFlyAnimal extends IAnimal {
    void fly();
}

3. 定義一個會游泳的子介面

public interface ISwimAnimal extends IAnimal {
    void swim();
}

4. 不同的動物去實現不同的子介面

public class Dog implements ISwimAnimal {
    @Override
    public void eat() {
    }

    @Override
    public void swim() {
    }
}

public class Bird implements IFlyAnimal {
    @Override
    public void eat() {
    }

    @Override
    public void fly() {
    }
}

5. 類圖
在這裡插入圖片描述

5. 里氏替換原則

定義:

子類可以擴充套件父類的功能,但不能改變父類原有的功能

優點:

  1. 約束繼承氾濫,開閉原則的一種體現
  2. 加強程式的健壯性,同時變更時也可以做好很好的相容性
  3. 提高程式的可維護性,擴充套件性,
  4. 降低需求變更引入的風險

示例

待更新

6. 迪米特法則

定義

一個物件應該對其他物件保持最少的瞭解,儘量減少類與類之間的耦合。

優點

降低類之間的耦合

示例

比如領導想知道課程的數量,可以去安排員工去檢視
1. 定義一個課程類

public class Course {

2. 定義一個員工類,員工持有並可以檢查課程數量

public class Employee {
	public void checkNumberOfCourse() {
		//模擬一下
		ArrayList<Course> courses = new ArrayList<Course>();
		for (int i = 0; i < 100; i++) {
			courses.add(new Course());
		}
		System.out.println("課程的數量為:" + courses.size());
	}
}

3. 領導想知道課程的數量,只需要讓員工去檢查即可

public class TeamLeader {
	public void commandCheckNumber (Employee employee) {
		employee.checkNumberOfCourse();
	}
}

4. 類圖
在這裡插入圖片描述

7. 合成複用原則

定義

儘量使用物件組合、聚合,而不是繼承關係達到軟體複用的目的

優點

可以使用系統更加靈活,降低類與類之間的耦合度
一個類的變化對其他類的影響相對叫小

示例

假設我們想要去連線資料庫,新增資料。
1. 抽象一個資料庫

public abstract class DBConnection {
	public String getConnection() {
		return null;}

2. 分別有MySQL資料庫和Oracle資料庫

public class MySQLConnection extends DBConnection {
	@Override
	public String getConnection() {
		return "獲取MySQL連線";
	}
}

public class OracleConnection extends DBConnection {
	@Override
	public String getConnection() {
		return "獲取Oracle連線";

3. 我們要獲取資料庫連線的時候,只需要持有他們共同的介面後者抽象類即可

public class ProductDao {
	private String dbConnection;
 
 	void setConnection(DBConnection dbConnection) {
		this.dbConnection = dbConnection.getConnection();
	}
	void addProduct() {
		System.out.println(dbConnection);
	}
}

4. 類圖
在這裡插入圖片描述

相關文章