你一定要知道業(yè)務(wù)開發(fā)最常用的兩種設(shè)計模式

一洪囤、背景

很多做業(yè)務(wù)開發(fā)的同學(xué)徒坡,很多認(rèn)為平時寫業(yè)務(wù)代碼工作就是簡單的增刪改查,沒有挑戰(zhàn)瘤缩,寫的代碼不會像一些開源框架那么優(yōu)雅喇完,隨著你積累的經(jīng)驗越來越多,你應(yīng)該跳出這種思維剥啤,業(yè)務(wù)代碼也可以寫的很優(yōu)雅锦溪,也可以有較好的可讀性擴(kuò)展性

我們可以觀察公司內(nèi)府怯,或者團(tuán)隊內(nèi)工作時間長一點(diǎn)的同事寫的代碼刻诊,一般都可以找到可以學(xué)習(xí)的代碼。如果你讀過Spring源碼的同學(xué)可以知道牺丙,Spring代碼有一個非常大的特點(diǎn)就是擴(kuò)展性極強(qiáng)则涯,他擴(kuò)展性強(qiáng)一個很重要的原因是恰當(dāng)?shù)氖褂昧撕芏嘣O(shè)計模式。

本文將結(jié)合案例分析平時業(yè)務(wù)開發(fā)中使用頻率最高的兩種設(shè)計模式<<策略模式>>與<<責(zé)任鏈模式>>冲簿。

二粟判、策略模式

以支付功能為例子,我們知道支付一般都支持多種支付方式峦剔,我們支付功能在后端發(fā)起档礁,不同的支付方式其實就是策略,我們可以通過策略模式來完成支付功能吝沫。將不同的支付方式代碼進(jìn)行解耦呻澜。

public interface PaymentStrategy {
    void pay(double amount);
}

public class WeChatPaymentStrategy implements PaymentStrategy {
    @Override
    public void pay(double amount) {
        // 微信支付邏輯
    }
}

public class AlipayPaymentStrategy implements PaymentStrategy {
    @Override
    public void pay(double amount) {
        // 支付寶支付邏輯
    }
}
import java.util.HashMap;
import java.util.Map;

public class PaymentStrategyFactory {
    private Map<String, PaymentStrategy> strategies = new HashMap<>();

    public void registerStrategy(String name, PaymentStrategy strategy) {
        strategies.put(name, strategy);
    }

    public PaymentStrategy getStrategy(String name) {
        return strategies.get(name);
    }
}

使用策略模式:

public class Main {
    public static void main(String[] args) {
        PaymentStrategyFactory factory = new PaymentStrategyFactory();

        // 注冊支付策略
        factory.registerStrategy("wechat", new WeChatPaymentStrategy());
        factory.registerStrategy("alipay", new AlipayPaymentStrategy());

        // 獲取支付策略
        PaymentStrategy wechatStrategy = factory.getStrategy("wechat");
        PaymentStrategy alipayStrategy = factory.getStrategy("alipay");

        // 使用支付策略
        wechatStrategy.pay(100.0);
        alipayStrategy.pay(150.0);
    }
}

通過上方實際例子,我們可以發(fā)現(xiàn)策略模式很好的將不同的支付方式進(jìn)行了解耦野舶,如果業(yè)務(wù)需要新增一種支付方式,我們不需要改原先的支付方式代碼宰衙,這樣可以達(dá)到對擴(kuò)展開發(fā)平道,對修復(fù)關(guān)閉的設(shè)計原則,對于測試范圍也可控了供炼。

三一屋、異步形式的責(zé)任鏈模式

責(zé)任鏈模式在業(yè)務(wù)開發(fā)中也是可以使用頻率高的設(shè)計模式,我們以展示商品為例:

[圖片上傳失敗...(image-3cc4a9-1715505779722)]

商品頁面袋哼,包含商品標(biāo)題冀墨,主圖等基礎(chǔ)信息,商品價格涛贯,商品優(yōu)惠活動诽嘉,商品庫存等等。

在微服務(wù)架構(gòu)中,商品基礎(chǔ)信息虫腋,商品價格骄酗,商品優(yōu)惠活動,商品庫存都是一個獨(dú)立的領(lǐng)域服務(wù)悦冀,他們通過rpc進(jìn)行通信趋翻,如果我們一個一個調(diào)用,這樣代碼看起來就是一本流水賬盒蟆,過程式編碼踏烙,整體的響應(yīng)時間也會拉長。最初的想法可能是這樣寫的:

