国产精品电影_久久视频免费_欧美日韩国产激情_成年人视频免费在线播放_日本久久亚洲电影_久久都是精品_66av99_九色精品美女在线_蜜臀a∨国产成人精品_冲田杏梨av在线_欧美精品在线一区二区三区_麻豆mv在线看

前端的設計模式系列-裝飾器模式

開發 項目管理
代碼也寫了幾年了,設計模式處于看了忘,忘了看的狀態,最近對設計模式有了點感覺,索性就再學習總結下吧。

代碼也寫了幾年了,設計模式處于看了忘,忘了看的狀態,最近對設計模式有了點感覺,索性就再學習總結下吧。

大部分講設計模式的文章都是使用的 Java、C++ 這樣的以類為基礎的靜態類型語言,作為前端開發者,js 這門基于原型的動態語言,函數成為了一等公民,在實現一些設計模式上稍顯不同,甚至簡單到不像使用了設計模式,有時候也會產生些困惑。

下面按照「場景」-「設計模式定義」- 「代碼實現」- 「易混設計模式」-「總」的順序來總結一下,如有不當之處,歡迎交流討論。

場景

微信小程序定義一個頁面是通過微信提供的Page 方法,然后傳入一個配置對象進去。

Page({
data: { // 參與頁面渲染的數據
logs: []
},
onLoad: function () {
// 頁面渲染后 執行
}
})

如果我們有個需求是在每個頁面加載的時候上報一些自定義數據。

最直接的當然是去每個頁面加就好了,但上報數據的邏輯是一致的,一個一個加有些傻了,這里就可以用到裝飾器模式了。

裝飾器模式

看下維基百科的定義。

裝飾器(修飾)模式,是面向對象程式領域中,一種動態地往一個類別中添加新的行為的設計模式。就功能而言,修飾模式相比生成子類別更為靈活,這樣可以給某個對象而不是整個類別添加一些功能。

看一下 UML 類圖和次序圖。

當訪問 Component1 中的operation 方法時,會先調用預先定義的兩個裝飾器 Decorator1 和 Decorator2 中的 operation 方法,執行一些額外操作,最后再執行原始的 operation 方法。

舉一個簡單的例子:

買奶茶的話可以額外加珍珠、椰果等,不同小料有不同的價格、也可以自由組合,此時就可以用到裝飾器模式,對原始奶茶進行加料、算價。

原始的奶茶有一個接口和類。

interface MilkTea {
public double getCost(); // 返回奶茶的價格
public String getIngredients(); // 返回奶茶的原料
}

class SimpleMilkTea implements MilkTea {
@Override
public double getCost() {
return 10;
}

@Override
public String getIngredients() {
return "MilkTea";
}
}

下邊引入裝飾器,進行加料。

// 添加一個裝飾器的抽象類
abstract class MilkTeaDecorator implements MilkTea {
private final MilkTea decoratedMilkTea;

public MilkTeaDecorator(MilkTea c) {
this.decoratedMilkTea = c;
}

@Override
public double getCost() {
return decoratedMilkTea.getCost();
}

@Override
public String getIngredients() {
return decoratedMilkTea.getIngredients();
}
}

// 添加珍珠
class WithPearl extends MilkTeaDecorator {
public WithPearl(MilkTea c) {
super(c); // 調用父類構造函數
}

@Override
public double getCost() {
// 調用父類方法
return super.getCost() + 2;
}

@Override
public String getIngredients() {
// 調用父類方法
return super.getIngredients() + ", 加珍珠";
}
}

// 添加椰果
class WithCoconut extends MilkTeaDecorator {
public WithCoconut(MilkTea c) {
super(c);
}

@Override
public double getCost() {
return super.getCost() + 1;
}

@Override
public String getIngredients() {
return super.getIngredients() + ", 加椰果";
}
}

讓我們測試一下,

public class Main {
public static void printInfo(MilkTea c) {
System.out.println("價格: " + c.getCost() + "; 加料: " + c.getIngredients());
}

public static void main(String[] args) {
MilkTea c = new SimpleMilkTea();
printInfo(c); // 價格: 10.0; 加料: MilkTea

c = new WithPearl(new SimpleMilkTea());
printInfo(c); // 價格: 12.0; 加料: MilkTea, 加珍珠

c = new WithCoconut(new WithPearl(new SimpleMilkTea()));
printInfo(c); // 價格: 13.0; 加料: MilkTea, 加珍珠, 加椰果
}
}

