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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > asp.net >内容正文

asp.net

设计模式:程序员跳不开的坑

發布時間:2024/4/14 asp.net 26 豆豆
生活随笔 收集整理的這篇文章主要介紹了 设计模式:程序员跳不开的坑 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

學編程,總是逃不了要學“算法”,也總跳不開要學“設計模式”。

無論學習什么語言,設計模式始終是我們必須掌握的,這是程序員的基本功。

設計模式(Design pattern)是一套被反復使用、多數人知曉的、經過分類編目的、代碼設計經驗的總結。

使用設計模式是為了可重用代碼、讓代碼更容易被他人理解、保證代碼可靠性。 毫無疑問,設計模式于己于他人于系統都是多贏的,設計模式使代碼編制真正工程化,設計模式是軟件工程的基石,如同大廈的一塊塊磚石一樣。

項目中合理的運用設計模式可以完美的解決很多問題,每種模式在現在中都有相應的原理來與之對應,每一個模式描述了一個在我們周圍不斷重復發生的問題,以及該問題的核心解決方案,這也是它能被廣泛應用的原因。

今天給大家推薦的新課《Go 語言實現 23 種設計模式》,教程涉及7大設計原則、23種設計模式,每種設計模式都從定義、應用及Golang實例三個部分進行詳細介紹。

本課需要學員對 Go 語言有一定的基礎哦,可先學習《Go 語言簡明教程》之后再來學習本課。

本課程概念較多,受篇幅限制,不宜放過多文字,下面截取課程第一章內容給大家介紹第1種設計原則——開閉原則的概念,想要學習完整設計原則及設計模式的小伙伴請移步至《Go 語言實現 23 種設計模式》學習整個課程

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-ciDlxOq8-1590489068301)(https://upload-images.jianshu.io/upload_images/226662-b2462d5ac430761b.png!thumbnail?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)]

開閉原則

開閉原則(Open Closed Principle,OCP) 由勃蘭特.梅耶(Bertrand Meyer)提出,他在 1988 年的著作《面向對象軟件構造》( Object Oriented Software Construction)中提出:軟件實體應當對擴展開放,對修改關閉(Software entities should be open for extension, but closed for modification),這就是開閉原則的經典定義。

開閉原則是設計模式中的總原則,開閉原則就是說:對拓展開放、對修改關閉。模塊應該在盡可能不修改代碼的前提下進行拓展,這就需要使用接口和抽象類來實現預期效果。我們舉例說明什么是開閉原則,以 4s 店銷售汽車為例,其類圖如圖所示:

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-YKdL9FfD-1590489068304)(https://upload-images.jianshu.io/upload_images/226662-b885ed67f01b9e34.png!thumbnail?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)]

ICar 接口定義了汽車的兩個屬性:名稱和價格。BenzCar 是一個奔馳車的實現類,代表奔馳車的總稱。Shop4S 代表售賣的 4S 店,ICar 接口的代碼清單如下:

<pre> package mainimport "fmt"type ICar interface {// 車名GetName() string// 價格GetPrice() int}copy</pre>

一般情況下 4S 店只出售一種品牌的車,這里用奔馳為例,代碼清單如下

<pre> type BenzCar struct {name stringprice int}func (b BenzCar) GetName() string {return b.name}func (b BenzCar) GetPrice() int {return b.price}copy</pre>

這里我們模擬一下 4s 店售車記錄:

<pre> func main() {var (list []ICar)list = []ICar{}list = append(list,&BenzCar{"邁巴赫",130})list = append(list,&BenzCar{"AMG",343})list = append(list,&BenzCar{"V",60})for _,v := range list {fmt.Println("車名:",v.GetName(),"\t價格:",v.GetPrice())}}copy</pre>

接下來,我們在命令行中輸入 cd Principle 先切換到 go 文件所在目錄下,然后執行 go run 1.go 來看我們的執行結果。如下圖所示:

暫時來看,以上設計是沒有啥問題的。但是,某一天,4s 店老板說奔馳轎車統一要收取一筆金融服務費,收取規則是價格在 100 萬元以上的收取 5%,50~100 萬元的收取 2%,其余不收取。為了應對這種需求變化,之前的設計又該如何呢?

目前,解決方案大致有如下三種:

  • 修改 ICar 接口:在 ICar 接口上加一個 getPriceWithFinance 接口,專門獲取加上金融服務費后的價格信息。這樣的后果是,實現類 BenzCar 也要修改,業務類 Shop4S 也要做相應調整。ICar 接口一般應該是足夠穩定的,不應頻繁修改,否則就失去了接口鍥約性了。
  • 修改 BenzCar 實現類:直接修改 BenzCar 類的 getPrice 方法,添加金融服務費的處理。這樣的一個直接后果就是,之前依賴 getPrice 的業務模塊的業務邏輯就發生了改變了,price 也不是之前的 price 了。
  • 使用子類拓展來實現:增加子類 FinanceBenzCar,覆寫父類 BenzCar 的 getPrice 方法,實現金融服務費相關邏輯處理。這樣的好處是:只需要調整 Shop4S 中的靜態模塊區中的代碼,main 中的邏輯是不用做很大的修改的。
  • 新增的 FinanceBenzCar 類代碼清單如下:

    <pre> type FinanceBenzCar struct {BenzCar}func (b FinanceBenzCar) GetPrice() int {// 獲取原價selfPrice := b.pricevar finance intif selfPrice >= 100 {finance = selfPrice + selfPrice5/100 } else if selfPrice >= 50 { finance = selfPrice + selfPrice2/100} else {finance = selfPrice}return finance}copy</pre>

    主函數:

    <pre> func main() {var (list []ICar)list = []ICar{}list = append(list,&FinanceBenzCar{BenzCar{"邁巴赫",99}})list = append(list,&FinanceBenzCar{BenzCar{"AMG",200}})list = append(list,&FinanceBenzCar{BenzCar{"V",40}})for _,v := range list {fmt.Println("車名:",v.GetName(),"\t價格:",v.GetPrice())}}copy</pre>

    測試結果

    <pre> === RUN TestBenzCar_GetName車名: 邁巴赫 價格: 100車名: AMG 價格: 210車名: V 價格: 40--- PASS: TestBenzCar_GetName (0.00s)PASScopy</pre>

    這樣,在業務規則發生改變的情況下,我們通過拓展子類及修改持久層(高層次模塊)便足以應對多變的需求。開閉原則要求我們盡可能通過拓展來實現變化,盡可能少地改變已有模塊,特別是底層模塊。

    開閉原則總結:

    • 提高代碼復用性
    • 提高代碼的可維護性

    本課不像其他項目實戰課程那般,相對晦澀難懂,不那么富有趣味性,但任何一個有趣、有用的程序、項目或者游戲,都需要堅實的基本功方能實現,設計模式就是我們必學的基本功。

    “每一棟大廈,都從一塊磚開始”

    總結

    以上是生活随笔為你收集整理的设计模式:程序员跳不开的坑的全部內容,希望文章能夠幫你解決所遇到的問題。

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