各司其職,讓你的世界秩序凌然

很多人在初入行業(yè)的時候,喜歡走到哪寫到哪,隨手一時爽,一直隨手一直爽,重構(gòu)直接火葬場。很多人會搬出來單一職責(zé)或者其他設(shè)計原理或者設(shè)計模式來給你解釋,當(dāng)然,本期不講這些。我們來聊一聊:展示組件和容器組件。

又是一個晴朗的周末,爬起來已經(jīng)中午了,突然發(fā)現(xiàn)身邊亂糟糟的,書啊,衣服啊,電腦啊丟的到處都是。今天還有人來家里進(jìn)行友好訪問(俗稱過來白嫖一頓飯),這么亂可不行,那么稍微起來收拾收拾吧。

// example .01 code
const clean = good => {
  if (good === 'clothes') {
    return 'My clothes are in the closet';
  } else if (good === 'book') {
    return 'My book is in the bookcase';
  } else if (good === 'laptop') {
    return 'My laptop is on the desk';
  } else {
    return false;
  }
};

const goodsInRoom = ['clothes', 'book', 'laptop'];

(() => {
  goodsInRoom.forEach(good => {
    const result = clean(good);
    console.log(result ? result : `${good} is not clean`);
  });
  console.log('My room is clean');
})();

看起來這樣就可以輕松的收拾房間了呢,但是,好像地面需要打掃,我還需要掃地、拖地。

突然,我放佛覺得哪里不對勁,什么都要我干,老子那個破掃地機(jī)器人,買了當(dāng)大爺嗎?不行,我需要讓他也干活。

class SweepingRobot {
    #range = [];

    constructor(name) {
        this.name = name;
    }

    setRange(range) {
        this.#range = range;
    }

    clean() {
        this.#range.forEach(range => {
            console.log(`${this.name} -> ${range}: start to clean`);
        );
    }
}

const robotClean = range => {
    const sweepingRobot = new SweepingRobot('斯沃特機(jī)器人');
    sweepingRobot.setRange(range);
    sweepingRobot.clean();
};

// ... example .01 code here ...

(() => {
    goodsInRoom.forEach(good => {
        const result = clean(good);
        console.log(result ? result : `${good} is not clean`);
    });

    robotClean(['廚房', '臥室', '洗手間', '陽臺']);
    console.log('My room is clean');
})();

看起來真不錯,回過頭,我們看看整個過程,我們在主入口首先把物品整理了,然后調(diào)用robotClean方法清理了廚房、臥室、洗手間、陽臺四個地方,我的房間終于干凈了。

看起來,這很符合邏輯,先收拾房間嘛,收拾完之后,發(fā)現(xiàn)房間太臟了,要掃地拖地,我就創(chuàng)建一個掃地機(jī)器人,替我干活就好了。

回歸引言:隨手一時爽,一直隨手一直爽,重構(gòu)直接火葬場。

很奇怪,我們按照正常的邏輯,哪里不對呢?不對,不對大發(fā)了。

看似都狠符合邏輯,但是這是人的邏輯,不是機(jī)器的邏輯,在機(jī)器的世界里,他需要一個抽象的,秩序凌然的世界。房間就是用來展示,房間不會自己打掃自己,打掃的只能是工具人。工具人要分開,比如我就可以收拾衣服、收拾書、收拾電腦,而我的掃地機(jī)器人就會打掃指定區(qū)域。

那么這樣做還有其他好處嗎?有,當(dāng)有人接手你的代碼的時候,你希望別人上來就是一句“f**k”嗎?混亂的代碼,會意味著你的邏輯也是混亂的,也就是你在寫這塊的時候,并沒有想好要怎么做要做什么。通往高級的一個重要點(diǎn)就是需要有代碼設(shè)計能力,這個設(shè)計可以通俗的理解成抽象能力。

那么讓我們,提升抽象能力,開啟新的篇章,向高級邁進(jìn)!

按例:(先來介紹展示組件和容器組件)

Presentational components are concerned with how things look.展示組件關(guān)注事物的外觀

Container components are concerned with how things work.容器組件關(guān)注事物如何工作

很多人會好奇,這不是 React 老生常談的,拆分組件要注意展示組件和容器組件嘛?關(guān)我們寫函數(shù)有啥關(guān)系。其實不然,展示和容器其實追溯應(yīng)該回歸到mvc體系,我們應(yīng)該活用這樣的思想去整理自己的代碼,分析一下我們打掃房間這個過程。

  1. 房間僅做展示效果,無論是臟亂,還是干凈整潔。
  2. 我可以收拾衣服、書、電腦,講他們放到原位。
  3. 斯沃特機(jī)器人可以幫我打掃房間。

抽象出三個模塊,我、機(jī)器人、房間,我和機(jī)器人注重的是工作,房間注重的展示,畢竟她還不是一個成熟的房間,不會自己打掃。

首先創(chuàng)建一個PersonClass這個類是抽象類,包含基本功能,clean方法,用來收拾指定的事件。

// PersonClass
class PersonClass {
  #name = '';

  constructor(name) {
    this.#name = name;
  }

  getName() {
    return this.#name;
  }

