很多人在初入行業(yè)的時(shí)候温峭,喜歡走到哪寫到哪,隨手一時(shí)爽识颊,一直隨手一直爽诚镰,重構(gòu)直接火葬場(chǎng)奕坟。很多人會(huì)搬出來單一職責(zé)或者其他設(shè)計(jì)原理或者設(shè)計(jì)模式來給你解釋祥款,當(dāng)然,本期不講這些月杉。我們來聊一聊:展示組件和容器組件刃跛。
又是一個(gè)晴朗的周末,爬起來已經(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');
})();
看起來這樣就可以輕松的收拾房間了呢,但是馍驯,好像地面需要打掃阁危,我還需要掃地、拖地汰瘫。
突然狂打,我放佛覺得哪里不對(duì)勁,什么都要我干混弥,老子那個(gè)破掃地機(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(['廚房', '臥室', '洗手間', '陽(yáng)臺(tái)']);
console.log('My room is clean');
})();
看起來真不錯(cuò)官辽,回過頭,我們看看整個(gè)過程粟瞬,我們?cè)谥魅肟谑紫劝盐锲氛砹送停缓笳{(diào)用robotClean
方法清理了廚房、臥室裙品、洗手間俗批、陽(yáng)臺(tái)四個(gè)地方,我的房間終于干凈了市怎。
看起來岁忘,這很符合邏輯,先收拾房間嘛区匠,收拾完之后干像,發(fā)現(xiàn)房間太臟了,要掃地拖地驰弄,我就創(chuàng)建一個(gè)掃地機(jī)器人麻汰,替我干活就好了。
回歸引言:隨手一時(shí)爽戚篙,一直隨手一直爽五鲫,重構(gòu)直接火葬場(chǎng)。
很奇怪岔擂,我們按照正常的邏輯位喂,哪里不對(duì)呢?不對(duì)乱灵,不對(duì)大發(fā)了塑崖。
看似都狠符合邏輯,但是這是人的邏輯痛倚,不是機(jī)器的邏輯规婆,在機(jī)器的世界里,他需要一個(gè)抽象的状原,秩序凌然的世界聋呢。房間就是用來展示,房間不會(huì)自己打掃自己颠区,打掃的只能是工具人削锰。工具人要分開,比如我就可以收拾衣服毕莱、收拾書器贩、收拾電腦颅夺,而我的掃地機(jī)器人就會(huì)打掃指定區(qū)域。
那么這樣做還有其他好處嗎蛹稍?有吧黄,當(dāng)有人接手你的代碼的時(shí)候,你希望別人上來就是一句“f**k”嗎唆姐?混亂的代碼拗慨,會(huì)意味著你的邏輯也是混亂的,也就是你在寫這塊的時(shí)候奉芦,并沒有想好要怎么做要做什么赵抢。通往高級(jí)的一個(gè)重要點(diǎn)就是需要有代碼設(shè)計(jì)能力,這個(gè)設(shè)計(jì)可以通俗的理解成抽象能力声功。
那么讓我們烦却,提升抽象能力,開啟新的篇章先巴,向高級(jí)邁進(jìn)其爵!
按例:(先來介紹展示組件和容器組件)
Presentational components are concerned with how things look.
展示組件關(guān)注事物的外觀
Container components are concerned with how things work.
容器組件關(guān)注事物如何工作
很多人會(huì)好奇,這不是 React 老生常談的伸蚯,拆分組件要注意展示組件和容器組件嘛摩渺?關(guān)我們寫函數(shù)有啥關(guān)系。其實(shí)不然朝卒,展示和容器其實(shí)追溯應(yīng)該回歸到mvc體系证逻,我們應(yīng)該活用這樣的思想去整理自己的代碼乐埠,分析一下我們打掃房間這個(gè)過程抗斤。
- 房間僅做展示效果,無論是臟亂丈咐,還是干凈整潔瑞眼。
- 我可以收拾衣服、書棵逊、電腦伤疙,講他們放到原位。
- 斯沃特機(jī)器人可以幫我打掃房間辆影。
抽象出三個(gè)模塊徒像,我、機(jī)器人蛙讥、房間锯蛀,我和機(jī)器人注重的是工作,房間注重的展示次慢,畢竟她還不是一個(gè)成熟的房間旁涤,不會(huì)自己打掃翔曲。
首先創(chuàng)建一個(gè)PersonClass
這個(gè)類是抽象類,包含基本功能劈愚,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)了本寶寶雖然是個(gè)寶寶但是還是個(gè)人這個(gè)事實(shí)菌羽,我決定掠械,需要實(shí)現(xiàn)一個(gè)PersonClass
類,然后我去繼承一下注祖,但是我這個(gè)人比較厲害份蝴,我不是只能干一件事,我可以按照隊(duì)列執(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ù)我們搞一個(gè)機(jī)器人類婚夫,機(jī)器人類也是一個(gè)抽象類,當(dāng)然和我們?nèi)祟愐膊畈欢嗍鸺Γ灿幸粋€(gè)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)建一個(gè)掃地機(jī)器人類來繼承機(jī)器人類,掃地機(jī)器人就是需要一個(gè)區(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);
}
}
好了,既然兩個(gè)“工具人”都搞定了炉抒,我們就來搞一搞我們的展示組件奢讨,展示組件需要的就是進(jìn)行房間初始化,當(dāng)房間在創(chuàng)建的時(shí)候焰薄,就有一個(gè)待打掃隊(duì)列拿诸,比如packedEventQueue
待收拾事件隊(duì)列以及cleanedRange
待清潔區(qū)域,在渲染render
的時(shí)候塞茅,首先檢查一下頁(yè)面清理狀態(tài)亩码,然后根據(jù)狀態(tài)告訴大家,是否干凈野瘦。本身是不會(huì)與外界有任何交互描沟,僅會(huì)提供一些方法出去,交給外部去處理鞭光。換句話就是吏廉,作為一個(gè)不成熟的RoomClass
,她是不會(huì)自己打掃自己的惰许,她也不管到底是誰打掃席覆,總之,她里面就是包含待收拾事件隊(duì)列以及待清潔區(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 = ['廚房', '洗手間', '客廳', '陽(yáng)臺(tái)'];
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ù)清晰明了,我們的各大工具人也分工明確障斋,做著他們工具人的本分纵潦,而我們的展示組件,也在盡心盡力的展示著我房間從臟亂到干凈的過程垃环。
請(qǐng)注意邀层,不是任何情況都要有展示組件,展示組件也不是一定不能做任何的邏輯遂庄,只是展示組件不對(duì)外做任何處理寥院。
打掃完了房間,朋友們也差不多到了涛目,我們 high 了一晚秸谢,結(jié)果,第二天我醒來之后霹肝,又是臟亂的房間估蹄。
啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊
我是 ihap 肥少,喜歡我的文章沫换,請(qǐng)關(guān)注喲臭蚁。我們是 ihap 技術(shù)黑洞,更多咨詢讯赏、擼貓一手資料垮兑,快關(guān)注吧!
參考文獻(xiàn):