电脑知识|欧美黑人一区二区三区|软件|欧美黑人一级爽快片淫片高清|系统|欧美黑人狂野猛交老妇|数据库|服务器|编程开发|网络运营|知识问答|技术教程文章 - 好吧啦网

您的位置:首頁技術文章
文章詳情頁

深入淺出JavaScript前端中的設計模式

瀏覽:241日期:2022-06-09 15:56:16
目錄
  • 關于設計模式
  • 七種常見的設計模式
  • 單例模式
  • 工廠模式
  • 適配器模式
  • 裝飾器模式
  • 策略模式
  • 觀察者模式
  • 發布-訂閱模式

關于設計模式

軟件設計模式,又稱設計模式,是一套被反復使用、多數人知曉的、經過分類編目的、代碼設計經驗的總結。它描述了在軟件設計過程中的一些不斷重復發生的問題,以及該問題的解決方案。也就是說,它是解決待定問題的一系列套路,是前輩們的代碼設計經驗的總結,具有一定的普遍性,可以重復使用。其目的是為了提高代碼的可重用性、代碼的可讀性和代碼的可靠性。

簡單地說就是一些通用的代碼編寫方式,它是經過不斷考驗得出的一些總結道理,按照這樣的模式去編寫我們的代碼,沿著前人留下來的經驗,我們就可以編寫出詩一般的代碼。

關于設計模式,我們需要知道五大基本原則(SOLID):

(1)單一職責原則:一個類,應該僅有一個引起它變化的原因,簡而言之,就是功能要單一。

(2)開放封閉原則:對擴展開放,對修改關閉。

(3)里氏替換原則:基類出現的地方,子類一定出現。兩個字總結-繼承。

(4)接口隔離原則:一個接口應該是一種角色,不該干的事情不敢,該干的都要干。簡而言之就是降低耦合、減低依賴。

(5)依賴翻轉原則:針對接口編程,依賴抽象而不依賴具體。所編寫的對象不應該跟具體的實例掛鉤,應該更偏抽象的概念。

更具體地描述設計模式的好處,有以下幾點:

①良好的封裝,不會讓內部變量污染外部

②封裝好的代碼可以作為一個模塊給外部調用。外部無需了解細節,只需按約定的規范調用。

③對擴展開放,對修改關閉,即開放關閉原則。外部不能修改內部代碼,保證了內部的正確性;又留出擴展接口,提高了靈活性。

像我們常用的各大框架,如React,Vue等都有不同設計模式的應用,Vue中使用了觀察者模式和發布-訂閱模式。

七種常見的設計模式

設計模式一共分為3大類23種,這里主要介紹常用的幾種。

①創建型模式:單例模式、工廠模式、建造者模式;

②結構型模式:適配器模式、裝飾器模式、代理模式;

③行為型模式:策略模式、觀察者模式、發布訂閱模式、職責鏈模式、中介者模式。

單例模式

單例模式:一個類只有一個實例,并提供一個訪問他的全局訪問點,即一個類只生成一個唯一的實例。

我們在一個類中聲明屬性instance,當調用函數getInstance時,我們判斷instance是否已經存在實例,若存在則訪問該instance對象,若不存在則創建。

class Singleton {    let _instance = null;    static getInstance() {if (!Singleton._instance) {  Singleton.instance = new Singleton()}// 如果這個唯一的實例已經存在,則直接返回return Singleton._instance    }}const s1 = Singleton.getInstance()const s2 = Singleton.getInstance()

Vuex就是一個典型的單例模式使用案例, store對象就是一個單例對象。

根據其功能代碼,我們可以看出單例模式的優劣點都在哪里。

優點: 節約資源,保證訪問的一致性。

缺點: 擴展性不友好,因為單例模式一般自行實例化,沒有接口。

工廠模式

這個模式我們就非常常用了,聲明一個class,然后根據傳進來的參數去生成對應的實例對象,就是所謂的工廠模式。每一個類就像一個已經開設好的工廠,我們只需要告訴我們的需求,它就會生成我們想要的一個對象返回。

class Restaurant{    constructor(){this.menuData = {};    }    // 獲取菜品    getDish(dish){if(!this.menuData[menu]){    console.log("菜品不存在,獲取失敗");    return;}return this.menuData[menu];    },    // 添加菜品    addMenu(menu,description){if(this.menuData[menu]){    console.log("菜品已存在,請勿重復添加");    return;}this.menuData[menu] = menu;    }    // 移除菜品    removeMenu(menu){if(!this.menuData[menu]){    console.log("菜品不存在,移除失敗");    return;}delete this.menuData[menu];    },}class Dish{    constructor(name,description){this.name = name;this.description = description;    }    eat(){console.log(`I"m eating ${this.name},it"s ${`this.description);    }}

優點:

