日韩无码专区无码一级三级片|91人人爱网站中日韩无码电影|厨房大战丰满熟妇|AV高清无码在线免费观看|另类AV日韩少妇熟女|中文日本大黄一级黄色片|色情在线视频免费|亚洲成人特黄a片|黄片wwwav色图欧美|欧亚乱色一区二区三区

RELATEED CONSULTING
相關(guān)咨詢
選擇下列產(chǎn)品馬上在線溝通
服務(wù)時間:8:30-17:00
你可能遇到了下面的問題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營銷解決方案
基于TypeScript理解程序設(shè)計的SOLID原則

說到 SOLID 原則,可能寫過代碼的同學(xué)們應(yīng)該都聽過吧,這是程序設(shè)計領(lǐng)域最常用到的設(shè)計原則。SOLID 由 羅伯特·C·馬丁 在 21 世紀(jì)早期引入,指代了面向?qū)ο缶幊毯兔嫦驅(qū)ο笤O(shè)計的五個基本原則, SOLID 其實(shí)是以下五個單詞的縮寫:

網(wǎng)站建設(shè)哪家好,找成都創(chuàng)新互聯(lián)!專注于網(wǎng)頁設(shè)計、網(wǎng)站建設(shè)、微信開發(fā)、重慶小程序開發(fā)、集團(tuán)企業(yè)網(wǎng)站建設(shè)等服務(wù)項(xiàng)目。為回饋新老客戶創(chuàng)新互聯(lián)還提供了文成免費(fèi)建站歡迎大家使用!

  • Single Responsibility Principle:單一職責(zé)原則
  • Open Closed Principle:開閉原則
  • Liskov Substitution Principle:里氏替換原則
  • Interface Segregation Principle:接口隔離原則
  • Dependency Inversion Principle:依賴倒置原則

TypeScript 的出現(xiàn)讓我們可以用面向?qū)ο蟮乃枷刖帉懗龈啙嵉?JavaScript 代碼,在下面的文章中,我們將用 TypeScript 編寫一些示例來分別解釋下這些原則。

單一職責(zé)原則(SRP)

核心思想:類的職責(zé)應(yīng)該單一,不要承擔(dān)過多的職責(zé)。

我們先看看下面這段代碼,我們?yōu)?Book 創(chuàng)建了一個類,但是類中卻承擔(dān)了多個職責(zé),比如把書保存為一個文件:

class Book {
public title: string;
public author: string;
public description: string;
public pages: number;

// constructor and other methods

public saveToFile(): void {
// some fs.write method to save book to file
}
}

遵循單一職責(zé)原則,我們應(yīng)該創(chuàng)建兩個類,分別負(fù)責(zé)不同的事情:

class Book {
public title: string;
public author: string;
public description: string;
public pages: number;

// constructor and other methods
}

class Persistence {
public saveToFile(book: Book): void {
// some fs.write method to save book to file
}
}

好處:降低類的復(fù)雜度、提高可讀性、可維護(hù)性、擴(kuò)展性、最大限度的減少潛在的副作用。

開閉原則(OCP)

核心思想:類應(yīng)該對擴(kuò)展開放,但對修改關(guān)閉。簡單理解就是當(dāng)別人要修改軟件功能的時候,不能讓他修改我們原有代碼,盡量讓他在原有的基礎(chǔ)上做擴(kuò)展。

先看看下面這段寫的不太好的代碼,我們單獨(dú)封裝了一個 AreaCalculator 類來負(fù)責(zé)計算 Rectangle 和 Circle 類的面積。想象一下,如果我們后續(xù)要再添加一個形狀,我們要創(chuàng)建一個新的類,同時我們也要去修改 AreaCalculator 來計算新類的面積,這違反了開閉原則。

class Rectangle {
public width: number;
public height: number;

constructor(width: number, height: number) {
this.width = width;
this.height = height;
}
}

class Circle {
public radius: number;

constructor(radius: number) {
this.radius = radius;
}
}

class AreaCalculator {
public calculateRectangleArea(rectangle: Rectangle): number {
return rectangle.width * rectangle.height;
}

public calculateCircleArea(circle: Circle): number {
return Math.PI * (circle.radius * circle.radius);
}
}

為了遵循開閉原則,我們只需要添加一個名為 Shape 的接口,每個形狀類(矩形、圓形等)都可以通過實(shí)現(xiàn)它來依賴該接口。通過這種方式,我們可以將 AreaCalculator 類簡化為一個帶有參數(shù)的函數(shù),每當(dāng)我們創(chuàng)建一個新的形狀類,都必須實(shí)現(xiàn)這個函數(shù),這樣就不需要修改原有的類了:

interface Shape {
calculateArea(): number;
}

class Rectangle implements Shape {
public width: number;
public height: number;

constructor(width: number, height: number) {
this.width = width;
this.height = height;
}

public calculateArea(): number {
return this.width * this.height;
}
}

class Circle implements Shape {
public radius: number;

constructor(radius: number) {
this.radius = radius;
}

public calculateArea(): number {
return Math.PI * (this.radius * this.radius);
}
}

class AreaCalculator {
public calculateArea(shape: Shape): number {
return shape.calculateArea();
}
}