  clean(event) {
    console.log(`${this.#name} packed up ${event}`);
  }
}

在確認(rèn)了本寶寶雖然是個寶寶但是還是個人這個事實,我決定,需要實現(xiàn)一個PersonClass類,然后我去繼承一下,但是我這個人比較厲害,我不是只能干一件事,我可以按照隊列執(zhí)行任務(wù)。

// IhapMrFatClass
class IhapMrFatClass extends PersonClass {
  #room = '';
  #packedEventQueue = [];

  constructor(name, room) {
    super(name);
    this.#room = room;
    this.#packedEventQueue = room.getPackedEventQueue();
  }

  clean() {
    let event = '';
    while ((event = this.#packedEventQueue.shift())) {
      super.clean(event);
    }
    this.#room.setPackedEventQueue(this.#packedEventQueue);
  }
}

繼續(xù)我們搞一個機(jī)器人類,機(jī)器人類也是一個抽象類,當(dāng)然和我們?nèi)祟愐膊畈欢?,也有一個clean方法。

// RobotClass
class RobotClass {
  #name = '機(jī)器人';

  constructor(name) {
    this.#name = name;
  }

  getName() {
    return this.#name;
  }

  clean(range) {
    console.log(`${this.#name} -> ${range}: cleaned`);
  }
}

接下來創(chuàng)建一個掃地機(jī)器人類來繼承機(jī)器人類,掃地機(jī)器人就是需要一個區(qū)域范圍,然后在區(qū)域范圍內(nèi)打掃。

// SweepRobotClass
class SweepRobotClass extends RobotClass {
  #room = '';
  #cleanedRange = [];

  constructor(name, room) {
    super(name);
    this.#room = room;
    this.#cleanedRange = room.getCleanedRange();
  }

  clean() {
    let range = '';
    while ((range = this.#cleanedRange.shift())) {
      super.clean(range);
    }
    this.#room.setCleanedRange(this.#cleanedRange);
  }
}

好了,既然兩個“工具人”都搞定了,我們就來搞一搞我們的展示組件,展示組件需要的就是進(jìn)行房間初始化,當(dāng)房間在創(chuàng)建的時候,就有一個待打掃隊列,比如packedEventQueue待收拾事件隊列以及cleanedRange待清潔區(qū)域,在渲染render的時候,首先檢查一下頁面清理狀態(tài),然后根據(jù)狀態(tài)告訴大家,是否干凈。本身是不會與外界有任何交互,僅會提供一些方法出去,交給外部去處理。換句話就是,作為一個不成熟的RoomClass,她是不會自己打掃自己的,她也不管到底是誰打掃,總之,她里面就是包含待收拾事件隊列以及待清潔區(qū)域,只要打掃干凈了,她就認(rèn)為干凈了。

// RoomClass
class RoomClass {
  #packedEventQueue = [];
  #cleanedRange = [];
  #clearStatus = false;

  constructor(initStatus) {
    const { packedEventQueue, cleanedRange } = initStatus;
    this.#packedEventQueue = packedEventQueue;
    this.#cleanedRange = cleanedRange;
  }

  setPackedEventQueue(packedEventQueue) {
    this.#packedEventQueue = packedEventQueue;
  }
  getPackedEventQueue() {
    return this.#packedEventQueue;
  }

  setCleanedRange(cleanedRange) {
    this.#cleanedRange = cleanedRange;
  }
  getCleanedRange() {
    return this.#cleanedRange;
  }

  _checkClearStatus() {
    this.#clearStatus = !(this.#packedEventQueue.length || this.#cleanedRange.length);
  }

  render() {
    this._checkClearStatus();
    console.log(this.#clearStatus ? '干凈的房間' : '臟亂的房間');
  }
}

好了,讓我們用起來吧

const packedEventQueue = ['clothes', 'book', 'laptop'];
const cleanedRange = ['廚房', '洗手間', '客廳', '陽臺'];

const ihapMrFatRoom = new RoomClass({ packedEventQueue, cleanedRange });
ihapMrFatRoom.render();
// 臟亂的房間

const ihapMrFat = new IhapMrFatClass('ihap 肥少', ihapMrFatRoom);
ihapMrFat.clean();

const sweepRobot = new SweepRobotClass('掃地機(jī)器人', ihapMrFatRoom);
sweepRobot.clean();

ihapMrFatRoom.render();
// 干凈的房間

這樣,主函數(shù)是不是很清晰明了了呢,不光我們的主函數(shù)清晰明了,我們的各大工具人也分工明確,做著他們工具人的本分,而我們的展示組件,也在盡心盡力的展示著我房間從臟亂到干凈的過程。

請注意,不是任何情況都要有展示組件,展示組件也不是一定不能做任何的邏輯,只是展示組件不對外做任何處理。

打掃完了房間,朋友們也差不多到了,我們 high 了一晚,結(jié)果,第二天我醒來之后,又是臟亂的房間。

啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊

我是 ihap 肥少,喜歡我的文章,請關(guān)注喲。我們是 ihap 技術(shù)黑洞,更多咨詢、擼貓一手資料,快關(guān)注吧!

參考文獻(xiàn):

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容