未來如果需要新增一種小料,只需要新寫一個裝飾器類,并且可以和之前的小料隨意搭配。

// 添加冰淇淋
class WithCream extends MilkTeaDecorator {
public WithCream(MilkTea c) {
super(c);
}

@Override
public double getCost() {
return super.getCost() + 5;
}

@Override
public String getIngredients() {
return super.getIngredients() + ", 加冰淇淋";
}
}

public class Main {
public static void printInfo(MilkTea c) {
System.out.println("價格: " + c.getCost() + "; 加料: " + c.getIngredients());
}

public static void main(String[] args) {
c = new WithCoconut(new WithCream(new WithPearl(new SimpleMilkTea())));
printInfo(c); // 價格: 18.0; 加料: MilkTea, 加珍珠, 加冰淇淋, 加椰果
}
}

讓我們用 js 改寫一下,達到同樣的效果。

const SimpleMilkTea = () => {
return {
getCost() {
return 10;
},

getIngredients() {
return "MilkTea";
},
};
};

// 加珍珠
const WithPearl = (milkTea) => {
return {
getCost() {
return milkTea.getCost() + 2;
},

getIngredients() {
return milkTea.getIngredients() + ", 加珍珠";
},
};
};

// 加椰果
const WithCoconut = (milkTea) => {
return {
getCost() {
return milkTea.getCost() + 1;
},

getIngredients() {
return milkTea.getIngredients() + ", 加椰果";
},
};
};

// 加冰淇淋
const WithCream = (milkTea) => {
return {
getCost() {
return milkTea.getCost() + 5;
},

getIngredients() {
return milkTea.getIngredients() + ", 加冰淇淋";
},
};
};

// test
const printInfo = (c) => {
console.log(
"價格: " + c.getCost() + "; 加料: " + c.getIngredients()
);
};

let c = SimpleMilkTea();
printInfo(c); // 價格: 10; 加料: MilkTea

c = WithPearl(SimpleMilkTea());
printInfo(c); // 價格: 12; 加料: MilkTea, 加珍珠

c = WithCoconut(WithPearl(SimpleMilkTea()));
printInfo(c); // 價格: 13; 加料: MilkTea, 加珍珠, 加椰果

c = WithCoconut(WithCream(WithPearl(SimpleMilkTea())));
printInfo(c); // 價格: 18; 加料: MilkTea, 加珍珠, 加冰淇淋, 加椰果

沒有再定義類和接口,js 中用函數直接表示。

原始的 SimpleMilkTea 方法返回一個奶茶對象,然后又定義了三個裝飾函數,傳入一個奶茶對象,返回一個裝飾后的對象。

代碼實現

回到文章最開頭的場景,我們需要為每個頁面加載的時候上報一些自定義數據。其實我們只需要引入一個裝飾函數,將傳入的 option 進行裝飾返回即可。

