每天一個設計模式之組合模式

作者按:《每天一個設計模式》旨在初步領會設計模式的精髓,目前採用javascriptpython兩種語言實現。誠然,每種設計模式都有多種實現方式,但此小冊只記錄最直截了當的實現方式 :)

原文地址是:《每天一個設計模式之組合模式》

歡迎關注個人技術博客:godbmw.com。每週 1 篇原創技術分享!開源教程(webpack、設計模式)、面試刷題(偏前端)、知識整理(每週零碎),歡迎長期關注!

如果您也想進行知識整理 + 搭建功能完善/設計簡約/快速啓動的個人博客,請直接戳theme-bmw

0. 項目地址

1. 什麼是“組合模式”?

組合模式,將對象組合成樹形結構以表示“部分-整體”的層次結構。
  1. 用小的子對象構造更大的父對象,而這些子對象也由更小的子對象構成
  2. 單個對象和組合對象對於用戶暴露的接口具有一致性,而同種接口不同表現形式亦體現了多態性

2. 應用場景

組合模式可以在需要針對“樹形結構”進行操作的應用中使用,例如掃描文件夾、渲染網站導航結構等等。

3. 代碼實現

這裏用代碼模擬文件掃描功能,封裝了FileFolder兩個類。在組合模式下,用戶可以向Folder類嵌套File或者Folder來模擬真實的“文件目錄”的樹結構。

同時,兩個類都對外提供了scan接口,File下的scan是掃描文件,Folder下的scan是調用子文件夾和子文件的scan方法。整個過程採用的是深度優先

3.1 python3 實現

class File:  # 文件類
    def __init__(self, name):
        self.name = name

    def add(self):
        raise NotImplementedError()

    def scan(self):
        print('掃描文件:' + self.name)


class Folder:  # 文件夾類
    def __init__(self, name):
        self.name = name
        self.files = []

    def add(self, file):
        self.files.append(file)

    def scan(self):
        print('掃描文件夾: ' + self.name)
        for item in self.files:
            item.scan()


if __name__ == '__main__':

    home = Folder("用戶根目錄")

    folder1 = Folder("第一個文件夾")
    folder2 = Folder("第二個文件夾")

    file1 = File("1號文件")
    file2 = File("2號文件")
    file3 = File("3號文件")

    # 將文件添加到對應文件夾中
    folder1.add(file1)

    folder2.add(file2)
    folder2.add(file3)

    # 將文件夾添加到更高級的目錄文件夾中
    home.add(folder1)
    home.add(folder2)

    # 掃描目錄文件夾
    home.scan()

執行$ python main.py, 最終輸出結果是:

掃描文件夾: 用戶根目錄
掃描文件夾: 第一個文件夾
掃描文件:1號文件
掃描文件夾: 第二個文件夾
掃描文件:2號文件
掃描文件:3號文件

3.2 ES6 實現

// 文件類
class File {
  constructor(name) {
    this.name = name || "File";
  }

  add() {
    throw new Error("文件夾下面不能添加文件");
  }

  scan() {
    console.log("掃描文件: " + this.name);
  }
}

// 文件夾類
class Folder {
  constructor(name) {
    this.name = name || "Folder";
    this.files = [];
  }

  add(file) {
    this.files.push(file);
  }

  scan() {
    console.log("掃描文件夾: " + this.name);
    for (let file of this.files) {
      file.scan();
    }
  }
}

let home = new Folder("用戶根目錄");

let folder1 = new Folder("第一個文件夾"),
  folder2 = new Folder("第二個文件夾");

let file1 = new File("1號文件"),
  file2 = new File("2號文件"),
  file3 = new File("3號文件");

// 將文件添加到對應文件夾中
folder1.add(file1);

folder2.add(file2);
folder2.add(file3);

// 將文件夾添加到更高級的目錄文件夾中
home.add(folder1);
home.add(folder2);

// 掃描目錄文件夾
home.scan();

執行$ node main.js,最終輸出結果是:

掃描文件夾: 用戶根目錄
掃描文件夾: 第一個文件夾
掃描文件: 1號文件
掃描文件夾: 第二個文件夾
掃描文件: 2號文件
掃描文件: 3號文件

4. 參考

  • 《JavaScript 設計模式和開發實踐》
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章