日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

(三)设计原则

發布時間:2023/12/31 编程问答 35 豆豆
生活随笔 收集整理的這篇文章主要介紹了 (三)设计原则 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

設計原則

  • 設計原則
  • 何為“設計”
    • 演示沉默是金 + 讓每個程序成為過濾器
  • 設計原則
    • 介紹
      • 單一職責原則
      • 開放封閉原則
      • 李氏置換原則
      • 接口隔離原則
      • 依賴倒置原則
      • 設計原則總結
    • 舉例說明
  • 從設計到模式
  • 簡介 23 種設計模式
  • 面試題
    • 第一題
    • 第二題

設計原則

  • 何為“設計”?
  • 五大設計原則
  • 從設計到模式
  • 簡介 23 種設計模式

何為“設計”

  • 即按照哪一種思路或者標準來實現功能
  • 功能相同,可以有不同設計方案來實現
  • 伴隨著需求增加,設計的作用才能體現出來

按我的理解,通俗來說,設計(僅指編程設計)就是按照哪一種思路或者標準來實現功能。同樣的功能,不同的設計思想都能用不同的方式來實現,前期效果可能一樣,但是隨著產品功能的增加和擴展,設計的作用才會慢慢的顯示出來。

結合《UNIX/Linux 設計哲學》中提到的系統設計原則 https://github.com/wangfupeng1988/read-notes/blob/master/book/Linux-Unix%E8%AE%BE%E8%AE%A1%E6%80%9D%E6%83%B3.md 。可能有一些會跟傳統思想有區別,但是請你重視它們。

  • 準則1:小即是美
  • 準則2:讓每個程序只做好一件事
  • 準則3:快速建立原型
  • 準則4:舍棄高效率而取可移植性
  • 準則5:采用純文本來存儲數據
  • 準則6:充分利用軟件的杠桿效應(軟件復用)
  • 準則7:使用 shell 腳本來提高杠桿效應和可移植性
  • 準則8:避免強制性的用戶界面
  • 準則9:讓每個程序都稱為過濾器
  • 十條小準則
    • 允許用戶定制環境
    • 盡量使操作系統內核小而輕量化
    • 使用小寫字母并盡量簡短
    • 保護樹木
    • 沉默是金
    • 并行思考
    • 各部分之和大于整體
    • 尋求 90% 的解決方案
    • 更壞就是更好
    • 層次化思考

無論你現在能否理解以上這些準則,我都希望你每隔一段時間(如半年)都重新自省一下,看自己結合自己的工作經歷,是否又加深了這些準則的理解。

PS,這本書推薦大家買來閱讀,JD 上已經買不到正版了,其他途徑自己去找找吧。我是直接下載了電子版,然后打印出來閱讀。


設計原則和設計模式都不難理解,因為:計算機越偏向底層就越簡單、執拗、越傻(如必須使用二進制,不使用十進制),因為其本質是電子 + 數學。而越偏向于高層或者表層就要越聰明,越任性(如java語言,設計原則),因為其本質是應對變化和需求。

演示沉默是金 + 讓每個程序成為過濾器

設計原則

S O L(Liskov) I D 五大設計原則

  • S - 單一職責原則
  • O - 開放封閉原則
  • L - 李氏置換原則
  • I - 接口獨立原則
  • D - 依賴導致原則

介紹

單一職責原則

  • 一個程序只做好一件事
  • 如果功能過于復雜就拆分開,每個部分保持獨立。

開放封閉原則

  • 對修改封閉,對擴展開放
  • 即要設計一種機制,當需求發生變化時,根據這種機制擴展代碼,而不是修改原有的代碼。原有代碼修改要重新測試,多人開發也很容易沖突
  • 這是軟件設計的終極目標

李氏置換原則

  • 子類能覆蓋父類
  • 父類能出現的地方子類就能出現。
  • JS 中子類繼承父類的場景較少,又不是強類型語言,因此體現較少。

接口隔離原則

  • 保持接口的單一獨立,避免出現“胖接口”。
  • JS中沒有接口(typescript例外),因此體現較少。
  • 類似于單一職責原則,只不過前者說的比較統一,后者是單獨對接口的規定。

依賴倒置原則

  • 面向接口編程,依賴于抽象而不依賴于具體。寫代碼時用到具體類時,不與具體類交互,而與具體類的上層接口交互。
  • 使用方只關注接口而不關注具體類的實現
  • JS中使用較少(沒有接口 & 弱類型)
    只關注輸入輸出接口,內部實現不用管

設計原則總結

S O 體現較多,詳細介紹
L I D體現較少,但是要了解其用意

舉例說明

后三個原則是基于高級面向對象語言語法的(如 java),找不到太合適的例子,就先以常見的 Promise 來解釋一下前兩個原則S O。

// 加載圖片 function loadImg(src) {var promise = new Promise(function (resolve, reject) {var img = document.createElement('img')img.onload = function () {resolve(img)}img.onerror = function () {reject('圖片加載失敗')}img.src = src})return promise }var src = 'https://www.imooc.com/static/img/index/logo_new.png' var result = loadImg(src)result.then(function (img) {console.log('img.width', img.width)return img }).then(function (img) {console.log('img.height', img.height) }).catch(function (ex) {// 統一捕獲異常console.log(ex) })
  • 單一職責原則:每個then中的邏輯只做好一件事,如果要做多個就用多個then
  • 開放封閉原則:如果這個需求要修改,那去擴展then即可,現有的邏輯不用修改,即對擴展開放、對修改封閉

這里引申兩點:

  • 其實 S 和 O 是相符現成的,相互依賴
  • 開放封閉原則的好處不止于此,從整個軟件開發流程看,減少現有邏輯的更改,也會減少測試的成本

