AVt天堂网 手机版,亚洲va久久久噜噜噜久久4399,天天综合亚洲色在线精品,亚洲一级Av无码毛片久久精品

當前位置:首頁 > 科技  > 軟件

開閉原則,開放的是什么?關閉的又是什么?

來源: 責編: 時間:2024-07-11 17:30:25 701觀看
導讀真實工作中,你是否是這樣操作過:一個需求過來,把原來的代碼改一遍,再一個需求過來,又把上一個需求的代碼改一遍,很多重復的工作還是在日復一日的重復,有什么好的辦法改善嗎?相信有經驗的小伙伴一定聽過:對擴展開放,對修改關閉。

真實工作中,你是否是這樣操作過:一個需求過來,把原來的代碼改一遍,再一個需求過來,又把上一個需求的代碼改一遍,很多重復的工作還是在日復一日的重復,有什么好的辦法改善嗎?7J428資訊網——每日最新資訊28at.com

相信有經驗的小伙伴一定聽過:對擴展開放,對修改關閉。那么,你知道這句話的真正含義嗎?今天我們來聊聊開閉原則到底是怎么實現的。7J428資訊網——每日最新資訊28at.com

什么是開閉原則?

開放封閉原則,英文是:Open–closed principle, 簡稱OCP,是該原則是 Bertrand Meyer 在1988年提出的,最后被 Robert C. Martin收錄到 SOLID原則,開閉原則指出:7J428資訊網——每日最新資訊28at.com

Software entities should be open for extension, but closed for modification.7J428資訊網——每日最新資訊28at.com

7J428資訊網——每日最新資訊28at.com

軟件實體應該對擴展開放,對修改關閉。7J428資訊網——每日最新資訊28at.com

如何實現開閉原則?

"對擴展開放,對修改關閉",如何理解呢?我們先看一個案例,如下圖,給出了電商領域庫存系統庫存變更的簡易模型圖,庫存系統接收外部系統庫存變更事件,然后對數據庫中的庫存進行修改。7J428資訊網——每日最新資訊28at.com

7J428資訊網——每日最新資訊28at.com

面對這個業務需求,很多人的代碼會寫出這樣:7J428資訊網——每日最新資訊28at.com