  • 良好的封裝,訪問者無需了解創建過程,代碼結構清晰。
  • 擴展性良好,通過工廠方法隔離了用戶和創建流程,符合開閉原則。
  • 解耦了高層邏輯和底層產品類,符合最少知識原則,不需要的就不要去交流;

缺點:

缺點就是如果我們的類定義太過抽象復雜了,會出現閱讀性的問題。

適配器模式

這個模式也很好理解,相當于我們平時使用的一些產品,如投影儀之類的,如果我們的電線無法適配到我們的屏幕,我們就需要借助一個中間的適配器,讓兩者可以溝通起來。

interface bookDataType1 {  book_id: number;  status: number;  create: string;  update: string;}interface bookDataType2 {  id: number;  status: number;  createTime: number;  updateAt: string;}interface bookDataType3 {  book_id: number;  status: number;  createTime: number;  updateAt: number;}const getTimeStamp = function (str: string): number {  //.....轉化成時間戳  return timeStamp;};//適配器export const bookDataAdapter = {  adapterType1(list: bookDataType1[]) {    const bookDataList: bookData[] = list.map((item) => {      return {book_id: item.book_id,status: item.status,createAt: getTimeStamp(item.create),updateAt: getTimeStamp(item.update),      };    });    return bookDataList;  },  adapterType2(list: bookDataType2[]) {    const bookDataList: bookData[] = list.map((item) => {      return {book_id: item.id,status: item.status,createAt: item.createTime,updateAt: getTimeStamp(item.updateAt),      };    });    return bookDataList;  },  adapterType3(list: bookDataType3[]) {    const bookDataList: bookData[] = list.map((item) => {      return {book_id: item.book_id,status: item.status,createAt: item.createTime,updateAt: item.updateAt,      };    });    return bookDataList;  },};

優點: 可以使原有邏輯得到更好的復用,有助于避免大規模改寫現有代碼,為了不改動原有的代碼而做出的一種妥協;

缺點:會讓系統變得零亂,明明調用 A,卻被適配到了 B,如果濫用,那么對可閱讀性不太友好。簡而言之搞復雜了,所以通常建議不要出現以上這樣的格式問題,應該跟后端溝通好數據。

裝飾器模式

典型的大腸包小腸,當前使用的對象無法滿足我們的全部需求,于是乎我們建一個新的類,再把這個對象在類中進行擴展,再生成一個新的對象。

策略模式

這個是相當相當常用,而且很好用的一個設計模式,可以讓我們根據不同的選擇去實現對應的功能,省略了大量的if,else。

比如我們現在有一個需求判斷,比如我現在要根據別人給我的不同食材去制造料理,最暴力常規那就是if,else多寫幾個就解決了。但是這里如果我們用策略模式就可以用很清晰,很簡潔的代碼去解決這個問題。

if ( "food" == "蘋果") {      水煮()} else if ("food" == "胡蘿卜") {      炒了()} else if ("food" == "魚") {      清蒸()} else if ("food" == "豬肉") {      炸了()} else if ("food" == "牛肉") {      烤了()} else {      生吃()}// 用了策略模式,看起來舒服多了let wayObj = {    "蘋果": 水煮(),    "胡蘿卜": 炒了(),    "魚": 清蒸(),    "豬肉": 炸了(),    "牛肉": 烤了(),    "不知道": 生吃()}

觀察者模式

這個模式從名字就可以看出來它是干嘛的,觀察者重點就是觀察,有兩個對象,一個是觀察,一個是被觀察,被觀察發生了變化,那我們觀察的對象就可以知道這個變化。

觀察者模式有一個別名叫“發布-訂閱模式”,或者說是“訂閱-發布模式”,訂閱者和訂閱目標是聯系在一起的,當訂閱目標發生改變時,逐個通知訂閱者。我們可以用報紙期刊的訂閱來形象的說明,當你訂閱了一份報紙,每天都會有一份最新的報紙送到你手上,有多少人訂閱報紙,報社就會發多少份報紙,報社和訂報紙的客戶就是上面文章開頭所說的“一對多”的依賴關系。

// 觀察者模式 被觀察者Subject 觀察者Observer Subject變化 notify觀察者let observerIds = 0;// 被觀察者Subjectclass Subject {  constructor() {    this.observers = [];  }  // 添加觀察者  addObserver(observer) {    this.observers.push(observer);  }  // 移除觀察者  removeObserver(observer) {    this.observers = this.observers.filter((obs) => {      return obs.id !== observer.id;    });  }  // 通知notify觀察者  notify() {    this.observers.forEach((observer) => observer.update(this));  }}// 觀察者Observerclass Observer {  constructor() {    this.id = observerIds++;  }  update(subject) {    // 更新  }}

發布-訂閱模式

其實上面也說了,跟觀察者模式是有異曲同工之妙的,但是它可以是一個一對多的關系,而且它需要一個中間人。

class Event {  constructor() {    this.eventEmitter = {};  }  // 訂閱  on(type, fn) {    if (!this.eventEmitter[type]) {      this.eventEmitter[type] = [];    }    this.eventEmitter[type].push(fn);  }  // 取消訂閱  off(type, fn) {    if (!this.eventEmitter[type]) {      return;    }    this.eventEmitter[type] = this.eventEmitter[type].filter((event) => {      return event !== fn;    });  }  // 發布  emit(type) {    if (!this.eventEmitter[type]) {      return;    }    this.eventEmitter[type].forEach((event) => {      event();    });  }}

到此這篇關于深入淺出JavaScript前端中的設計模式的文章就介紹到這了,更多相關JS設計模式內容請搜索以前的文章或繼續瀏覽下面的相關文章希望大家以后多多支持!

標簽: JavaScript
相關文章:
主站蜘蛛池模板: Honsberg流量计-Greisinger真空表-气压计-上海欧臻机电设备有限公司 | 矿用履带式平板车|探水钻机|气动架柱式钻机|架柱式液压回转钻机|履带式钻机-启睿探水钻机厂家 | 气体检测仪-氢气检测仪-可燃气体传感器-恶臭电子鼻-深国安电子 | 大型工业风扇_工业大风扇_大吊扇_厂房车间降温-合昌大风扇 | 机床主轴维修|刀塔维修|C轴维修-常州翔高精密机械有限公司 | 山东成考网-山东成人高考网| 合肥通道闸-安徽车牌识别-人脸识别系统厂家-安徽熵控智能技术有限公司 | 新型游乐设备,360大摆锤游乐设备「诚信厂家」-山东方鑫游乐设备 新能源汽车电池软连接,铜铝复合膜柔性连接,电力母排-容发智能科技(无锡)有限公司 | 电动球阀_不锈钢电动球阀_电动三通球阀_电动调节球阀_上海湖泉阀门有限公司 | 臭氧老化试验箱,高低温试验箱,恒温恒湿试验箱,防水试验设备-苏州亚诺天下仪器有限公司 | 深圳市万色印象美业有限公司| GAST/BRIWATEC/CINCINNATI/KARL-KLEIN/ZIEHL-ABEGG风机|亚喜科技 | 高压绝缘垫-红色配电房绝缘垫-绿色高压绝缘地毯-上海苏海电气 | 玻纤土工格栅_钢塑格栅_PP焊接_单双向塑料土工格栅_复合防裂布厂家_山东大庚工程材料科技有限公司 | 电销卡_稳定企业大语音卡-归属地可选-世纪通信 | 浙江浩盛阀门有限公司| 石英陶瓷,石英坩埚,二氧化硅陶瓷-淄博百特高新材料有限公司 | 恒温恒湿试验箱厂家-高低温试验箱维修价格_东莞环仪仪器_东莞环仪仪器 | 变色龙云 - 打包app_原生app_在线制作平台_短链接_ip查询 | 平面钻,法兰钻,三维钻-山东兴田阳光智能装备股份有限公司 | 低温等离子清洗机(双气路进口)-嘉润万丰| 洛阳网站建设_洛阳网站优化_网站建设平台_洛阳香河网络科技有限公司 | 专业深孔加工_东莞深孔钻加工_东莞深孔钻_东莞深孔加工_模具深孔钻加工厂-东莞市超耀实业有限公司 | 整车VOC采样环境舱-甲醛VOC预处理舱-多舱法VOC检测环境仓-上海科绿特科技仪器有限公司 | 土壤养分检测仪_肥料养分检测仪_土壤水分检测仪-山东莱恩德仪器 大型多片锯,圆木多片锯,方木多片锯,板材多片锯-祥富机械有限公司 | 右手官网|右手工业设计|外观设计公司|工业设计公司|产品创新设计|医疗产品结构设计|EMC产品结构设计 | 安规_综合测试仪,电器安全性能综合测试仪,低压母线槽安规综合测试仪-青岛合众电子有限公司 | 行星搅拌机,双行星搅拌机,动力混合机,无锡米克斯行星搅拌机生产厂家 | 镀锌角钢_槽钢_扁钢_圆钢_方矩管厂家_镀锌花纹板-海邦钢铁(天津)有限公司 | 称重传感器,测力传感器,拉压力传感器,压力变送器,扭矩传感器,南京凯基特电气有限公司 | 橡胶弹簧|复合弹簧|橡胶球|振动筛配件-新乡市永鑫橡胶厂 | 定制液氮罐_小型气相液氮罐_自增压液氮罐_班德液氮罐厂家 | 双效节能浓缩器-热回流提取浓缩机组-温州市利宏机械 | 四川成都干燥设备_回转筒干燥机_脉冲除尘器_输送设备_热风炉_成都川工星科机电设备有限公司 | 翰香原枣子坊加盟费多少钱-正宗枣核糕配方培训利润高飘香 | 工业制氮机_psa制氮机厂家-宏骁智能装备科技江苏有限公司 | 发电机组|柴油发电机组-批发,上柴,玉柴,潍柴,康明斯柴油发电机厂家直销 | 电镀标牌_电铸标牌_金属标贴_不锈钢标牌厂家_深圳市宝利丰精密科技有限公司 | 杭州双螺杆挤出机-百科| 玉米深加工机械,玉米加工设备,玉米加工机械等玉米深加工设备制造商-河南成立粮油机械有限公司 | 面粉仓_储酒罐_不锈钢储酒罐厂家-泰安鑫佳机械制造有限公司 |