從設計到模式

  • 設計
  • 模式
  • 分開
  • 從設計到模式

“設計”和“模式”應該分開看?!霸O計”即設計原則、設計思想,“模式”即一些固話了的符合設計原則的既定方式、成型的可套用的模板。先有“設計”后有“模式”,因此應該“從設計到模式”,不能將“設計模式”作為一個詞來稱呼。

這并不是故意咬文爵字。

(分開之后,你可能會有一種豁然開朗的感覺)

簡介 23 種設計模式

以下是所有 23 種設計模式。一些是前端常用且能找到經典使用場景的,一些是不常用或者找不到代表性的使用場景的。根據使用的不同,講解時也會區分優先級,重點的模式詳細講解。

  • 創建型模式
    • 工廠模式(工廠方法模式,抽象工廠模式,建造者模式)
    • 單例模式
    • 原型模式
  • 結構型模式
    • 適配器模式
    • 裝飾器模式
    • 代理模式
    • 外觀模式
    • 橋接模式
    • 組合模式
    • 享元模式
  • 行為型模式
    • 策略模式
    • 模板方法模式
    • 觀察者模式
    • 迭代器模式
    • 職責連模式
    • 命令模式
    • 備忘錄模式
    • 狀態模式
    • 訪問者模式
    • 中介者模式
    • 解釋器模式

分優先級

  • 前端常用設計模式,詳講
  • 前端非常用設計模式,略講
  • 前端少用設計模式,介紹

接下來說兩個問題:

  • 我如何講解設計模式?
    • 介紹以及舉例(生活中易理解的示例)
    • 畫 UML 類圖寫 demo 代碼
    • 結合經典應用場景,講解該設計模式如何被使用(如果該設計模式沒有經典應用,就不講)
  • 你如何學習設計模式?
    • 明白每個設計的目的和道理
    • 通過經典應用體會它的真正使用場景
    • 自己編碼時多思考,盡量模仿

最后說明一下。雖然設計模式案例說應該基于 java 學習,因為 java 具有完善的面向對象語言編程的語法。但是現在我們限定的前提環境是前端 JS ,那就不應該再按照 java 的模式去講解設計模式,否則就是削足適履。

  • JS 和 java 語法不一樣;
  • 前端和 java 的應用場景也不同,如前端不會考慮并發、內存泄露

面試題

第一題

打車時,可以打專車或者快車。任何車都有車牌號和名稱
不同車價格不同,快車每公里1元,專車每公里2元
行程開始時,顯示車輛信息
行程結束時,顯示打車金額(假定行程就5公里)

要求:
畫出UML類圖
用ES6語法寫出該示例

class Car {constructor(number, name) {this.number = numberthis.name = name} } class Kuaiche extends Car {constructor(number, name) {super(number, name)this.price = 1} } class Zhuanche extends Car {constructor(number, name) {super(number, name)this.price = 2} }class Trip {constructor(car) {this.car = car}start() {console.log(`行程開始,名稱: ${this.car.name}, 車牌號: ${this.car.number}`)}end() {console.log('行程結束,價格: ' + (this.car.price * 5))} }let car = new Kuaiche(100, '桑塔納') let trip = new Trip(car) trip.start() trip.end()

第二題

某停車場,分3層,每層100車位
每個車位都能監控到車輛的駛入和離開
車輛進入前,顯示每層的空余車位數量
車輛進入時,攝像頭可識別車牌號和時間
車輛出來時,出口顯示器顯示車牌號和停車時長

// 車 class Car {constructor(num) {this.num = num} }// 入口攝像頭 class Camera {shot(car) {return {num: car.num,inTime: Date.now()}} }// 出口顯示器 class Screen {show(car, inTime) {console.log('車牌號', car.num)console.log('停車時間', Date.now() - inTime)} }// 停車場 class Park {constructor(floors) {this.floors = floors || []this.camera = new Camera()this.screen = new Screen()this.carList = {}}in(car) {// 獲取攝像頭的信息:號碼 時間const info = this.camera.shot(car)// 停到某個車位const i = parseInt(Math.random() * 100 % 100)const place = this.floors[0].places[i]place.in()info.place = place// 記錄信息this.carList[car.num] = info}out(car) {// 獲取信息const info = this.carList[car.num]const place = info.placeplace.out()// 顯示時間this.screen.show(car, info.inTime)// 刪除信息存儲delete this.carList[car.num]}emptyNum() {return this.floors.map(floor => {return `${floor.index} 層還有 ${floor.emptyPlaceNum()} 個車位`}).join('\n')} }// 層 class Floor {constructor(index, places) {this.index = indexthis.places = places || []}emptyPlaceNum() {let num = 0this.places.forEach(p => {if (p.empty) {num = num + 1}})return num} }// 車位 class Place {constructor() {this.empty = true}in() {this.empty = false}out() {this.empty = true} }// 測試代碼------------------------------ // 初始化停車場 const floors = [] for (let i = 0; i < 3; i++) {const places = []for (let j = 0; j < 100; j++) {places[j] = new Place()}floors[i] = new Floor(i + 1, places) } const park = new Park(floors)// 初始化車輛 const car1 = new Car('A1') const car2 = new Car('A2') const car3 = new Car('A3')console.log('第一輛車進入') console.log(park.emptyNum()) park.in(car1) console.log('第二輛車進入') console.log(park.emptyNum()) park.in(car2) console.log('第一輛車離開') park.out(car1) console.log('第二輛車離開') park.out(car2)console.log('第三輛車進入') console.log(park.emptyNum()) park.in(car3) console.log('第三輛車離開') park.out(car3)

總結

以上是生活随笔為你收集整理的(三)设计原则的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。