里氏替換原則(LSP)

核心思想:在使用基類的的地方可以任意使用其子類,能保證子類完美替換基類。簡單理解就是所有父類能出現(xiàn)的地方,子類就可以出現(xiàn),并且替換了也不會出現(xiàn)任何錯誤。

我們必須要求子類的所有相同方法,都必須遵循父類的約定,否則當(dāng)父類替換為子類時就會出錯。

先來看看下面這段代碼,Square 類擴(kuò)展了 Rectangle 類。但是這個擴(kuò)展沒有任何意義,因?yàn)槲覀兺ㄟ^覆蓋寬度和高度屬性來改變了原有的邏輯。

class Rectangle {
public width: number;
public height: number;

constructor(width: number, height: number) {
this.width = width;
this.height = height;
}

public calculateArea(): number {
return this.width * this.height;
}
}

class Square extends Rectangle {
public _width: number;
public _height: number;

constructor(width: number, height: number) {
super(width, height);

this._width = width;
this._height = height;
}
}

遵循里氏替換原則,我們不需要覆蓋基類的屬性,而是直接刪除掉 Square 類并,將它的邏輯帶到 Rectangle 類,而且也不改變其用途。

class Rectangle {
public width: number;
public height: number;

constructor(width: number, height: number) {
this.width = width;
this.height = height;
}

public calculateArea(): number {
return this.width * this.height;
}

public isSquare(): boolean {
return this.width === this.height;
}
}

好處:增強(qiáng)程序的健壯性,即使增加了子類,原有的子類還可以繼續(xù)運(yùn)行。

接口隔離原則(ISP)

核心思想:類間的依賴關(guān)系應(yīng)該建立在最小的接口上。簡單理解就是接口的內(nèi)容一定要盡可能地小,能有多小就多小。我們要為各個類建立專用的接口,而不要試圖去建立一個很龐大的接口供所有依賴它的類去調(diào)用。

看看下面的代碼,我們有一個名為 Troll 的類,它實(shí)現(xiàn)了一個名為 Character 的接口,但是 Troll 既不會游泳也不會說話,所以它似乎不太適合實(shí)現(xiàn)我們的接口:

interface Character {
shoot(): void;
swim(): void;
talk(): void;
dance(): void;
}

class Troll implements Character {
public shoot(): void {
// some method
}

public swim(): void {
// a troll can't swim
}

public talk(): void {
// a troll can't talk
}

public dance(): void {
// some method
}
}

遵循接口隔離原則,我們刪除 Character 接口并將它的功能拆分為四個接口,然后我們的 Troll 類只需要依賴于我們實(shí)際需要的這些接口。

interface Talker {
talk(): void;
}

interface Shooter {
shoot(): void;
}

interface Swimmer {
swim(): void;
}

interface Dancer {
dance(): void;
}

class Troll implements Shooter, Dancer {
public shoot(): void {
// some method
}

public dance(): void {
// some method
}
}

依賴倒置原則(DIP)

核心思想:依賴一個抽象的服務(wù)接口,而不是去依賴一個具體的服務(wù)執(zhí)行者,從依賴具體實(shí)現(xiàn)轉(zhuǎn)向到依賴抽象接口,倒置過來。

看看下面這段代碼,我們有一個 SoftwareProject 類,它初始化了 FrontendDeveloper 和 BackendDeveloper 類:

class FrontendDeveloper {
public writeHtmlCode(): void {
// some method
}
}

class BackendDeveloper {
public writeTypeScriptCode(): void {
// some method
}
}

class SoftwareProject {
public frontendDeveloper: FrontendDeveloper;
public backendDeveloper: BackendDeveloper;

constructor() {
this.frontendDeveloper = new FrontendDeveloper();
this.backendDeveloper = new BackendDeveloper();
}

public createProject(): void {
this.frontendDeveloper.writeHtmlCode();
this.backendDeveloper.writeTypeScriptCode();
}
}

遵循依賴倒置原則,我們創(chuàng)建一個 Developer 接口,由于 FrontendDeveloper 和 BackendDeveloper 是相似的類,它們都依賴于 Developer 接口。

我們不需要在 SoftwareProject 類中以單一方式初始化 FrontendDeveloper 和 BackendDeveloper,而是將它們作為一個列表來遍歷它們,分別調(diào)用每個 develop() 方法。

interface Developer {
develop(): void;
}

class FrontendDeveloper implements Developer {
public develop(): void {
this.writeHtmlCode();
}

private writeHtmlCode(): void {
// some method
}
}

class BackendDeveloper implements Developer {
public develop(): void {
this.writeTypeScriptCode();
}

private writeTypeScriptCode(): void {
// some method
}
}

class SoftwareProject {
public developers: Developer[];

public createProject(): void {
this.developers.forEach((developer: Developer) => {
developer.develop();
});
}
}

好處:實(shí)現(xiàn)模塊間的松耦合,更利于多模塊并行開發(fā)。


當(dāng)前標(biāo)題:基于TypeScript理解程序設(shè)計的SOLID原則
分享鏈接:http://www.5511xx.com/article/copcgcg.html