const Base = (option) => {
const { onLoad ...rest } = option;
return {
...rest,
// 重寫 onLoad 方法
onLoad(...args) {
// 增加路由字段
this.reportData(); // 上報數據

// onLoad
if (typeof onLoad === 'function') {
onLoad.call(this, ...args);
}
}
reportData() {
// 做一些事情
}
}

然后回到原始頁面增加 Base 的調用即可。

Page(Base({
data: { // 參與頁面渲染的數據
logs: []
},
onLoad: function () {
// 頁面渲染后 執行
}
})

同理,利用裝飾器模式我們也可以對其它生命周期統一插入我們需要做的事情,而不需要業務方自己再寫一遍。

在大團隊的話,每個業務方可能都需要在小程序生命周期做一些事情,此時只需要利用裝飾器模式,編寫一個裝飾函數,然后在業務代碼中調用即可。

最終的業務代碼可能會裝飾很多層,最終才傳給小程序 Page 函數。

Page(Base(Log(Ce({
data: { // 參與頁面渲染的數據
logs: []
},
onLoad: function () {
// 頁面渲染后 執行
}
})

易混設計模式

如果之前看過代理模式,到這里可能會有一些困惑,因為和代理模式的作用很像,都是對原有對象進行包裝,增強原有對象。

但還是有很大的不同點:

代理模式中,我們是直接將原對象封裝到代理對象之中,對于業務方并不關系原始對象,直接使用代理對象即可。

裝飾器模式中,我們只提供了裝飾函數,輸入原始對象,輸出增強對象。輸出的增強對象,還可以接著傳入到新的裝飾器函數中繼續增強。對于業務方,可以隨意組合裝飾函數,但得有一個最最開始的原始對象。

再具體點:

代理模式的話,對象之間的依賴關系已經寫死了,原始對象 A,新增代理對象A1, A1 的基礎上再新增代理對象A2。如果我們不想要 A1 新增的功能了,我們并不能直接使用 A2 ,因為A2 已經包含了 A1 的功能,我們只能在 A 的基礎上再新寫一個代理對象A3。

而裝飾器模式,我們只提供裝飾函數A1,裝飾函數 A2,然后對原始對象進行裝飾 A2(A1(A))。如果不想要 A1新增的功能,只需要把 A1 這個裝飾器去掉,調用 A2(A) 即可。

所以使用代理模式還是使用裝飾器模式,取決于我們是要把所有功能包裝后最終產出一個對象給業務方使用,還是提供許多功能,讓業務方自由組合。

裝飾器模式同樣踐行了「單一職責原則」,可以把對象/函數的各個功能獨立出來,降低它們之間的耦合性。

業務開發中,如果某個對象/函數擁有了太多功能,可以考慮使用裝飾器模式進行拆分。


責任編輯:武曉燕 來源: windliang
相關推薦

2023-09-04 13:14:00

裝飾器設計模式

2023-12-13 13:28:16

裝飾器模式Python設計模式

2022-02-06 22:30:36

前端設計模式

2022-02-11 10:22:48

模版模式語言

2022-02-15 22:45:00

前端設計模式

2020-11-09 08:20:33

解釋器模式

2022-01-29 22:12:35

前端模式觀察者

2022-02-13 23:33:24

設計模式Java

2024-02-23 12:11:53

裝飾器模式對象

2021-06-22 15:27:13

設計模式迭代器模式Java

2020-12-01 07:16:05

重學設計模式

2022-03-25 11:01:28

Golang裝飾模式Go 語言

2020-11-03 13:05:18

命令模式

2020-11-04 08:54:54

狀態模式

2020-10-23 09:40:26

設計模式

2022-01-12 13:33:25

工廠模式設計

2020-11-06 09:01:46

迭代器模式

2020-10-20 13:33:00

建造者模式

2020-11-05 09:38:07

中介者模式

2021-10-28 19:09:09

模式原型Java
點贊
收藏

51CTO技術棧公眾號

一本色道久久综合亚洲精品不卡| 欧美最新精品| 久久久久久久久99精品大| 亚洲国产高清福利视频| 99视频在线免费| 99pao成人国产永久免费视频| 中文字幕av一区二区三区谷原希美 | 国产精品一区av| 日本精品裸体写真集在线观看| 亚洲国产sm捆绑调教视频| 日本香蕉视频在线观看| 伊人激情综合| 欧洲成人免费aa| 你懂得影院夜精品a| 欧美日韩国产区一| 偷偷要 色偷偷| 久久久精品一品道一区| 中文字幕色一区二区| 我不卡伦不卡影院| 欧美一性一乱一交一视频| 日本综合视频| 精品日韩一区二区| 日本视频在线观看| 色婷婷久久久综合中文字幕 | 亚洲va国产天堂va久久en| 国产免费黄色av| 国产在线视频不卡二| 国产欧美一区二区在线播放| 欧洲乱码伦视频免费| 国内精品久久久久久久| 免费视频成人| 伊人久久久久久久久久| 狂野欧美激情性xxxx欧美| 欧美午夜精品一区二区蜜桃| 91午夜在线| 亚洲免费色视频| 一本色道久久亚洲综合精品蜜桃| 不卡一区中文字幕| 成人一级生活片| 国产一区在线精品| 中文字幕av导航| 精品一二三四区| 亚洲一区二区高清视频| 日韩av网站免费在线| 亚洲黄色成人久久久| 全国精品久久少妇| 亚洲一区尤物| 国产精品123| 成人av在线播放观看| 国内精品在线播放| 欧美成人精品免费| 91麻豆产精品久久久久久| 国语对白做受xxxxx在线中国| 久久综合九色综合97婷婷| 国产综合免费视频| 久久久精品蜜桃| 免费yellow网站| 亚洲国产三级在线| 福利视频在线导航| 精品国产精品网麻豆系列| 女海盗2成人h版中文字幕| 亚洲欧美日韩视频一区| 在线观看欧美| 日韩av电影院| 欧美视频一区| 一级日韩一区在线观看| 成人午夜视频在线| 色悠悠久久综合网| 婷婷久久综合九色综合绿巨人| 日本福利在线观看| 日韩视频一区二区| 婷婷久久免费视频| 欧美影院在线播放| 国模 一区 二区 三区| 在线免费观看的av| 4p变态网欧美系列| 亚洲成人动漫av| 在线伊人免费视频| 欧美日韩亚洲综合一区| 麻豆福利在线观看| 中文字幕精品久久久久| 精品国产伦一区二区三区观看说明| 高清一区二区三区四区五区 | 一本高清dvd不卡在线观看| 免费黄色在线网站| 中文精品99久久国产香蕉| 丝袜美腿综合| 激情小说网站亚洲综合网 | 国产精品自产拍在线观看| 黄色综合网站| 永久免费网站视频在线观看| 国产精品婷婷午夜在线观看| 青青久草在线| 亚洲裸体xxxx| 国产欧美日韩免费观看| 精品一区二区三区日本| 久久久一区二区| 国产午夜在线观看| 色系列之999| 国内精品久久久久久久97牛牛| 国产欧美123| 午夜久久久久久久久| 小视频免费在线观看| 国产精品r级在线| 激情伊人五月天久久综合| 缴情综合网五月天| 亚洲国产成人91精品| 精品国产123区| 50度灰在线观看| 欧美性猛交xxxxx水多| 日韩成人精品一区二区三区| 国产另类自拍| 亚洲免费在线电影| 成人va天堂| 国产精品一级久久久| 国产精品免费视频网站| heyzo一区| 成人黄色激情网| 国产片一区二区| 一区二区乱码| 国产乱码精品一区二区三区日韩精品| 久久久亚洲午夜电影| 色综合999| 亚洲自拍av在线| 亚洲品质自拍视频| 涩涩涩久久久成人精品| 欧美12av| 精品久久久久久久久国产字幕| 一本一道久久a久久| 只有这里有精品| 3d成人动漫网站| 91精品蜜臀一区二区三区在线| 亚洲欧美自偷自拍另类| 中文字幕日韩欧美| 精品制服美女丁香| 天堂va在线| 成人av免费电影| 亚洲第一福利视频在线| 国产精品传媒| 116极品美女午夜一级| 亚洲欧美日韩在线高清直播| 日韩经典中文字幕一区| 日本免费在线观看| 国产精品免费一区二区三区在线观看 | 噼里啪啦在线中文观看| 欧美大片免费观看| 成人激情文学综合网| 亚洲小说区图片区都市| 国产欧美精品一区二区三区| 精品女厕一区二区三区| 西野翔中文久久精品字幕| 久久久精品三级| 久久夜色精品国产欧美乱| 国产成人av电影| 超碰aⅴ人人做人人爽欧美| 亚洲欧美99| 日韩av综合网站| 久久精品99国产精品日本| 日本理论片午伦夜理片在线观看| 国产精品 日韩| 精品久久久久久久中文字幕 | 91精品国模一区二区三区| 亚洲综合一二区| 韩国精品在线观看| 中文一区在线| 午夜免费高清视频| 3atv在线一区二区三区| 韩日成人av| 不卡在线视频| 国产精品区一区二区三在线播放 | 日韩高清有码在线| 麻豆91在线播放免费| av资源一区| 亚洲中文字幕无码一区二区三区 | 国产一区一区三区| 亚洲日韩第一页| 91在线观看高清| 白嫩白嫩国产精品| 五月天婷婷综合社区| 国产日韩欧美另类| 欧美美女直播网站| 毛片av一区二区| 成人mm视频在线观看| 国产一区亚洲二区三区| 欧美日韩国产成人高清视频| 亚洲精品国产高清久久伦理二区| 色狮一区二区三区四区视频| 中文字幕在线观看日本| 亚洲美女网站18| 欧美国产日韩在线| 黄色成人在线免费| 国产精品久久国产愉拍| 1区2区3区在线| 欧美 日韩精品| 国产精品 欧美在线| 欧美日韩卡一卡二| 国产精品亚洲午夜一区二区三区 | 7777精品久久久大香线蕉小说| 日韩欧美自拍偷拍| av一区二区三区四区|