淺談前端出現(xiàn)率高的設計模式
點擊上方 前端Q,關注公眾號
回復加群,加入前端Q技術交流群
說到設計模式,大家想到的就是六大原則,23種模式。這么多模式,并非都要記住,但作為前端開發(fā),對于前端出現(xiàn)率高的設計模式還是有必要了解并掌握的,淺淺掌握9種模式后,整理了這份文章。
那么,我們先了解六大原則
六大原則:
-
依賴倒置原則(Dependence Inversion Principle):高層(業(yè)務層)不應該直接調用底層(基礎層)模塊 -
開閉原則(Open Close Principle):單模塊對拓展開放、對修改關閉 -
單一原則(Single Responsibility Principle):單模塊負責的職責必須是單一的 -
迪米特法則(Law of Demeter):對外暴露接口應該簡單 -
接口隔離原則(Interface Segregation Principle):單個接口(類)都應該按業(yè)務隔離開 -
里氏替換原則(Liskov Substitution Principle):子類可以替換父類
六大原則也可以用六個字替換:高內聚低耦合。
高層不直接依賴底層:依賴倒置原則 內部修改關閉,外部開放擴展:開閉原則 聚合單一功能:單一原則 低知識接口,對外接口簡單:迪米特法則 耦合多個接口,不如隔離拆分:接口隔離原則 合并復用,子類可以替換父類:里氏替換原則
我們采用模式編寫時,要盡可能遵守這六大原則
23 種設計模式分為“創(chuàng)建型”、“行為型”和“結構型”
前端九種設計模式
一、創(chuàng)建型
創(chuàng)建型從功能上來說就是創(chuàng)建元素,目標是規(guī)范元素創(chuàng)建步驟
1.構造器模式:抽象了對象實例的變與不變(變的是屬性值,不變的是屬性名)
js
復制代碼
// 需求:給公司員工創(chuàng)建線上基本信息
// 單個員工創(chuàng)建,可以直接使用創(chuàng)建
const obj = {
name:'張三',
age:'20',
department:'人力資源部門'
}
// 可員工的數(shù)量過于多的時候,一個個創(chuàng)建不可行,那么就可以使用構造器模式
class Person {
constructor(obj){
this.name = obj.name
this.age = obj.age
this.department = obj.department
}
}
const person1 = new Person(obj)
2. 工廠模式:為創(chuàng)建一組相關或相互依賴的對象提供一個接口,且無須指定它們的具體類
即隱藏創(chuàng)建過程、暴露共同接口。
js
復制代碼
// 需求:公司員工創(chuàng)建完信息后需要為每一個員工創(chuàng)建一個信息名片
class setPerson {
constructor(obj) {
this.pesonObj = obj
}
creatCard() {
//創(chuàng)建信息名片
}
otherFynction(){
}
}
class Person {
constructor(obj) {
return new setPerson(obj)
}
}
const person = new Person()
const card = person.creatCard({
name:'張三',
age:'20',
department:'人力資源部門'
})
3. 單例模式:全局只有一個實例,避免重復創(chuàng)建對象,優(yōu)化性能
js
復制代碼
// 需求:判斷一款應用的開閉狀態(tài),根據(jù)不同狀態(tài)給出不同提示
class applicationStation {
constructor() {
this.state = 'off'
}
play() {
if (this.state === 'on') {
console.log('已打開')
return
}
this.state = 'on'
}
shutdown() {
if (this.state === 'off') {
console.log('已關閉')
return
}
this.state = 'off'
}
}
window.applicationStation = new applicationStation()
// applicationStation.instance = undefined
// applicationStation.getInstance = function() {
// return function() {
// if (!applicationStation.instance) { // 如果全局沒有實例再創(chuàng)建
// applicationStation.instance = new applicationStation()
// }
// return applicationStation.instance
// }()
// }
// application1和application2擁有同一個applicationStation對象
const application1 = window.applicationStation
const application2 = window.applicationStation
二、結構型
結構型從功能上來說就是給元素添加行為的,目標是優(yōu)化結構的實現(xiàn)方式
1. 適配器模式:適配獨立模塊,保證模塊間的獨立解耦且連接兼容
js
復制代碼
// 需求:一個港行PS,需要適配插座國標
class HKDevice {
getPlug() {
return '港行雙圓柱插頭'
}
}
class Target {
constructor() {
this.plug = new HKDevice()
}
getPlug() {
return this.plug.getPlug() + '+港行雙圓柱轉換器'
}
}
const target = new Target()
target.getPlug()
2. 裝飾器模式:動態(tài)將責任附加到對象之上
js
復制代碼
// 說回我們之前說的為公司員工創(chuàng)建名片需求,現(xiàn)在追加需求,要給不同工齡的員工,創(chuàng)建不同的類型名片樣式
//由于的工廠函數(shù)還有其他各種方法,不好直接改動原工廠函數(shù),這時候我們可以使用裝飾器模式實現(xiàn)
class setPerson {
constructor(obj) {
this.pesonObj = obj
}
creatCard() {
//創(chuàng)建信息名片
}
otherFynction(){
}
}
// 追加
class updatePerson {
constructor(obj) {
this.pesonObj = obj
}
creatCard() {
this.pesonObj.creatCard()
if(this.pesonObj.seniorityNum<1){
this.update(this.pesonObj)
}
}
update(pesonObj) {
//追加處理
}
}
const person = new setPerson()
const newPerson = new updatePerson(person)
newDevice.creatCard()
3. 代理模式:使用代理人來替代原始對象處理更專業(yè)的事情
js
復制代碼
// 需求:在單例模式中,我們實現(xiàn)了應用狀態(tài)的判斷,現(xiàn)在,我們需要控制這個應用要在登錄注冊的情況下才能使用,可以通過代理模式,講這個需求代理給專門攔截的對象進行判斷
class applicationStation {
init() {
return 'hello'
}
}
class User {
constructor(loginStatus) {
this.loginStatus = loginStatus
}
}
class applicationStationProxy {
constructor(user) {
this.user = user
}
init() {
return this.user.loginStatus ? new applicationStation().init() : please Login
}
}
const user = new User(true)
const userProcy = new applicationStationProxy(user)
userProcy.init()
三、行為型
不同對象之間責任的劃分和算法的抽象化
1. 觀察者模式:當一個屬性發(fā)生變化時,觀察者會連續(xù)引發(fā)所有的相關狀態(tài)變更
js
復制代碼
// 需求:通過智能家居中心一鍵控制系統(tǒng)
class MediaCenter {
constructor() {
this.state = ''
this.observers = []
}
attach(observers) {
this.observers.push(observers)
}
getState() {
return this.state
}
setState(state) {
this.state = state
this.notifyAllobservers()
}
notifyAllobservers() {
this.observers.forEach(ob => {
ob.update()
})
}
}
class observers {
constructor(name, center) {
this.name = name
this.center = center
this.center.attach(this)
}
update() {
// 更新狀態(tài)
this.center.getState()
}
}
2. 模版模式:在模版中,定義好每個方法的執(zhí)行步驟。方法本身關注于自己的事情
js
復制代碼
// 需求:新員工入職,按照規(guī)定流程,進行相關培訓和辦理好員工相關資料
class EntryPath {
constructor(obj) {
// some code
}
init() {
// 初始化員工信息
}
creatCard() {
// 創(chuàng)建員工名片
}
inductionTraining() {
// 入職培訓
}
trainingExamination() {
// 訓后測試
}
personEntry() {
this.init()
this.creatCard()
this.inductionTraining()
this.trainingExamination()
}
}
3. 命令模式:請求以指令的形式包裹在對象中,并傳給調用對象
js
復制代碼
// 需求:游戲角色的控制
// 接受者
class Receiver {
execute() {
// 奔跑
}
}
// 操控者
class Operator {
constructor(command) {
this.command = command
}
run() {
this.command.execute()
}
}
// 指令器
class command {
constructor(receiver) {
this.receiver = receiver
}
execute() {
// 邏輯
this.receiver.execute()
}
}
const soldier = new Receiver()
const order = new command(soldier)
const player = new Operator(order)
player.run()
最后,很多人看了文章后提到了應用場景。本人在實際開發(fā)中遇到的場景其實都沒辦法完全嚴格按照六大原則來設計代碼。但能在認知這些設計模式的情況下設計代碼邏輯的思想往這些模式上靠。另外文中很多例子都是比較簡單的,一則為了簡單理解,二則復雜的不好輸出。若大家有優(yōu)秀的案例可以分享出來,一起交流學習,一起進步~~
作者:洪小小
鏈接:https://juejin.cn/post/7274146202496041018
來源:稀土掘金
往期推薦
最后
歡迎加我微信,拉你進技術群,長期交流學習...
歡迎關注「前端Q」,認真學前端,做個專業(yè)的技術人...
評論
圖片
表情