public class Stock {    public void updateStock(String event){        if("outOfStock" == event){            // todo 出庫事件   庫存操作        }else if("warehousing" == event){            // todo 入庫事件   庫存操作        }    }}

這時,新的需求來了:WMS倉儲系統內部會產生盤點事件(盤盈/盤虧),這些事件會導致變更庫存。于是,代碼就會發展成下面這樣:7J428資訊網——每日最新資訊28at.com

public class Stock {    public void updateStock(String event){        if("outOfStock" == event){            // todo 出庫事件   庫存操作        }else if("warehousing" == event){            // todo 入庫事件   庫存操作        }else if("panSurplus" == event){            // todo 盤盈事件   庫存操作        }else if("loss" == event){            // todo 盤虧事件   庫存操作        }    }}

很顯然,上述代碼的實現,每來一個需求,就需要修改一次代碼,在方法中增加一個 else if分支,因此 Stock類就一直處于變更中,不穩定。7J428資訊網——每日最新資訊28at.com

有沒有什么好的辦法,可以使得這個代碼不用被修改,但是又能夠靈活的擴展,滿足業務需求呢?7J428資訊網——每日最新資訊28at.com

這個時候我們就要搬出 java的三大法寶:繼承,實現,多態。7J428資訊網——每日最新資訊28at.com

我們發現整個業務模型是:事件導致庫存變更。所以,能不能把事件抽離出來?把它抽象成一個接口,代碼如下:7J428資訊網——每日最新資訊28at.com

public interface Event {    void updateStock(String event);}

每種事件對應一種庫存變更,抽象成一個具體的實現類,代碼如下:7J428資訊網——每日最新資訊28at.com

入庫事件7J428資訊網——每日最新資訊28at.com

public class WarehousingEvent implements Event {    public void updateStock(String event){        // 業務邏輯    }}

出庫事件7J428資訊網——每日最新資訊28at.com

public class OutOfStockEvent implements Event {    public void updateStock(String event){        // 業務邏輯    }}

xxx事件7J428資訊網——每日最新資訊28at.com

public class XXXEvent implements Event {    public void updateStock(String event){        // 業務邏輯    }}

最后,Stock類中 updateStock()庫存變更邏輯就可以抽象成下面這樣:7J428資訊網——每日最新資訊28at.com

public class Stock {    public void updateStock(String event){        // 根據事件類型獲取真實的實現類        Event event = getEventInstance(event);        // 庫存變更操作        event.updateStock();    }}

經過抽象、分離和改造之后,Stock.updateStock()類就穩定下來了,再也不需要每增加一個事件就需要增加一個 else if分支處理,這種抽象帶來的好處也是很明顯的:每次有新的庫存變更事件,只需要增加一個實現類,其他的邏輯都不需要更改,當庫存事件無效時只需要把實現類刪除即可。7J428資訊網——每日最新資訊28at.com

開閉原則是常見方式

在Java編程中,遵循開閉原則的常見方式有:使用抽象類和接口、使用策略模式、使用裝飾器模式等。7J428資訊網——每日最新資訊28at.com

1.抽象類和接口

抽象類和接口是 Java中實現 開閉原則的基礎,通過定義抽象類或接口,程序員可以在不修改已有代碼的情況下,通過繼承或實現來擴展新功能。因此,我們強烈建議:面向接口編程。7J428資訊網——每日最新資訊28at.com

2.策略模式

策略模式是一種行為設計模式,允許在運行時選擇算法的實現,策略模式通過定義一系列算法,并將每個算法封裝在獨立的類中,使得它們可以相互替換。7J428資訊網——每日最新資訊28at.com

在上面的示例講解中,其實使用的就是策略模式,當后期有其他的庫存事件時,我們只需要添加擴展類,而無需修改現有的代碼。7J428資訊網——每日最新資訊28at.com

3.裝飾器模式

裝飾器模式是一種結構設計模式,允許向一個對象動態添加行為。裝飾器模式通過創建一個裝飾器類來包裝原始類,從而增加新的功能。示例代碼:7J428資訊網——每日最新資訊28at.com

// 定義一個接口public interface Coffee {    String getDescription();    double getCost();}// 實現接口的具體類public class SimpleCoffee implements Coffee {    @Override    public String getDescription() {        return "Simple Coffee";    }    @Override    public double getCost() {        return 5.0;    }}// 創建裝飾器抽象類public abstract class CoffeeDecorator implements Coffee {    protected Coffee decoratedCoffee;    public CoffeeDecorator(Coffee coffee) {        this.decoratedCoffee = coffee;    }    @Override    public String getDescription() {        return decoratedCoffee.getDescription();    }    @Override    public double getCost() {        return decoratedCoffee.getCost();    }}// 實現具體的裝飾器類public class MilkDecorator extends CoffeeDecorator {    public MilkDecorator(Coffee coffee) {        super(coffee);    }    @Override    public String getDescription() {        return decoratedCoffee.getDescription() + ", Milk";    }    @Override    public double getCost() {        return decoratedCoffee.getCost() + 1.5;    }}public class SugarDecorator extends CoffeeDecorator {    public SugarDecorator(Coffee coffee) {        super(coffee);    }    @Override    public String getDescription() {        return decoratedCoffee.getDescription() + ", Sugar";    }    @Override    public double getCost() {        return decoratedCoffee.getCost() + 0.5;    }}// 客戶端代碼public class CoffeeShop {    public static void main(String[] args) {        Coffee coffee = new SimpleCoffee();        System.out.println(coffee.getDescription() + " $" + coffee.getCost());        coffee = new MilkDecorator(coffee);        System.out.println(coffee.getDescription() + " $" + coffee.getCost());        coffee = new SugarDecorator(coffee);        System.out.println(coffee.getDescription() + " $" + coffee.getCost());    }}

在這個示例中,Coffee接口定義了獲取描述和成本的方法,SimpleCoffee類實現了這個接口。CoffeeDecorator類是一個抽象類,實現了 Coffee接口,并持有一個 Coffee對象。MilkDecorator和SugarDecorator類分別繼承了CoffeeDecorator類,并擴展了其功能。如果我們需要增加新的裝飾器,只需要繼承 CoffeeDecorator類并實現其方法即可,而無需修改現有的代碼。7J428資訊網——每日最新資訊28at.com

總結

本文通過一個電商中庫存實例,演示了開閉原則的整個抽象和實現過程,并給出了開閉原則最常用的 3種實現方式。7J428資訊網——每日最新資訊28at.com

開閉原則的核心是對擴展開放,對修改關閉,因此,當業務需求一直需要修改同一段代碼時,我們就得多思考代碼修改的理由是什么?它們之間是不是有一定的共同性?能不能把這些變更點分離出來,通過擴展來實現而不是修改代碼?7J428資訊網——每日最新資訊28at.com

其實在業務開發中還有很多類似的場景,比如:電商系統中的會員系統,需要根據用戶不同的等級計算不同的費用;機票系統,根據用戶不同的等級(普通,白金用戶,黃金用戶...)提供不同的售票機制;網關系統中,根據不同的粒度(接口,ip,服務,集群)來實現限流;7J428資訊網——每日最新資訊28at.com

可能有小伙伴會反駁,業務場景有類似的場景,但是邏輯簡單,幾個 if-else就搞定了,沒有必要去搞這么復雜的設計。7J428資訊網——每日最新資訊28at.com

本人建議:功夫在平時,功夫在細節。7J428資訊網——每日最新資訊28at.com

很多人總抱怨業務開發技術成長慢,特別是對于初級程序員,但是大部門人的起點都是業務的 CRUD,如果能在業務 CRUD過程中想辦法"挖掘"某些 設計模式,通過這種長期的刻意練習,量變產生質變,慢慢就能領會這些經典設計原則的奧妙,終有一天也能寫出讓人賞心悅目的代碼。7J428資訊網——每日最新資訊28at.com

本文鏈接:http://www.tebozhan.com/showinfo-26-100459-0.html開閉原則,開放的是什么?關閉的又是什么?

聲明:本網頁內容旨在傳播知識,若有侵權等問題請及時與本網聯系,我們將在第一時間刪除處理。郵件:2376512515@qq.com

上一篇: IDC:蘋果 Vision Pro 今年銷量不超過 50 萬臺,平價款明年發布

下一篇: Python 數據類型(如整數、浮點數、字符串、列表、元組、字典)

標簽:
  • 熱門焦點
  • 小米官宣:2023年上半年出貨量中國第一!

