成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

基于 TypeScript 理解程序設計的 SOLID 原則

開發
TypeScript 的出現讓我們可以用面向對象的思想編寫出更簡潔的 JavaScript 代碼,在下面的文章中,我們將用 TypeScript 編寫一些示例來分別解釋下這些原則。

大家好,我是 ConardLi,今天我們來基于 TypeScript 回顧學習下程序設計中的 SOLID 原則。

說到 SOLID 原則,可能寫過代碼的同學們應該都聽過吧,這是程序設計領域最常用到的設計原則。SOLID 由 羅伯特·C·馬丁 在 21 世紀早期引入,指代了面向對象編程和面向對象設計的五個基本原則, SOLID 其實是以下五個單詞的縮寫:

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

TypeScript 的出現讓我們可以用面向對象的思想編寫出更簡潔的 JavaScript 代碼,在下面的文章中,我們將用 TypeScript 編寫一些示例來分別解釋下這些原則。

單一職責原則(SRP)

核心思想:類的職責應該單一,不要承擔過多的職責。

我們先看看下面這段代碼,我們為 Book 創建了一個類,但是類中卻承擔了多個職責,比如把書保存為一個文件:

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
}
}

遵循單一職責原則,我們應該創建兩個類,分別負責不同的事情:

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
}
}

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

開閉原則(OCP)

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

先看看下面這段寫的不太好的代碼,我們單獨封裝了一個 AreaCalculator 類來負責計算 Rectangle 和 Circle 類的面積。想象一下,如果我們后續要再添加一個形狀,我們要創建一個新的類,同時我們也要去修改 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 的接口,每個形狀類(矩形、圓形等)都可以通過實現它來依賴該接口。通過這種方式,我們可以將 AreaCalculator 類簡化為一個帶有參數的函數,每當我們創建一個新的形狀類,都必須實現這個函數,這樣就不需要修改原有的類了:

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)

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

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

先來看看下面這段代碼,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;
}
}

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;
}
}

好處:增強程序的健壯性,即使增加了子類,原有的子類還可以繼續運行。

接口隔離原則(ISP)

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

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

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 類只需要依賴于我們實際需要的這些接口。

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)

核心思想:依賴一個抽象的服務接口,而不是去依賴一個具體的服務執行者,從依賴具體實現轉向到依賴抽象接口,倒置過來。

看看下面這段代碼,我們有一個 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();
}
}

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

我們不需要在 SoftwareProject 類中以單一方式初始化 FrontendDeveloper 和 BackendDeveloper,而是將它們作為一個列表來遍歷它們,分別調用每個 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();
});
}
}

好處:實現模塊間的松耦合,更利于多模塊并行開發。

責任編輯:趙寧寧 來源: code秘密花園
相關推薦

2021-02-11 08:59:37

SOLID模塊倒置原則

2012-05-08 10:14:45

設計原則

2012-06-07 10:11:01

面向對象設計原則Java

2017-10-24 15:28:27

PHP代碼簡潔SOLID原則

2009-01-18 09:11:16

JavaIDLJava分布式程序設計

2022-09-27 09:21:34

SOLID開閉原則Go

2022-07-15 09:01:15

React對象編程

2011-07-29 17:36:25

程序員

2013-12-12 16:30:20

Lua腳本語言

2020-05-14 09:15:52

設計模式SOLID 原則JS

2024-09-30 11:51:07

2012-03-13 09:24:30

Java

2009-12-04 10:53:06

VS WEB

2010-12-28 10:12:39

PHP

2023-10-09 18:52:14

SOLIDJava

2011-07-05 16:05:43

面向對象編程

2009-06-23 17:52:04

Linux程序設計

2009-06-23 18:13:21

2011-07-05 15:22:04

程序設計

2011-07-05 15:59:57

面向對象編程
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 国产美女在线免费观看 | 欧洲尺码日本国产精品 | 在线午夜| 精品久久久久久久久亚洲 | 日本a视频 | 久久久久99| 日本一区不卡 | 国产一区二区不卡 | 国产成人99久久亚洲综合精品 | 国产欧美日韩在线一区 | 中文字幕电影在线观看 | 久久这里有精品 | 国产99小视频 | 欧美精品在线播放 | 91欧美激情一区二区三区成人 | 国产精品不卡一区二区三区 | 久久精品欧美电影 | 欧州一区 | 国产精品成人一区二区 | 久久成人精品一区二区三区 | 国产综合久久久 | 这里只有精品99re | 爱操影视 | 欧美色综合一区二区三区 | 日本又色又爽又黄的大片 | 亚洲国产成人av好男人在线观看 | 久久人人爽人人爽 | 日韩成人免费视频 | 一区二区免费看 | 涩在线 | 日韩电影一区二区三区 | 久久精品色欧美aⅴ一区二区 | 超碰在线观看97 | 九九精品网 | 女人牲交视频一级毛片 | 国产一区| 国产成人久久精品一区二区三区 | www.狠狠干| 欧美成人免费在线 | 一区二区三区久久久 | 日日操夜夜操天天操 |