成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

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

開發
本文通過一個電商中庫存實例,演示了開閉原則的整個抽象和實現過程,并給出了開閉原則最常用的三種實現方式。

真實工作中,你是否是這樣操作過:一個需求過來,把原來的代碼改一遍,再一個需求過來,又把上一個需求的代碼改一遍,很多重復的工作還是在日復一日的重復,有什么好的辦法改善嗎?

相信有經驗的小伙伴一定聽過:對擴展開放,對修改關閉。那么,你知道這句話的真正含義嗎?今天我們來聊聊開閉原則到底是怎么實現的。

什么是開閉原則?

開放封閉原則,英文是:Open–closed principle, 簡稱OCP,是該原則是 Bertrand Meyer 在1988年提出的,最后被 Robert C. Martin收錄到 SOLID原則,開閉原則指出:


Software entities should be open for extension, but closed for modification.


軟件實體應該對擴展開放,對修改關閉。

如何實現開閉原則?

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

面對這個業務需求,很多人的代碼會寫出這樣:

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

這時,新的需求來了:WMS倉儲系統內部會產生盤點事件(盤盈/盤虧),這些事件會導致變更庫存。于是,代碼就會發展成下面這樣:

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類就一直處于變更中,不穩定。

有沒有什么好的辦法,可以使得這個代碼不用被修改,但是又能夠靈活的擴展,滿足業務需求呢?

這個時候我們就要搬出 java的三大法寶:繼承,實現,多態。

我們發現整個業務模型是:事件導致庫存變更。所以,能不能把事件抽離出來?把它抽象成一個接口,代碼如下:

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

每種事件對應一種庫存變更,抽象成一個具體的實現類,代碼如下:

入庫事件

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

出庫事件

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

xxx事件

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

最后,Stock類中 updateStock()庫存變更邏輯就可以抽象成下面這樣:

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

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

開閉原則是常見方式

在Java編程中,遵循開閉原則的常見方式有:使用抽象類和接口、使用策略模式、使用裝飾器模式等。

1.抽象類和接口

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

2.策略模式

策略模式是一種行為設計模式,允許在運行時選擇算法的實現,策略模式通過定義一系列算法,并將每個算法封裝在獨立的類中,使得它們可以相互替換。

在上面的示例講解中,其實使用的就是策略模式,當后期有其他的庫存事件時,我們只需要添加擴展類,而無需修改現有的代碼。

3.裝飾器模式

裝飾器模式是一種結構設計模式,允許向一個對象動態添加行為。裝飾器模式通過創建一個裝飾器類來包裝原始類,從而增加新的功能。示例代碼:

// 定義一個接口
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類并實現其方法即可,而無需修改現有的代碼。

總結

本文通過一個電商中庫存實例,演示了開閉原則的整個抽象和實現過程,并給出了開閉原則最常用的 3種實現方式。

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

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

可能有小伙伴會反駁,業務場景有類似的場景,但是邏輯簡單,幾個 if-else就搞定了,沒有必要去搞這么復雜的設計。

本人建議:功夫在平時,功夫在細節。

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

責任編輯:趙寧寧 來源: 猿java
相關推薦

2024-07-12 14:27:36

2023-05-05 08:18:38

Linuxsource命令

2020-01-14 10:57:39

內存泄漏虛擬機

2017-03-21 23:29:44

DevOps運維開發

2022-09-07 08:41:57

SpringIstio分布式

2019-01-17 14:35:01

2015-06-04 10:26:50

2023-04-27 13:09:10

MLOps工程師軟技能

2024-06-03 07:57:32

LLMLlama 2token

2012-04-16 15:14:47

web設計

2023-12-27 08:36:27

2021-12-14 10:25:59

元宇宙技術Web

2009-07-07 16:50:39

ServletResp

2009-09-16 09:39:50

ccna是什么CCNA

2009-07-15 15:47:49

iBATIS是什么

2011-06-07 16:56:40

LDAP

2013-02-21 15:40:02

SDN

2009-03-26 15:48:00

2021-11-26 14:28:39

智慧交通智慧城市

2021-10-11 08:58:34

Goroutine操作系統
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 久久综合久色欧美综合狠狠 | 久久久免费毛片 | 一区二区三区久久久 | 日韩中文字幕在线视频 | 久久亚洲欧美日韩精品专区 | 亚洲成人免费在线观看 | 久久久久亚洲 | 亚洲视频免费观看 | 亚洲最大成人综合 | 精久久| 久久久久久久久久久福利观看 | 国产精品二区三区在线观看 | 国产精品视频一区二区三区 | 国产a爽一区二区久久久 | a国产视频 | 国产一区二区三区在线 | 91视频大全 | 久久久妇女国产精品影视 | 欧美一级欧美一级在线播放 | 91直接看| 日韩三级在线 | 国产视频一区在线 | 日韩欧美在 | 精品国产31久久久久久 | 亚洲精品1 | 国产精品成人一区二区三区 | 精品国产黄a∨片高清在线 www.一级片 国产欧美日韩综合精品一区二区 | 国产精品一区二区久久久久 | 欧美日韩美女 | 国产精品不卡一区 | 国产中的精品av涩差av | 免费网站国产 | 精品国产一区二区三区久久久蜜月 | 欧美日韩在线免费观看 | 欧美一区二区三区四区五区无卡码 | 午夜视频免费在线观看 | 中文字幕视频在线 | 亚洲精品免费在线观看 | 性色视频 | av资源中文在线天堂 | 国产蜜臀97一区二区三区 |