    今日早間,小米電視官方微博帶來消息,稱2023年小米電視上半年出貨量達到了中國第一,同時還表示小米電視的巨屏風暴即將開始。“公布一個好消息2023年#小米電視上半年出貨量中國
  • 直屏旗艦來了 iQOO 12和K70 Pro同臺競技

    旗艦機基本上使用的都是雙曲面屏幕,這就讓很多喜歡直屏的愛好者在苦等一款直屏旗艦,這次,你們等到了。據博主數碼閑聊站帶來的最新爆料稱,Redmi下代旗艦K70 Pro和iQOO 12兩款手
  • 7月安卓手機性價比榜:努比亞+紅魔兩款新機入榜

    7月登場的新機有努比亞Z50S Pro和紅魔8S Pro,除了三星之外目前唯二的兩款搭載超頻版驍龍8Gen2處理器的產品,而且努比亞和紅魔也一貫有著不錯的性價比,所以在本次的性價比榜單
  • 如何通過Python線程池實現異步編程?

    線程池的概念和基本原理線程池是一種并發處理機制,它可以在程序啟動時創建一組線程,并將它們置于等待任務的狀態。當任務到達時,線程池中的某個線程會被喚醒并執行任務,執行完任
  • 虛擬鍵盤 API 的妙用

    你是否在遇到過這樣的問題:移動設備上有一個固定元素,當激活虛擬鍵盤時,該元素被隱藏在了鍵盤下方?多年來,這一直是 Web 上的默認行為,在本文中,我們將探討這個問題、為什么會發生
  • 重估百度丨“晚熟”的百度云,能等到春天嗎?

    ©自象限原創作者|程心排版|王喻可2016年7月13日,百度云計算戰略發布會在北京舉行,宣告著百度智能云的正式啟程。彼時的會場座無虛席,甚至排隊排到了門外,在場的所有人幾乎都
  • iQOO 11S新品發布會

    iQOO將在7月4日19:00舉行新品發布會,推出杭州亞運會電競賽事官方用機iQOO 11S。
  • 首發天璣9200+ iQOO Neo8系列發布首銷售價2299元起

    2023年5月23日晚,iQOO Neo8系列正式發布。其中,Neo系列首款Pro之作——iQOO Neo8 Pro強悍登場,限時售價3099元起;價位段最強性能手機iQOO Neo8同期上市
  • OPPO K11評測:旗艦級IMX890加持 2000元檔最強影像手機

    【Techweb評測】中端機型用戶群體巨大,占了中國目前手機市場的大頭,一直以來都是各手機品牌的“必爭之地”,其中OPPO K系列機型一直以來都以高品質、
Top