1历等、查詢商品基礎(chǔ)信息
2讨惩、查詢商品價格
3、查詢商品活動
4募闲、查詢商品庫存

由于這幾個服務(wù)邏輯比較獨(dú)立步脓,其實是可以并行調(diào)用,我們可以結(jié)合責(zé)任鏈模式CompletableFuture進(jìn)行優(yōu)化浩螺。

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CompletableFuture;

// 商品信息類
class ProductInfo {
    //模擬商品基礎(chǔ)信息
    private String basicInfo;
    //商品價格
    private double price;
    //模擬商品活動信息
    private String activity;
    //模擬商品庫存
    private int inventory;

    // 省略構(gòu)造函數(shù)靴患、getter和setter
}

// 定義責(zé)任鏈節(jié)點(diǎn)接口 補(bǔ)全商品處理接口
interface ServiceHandler {
    CompletableFuture<Void> handle(ProductInfo productInfo);
}

// 實現(xiàn)商品基礎(chǔ)信息補(bǔ)全節(jié)點(diǎn)
class BasicInfoServiceHandler implements ServiceHandler {
    @Override
    public CompletableFuture<Void> handle(ProductInfo productInfo) {
        CompletableFuture<Void> future = new CompletableFuture<>();
        // 模擬異步調(diào)用外部服務(wù),修改商品信息對象
        CompletableFuture.runAsync(() -> {
            // 補(bǔ)充商品基礎(chǔ)信息數(shù)據(jù)
            productInfo.setBasicInfo("...");
            future.complete(null);
        });
        return future;
    }
}

// 實現(xiàn)商品價格補(bǔ)全節(jié)點(diǎn)
class PriceServiceHandler implements ServiceHandler {
    @Override
    public CompletableFuture<Void> handle(ProductInfo productInfo) {
        CompletableFuture<Void> future = new CompletableFuture<>();
        // 模擬異步調(diào)用外部服務(wù)要出,修改商品信息對象
        CompletableFuture.runAsync(() -> {
            // 補(bǔ)充商品價格數(shù)據(jù)
            productInfo.setPrice(100.0);
            future.complete(null);
        });
        return future;
    }
}

// 實現(xiàn)商品活動補(bǔ)全節(jié)點(diǎn)
class ActivityServiceHandler implements ServiceHandler {
    @Override
    public CompletableFuture<Void> handle(ProductInfo productInfo) {
        CompletableFuture<Void> future = new CompletableFuture<>();
        // 模擬異步調(diào)用外部服務(wù)鸳君,修改商品信息對象
        CompletableFuture.runAsync(() -> {
            // 補(bǔ)充商品活動數(shù)據(jù)
            productInfo.setActivity("...");
            future.complete(null);
        });
        return future;
    }
}

// 實現(xiàn)商品庫存服務(wù)節(jié)點(diǎn)
class InventoryServiceHandler implements ServiceHandler {
    @Override
    public CompletableFuture<Void> handle(ProductInfo productInfo) {
        CompletableFuture<Void> future = new CompletableFuture<>();
        // 模擬異步調(diào)用外部服務(wù),修改商品信息對象
        CompletableFuture.runAsync(() -> {
            // 補(bǔ)充商品庫存數(shù)據(jù)
            productInfo.setInventory(100);
            future.complete(null);
        });
        return future;
    }
}

// 責(zé)任鏈
class ServiceHandlerChain {
    private List<ServiceHandler> handlers = new ArrayList<>();

    public void addHandler(ServiceHandler handler) {
        handlers.add(handler);
    }

    public ProductInfo execute(ProductInfo productInfo) {
        CompletableFuture<Void>[] futures = handlers.stream()
                .map(handler -> handler.handle(productInfo))
                .toArray(CompletableFuture[]::new);
        //等待所有的異步補(bǔ)全任務(wù)處理完成   
        CompletableFuture<Void> allOfFuture = CompletableFuture.allOf(futures);
        allOfFuture.join(); // 等待所有異步操作完成
        return productInfo;
    }
}

調(diào)用責(zé)任鏈患蹂,實現(xiàn)商品信息補(bǔ)全:

public class Main {
    public static void main(String[] args) {
        // 創(chuàng)建商品信息對象
        ProductInfo productInfo = new ProductInfo();

        // 創(chuàng)建責(zé)任鏈
        ServiceHandlerChain chain = new ServiceHandlerChain();
        chain.addHandler(new BasicInfoServiceHandler());
        chain.addHandler(new PriceServiceHandler());
        chain.addHandler(new ActivityServiceHandler());
        chain.addHandler(new InventoryServiceHandler());

        // 執(zhí)行責(zé)任鏈
        ProductInfo result = chain.execute(productInfo);

        // 處理最終的商品信息對象
    }
}

通過責(zé)任鏈模式+CompletableFuture優(yōu)化調(diào)整或颊,我們將商品各自補(bǔ)全邏輯進(jìn)行拆分互不依賴传于,如果需要展示商品其他信息可以擴(kuò)展新節(jié)點(diǎn)囱挑,而且每個節(jié)點(diǎn)都是異步化處理,提升整體響應(yīng)速度沼溜。

四平挑、總結(jié)

本文結(jié)合實際例子對于業(yè)務(wù)開發(fā)工作中最常用兩個設(shè)計模式進(jìn)行了總結(jié),適當(dāng)使用設(shè)計模式可以把一些業(yè)務(wù)需求實現(xiàn)的更加優(yōu)雅系草,對于未來的擴(kuò)展性也打下了基礎(chǔ)通熄,給后期開發(fā)測試都減少了工作量,設(shè)計模式可以結(jié)合我們實際業(yè)務(wù)適當(dāng)調(diào)整找都,變成適合我們自己業(yè)務(wù)的模式唇辨,比如上面的異步形式的責(zé)任鏈

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末能耻,一起剝皮案震驚了整個濱河市赏枚,隨后出現(xiàn)的幾起案子亡驰,更是在濱河造成了極大的恐慌,老刑警劉巖嗡贺,帶你破解...
    沈念sama閱讀 211,042評論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件隐解,死亡現(xiàn)場離奇詭異,居然都是意外死亡诫睬,警方通過查閱死者的電腦和手機(jī)煞茫,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 89,996評論 2 384
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來摄凡,“玉大人续徽,你說我怎么就攤上這事∏自瑁” “怎么了钦扭?”我有些...
    開封第一講書人閱讀 156,674評論 0 345
  • 文/不壞的土叔 我叫張陵,是天一觀的道長床绪。 經(jīng)常有香客問我客情,道長,這世上最難降的妖魔是什么癞己? 我笑而不...
    開封第一講書人閱讀 56,340評論 1 283
  • 正文 為了忘掉前任膀斋,我火速辦了婚禮,結(jié)果婚禮上痹雅,老公的妹妹穿的比我還像新娘仰担。我一直安慰自己,他們只是感情好绩社,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,404評論 5 384
  • 文/花漫 我一把揭開白布摔蓝。 她就那樣靜靜地躺著,像睡著了一般愉耙。 火紅的嫁衣襯著肌膚如雪贮尉。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,749評論 1 289
  • 那天朴沿,我揣著相機(jī)與錄音猜谚,去河邊找鬼。 笑死悯仙,一個胖子當(dāng)著我的面吹牛龄毡,可吹牛的內(nèi)容都是我干的吠卷。 我是一名探鬼主播锡垄,決...
    沈念sama閱讀 38,902評論 3 405
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼祭隔!你這毒婦竟也來了货岭?” 一聲冷哼從身側(cè)響起路操,我...
    開封第一講書人閱讀 37,662評論 0 266
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎千贯,沒想到半個月后屯仗,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,110評論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡搔谴,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,451評論 2 325
  • 正文 我和宋清朗相戀三年魁袜,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片敦第。...
    茶點(diǎn)故事閱讀 38,577評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡峰弹,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出芜果,到底是詐尸還是另有隱情鞠呈,我是刑警寧澤,帶...
    沈念sama閱讀 34,258評論 4 328
  • 正文 年R本政府宣布右钾,位于F島的核電站蚁吝,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏舀射。R本人自食惡果不足惜窘茁,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,848評論 3 312
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望后控。 院中可真熱鬧庙曙,春花似錦、人聲如沸浩淘。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,726評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽张抄。三九已至砂蔽,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間署惯,已是汗流浹背左驾。 一陣腳步聲響...
    開封第一講書人閱讀 31,952評論 1 264
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留极谊,地道東北人诡右。 一個月前我還...
    沈念sama閱讀 46,271評論 2 360
  • 正文 我出身青樓,卻偏偏與公主長得像轻猖,于是被迫代替她去往敵國和親帆吻。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,452評論 2 348

推薦閱讀更多精彩內(nèi)容