成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

把「策略模式」應(yīng)用到實(shí)際項(xiàng)目中

LeviDing / 622人閱讀

摘要:閱讀原文把策略模式應(yīng)用到實(shí)際項(xiàng)目中無論你知不知道這個(gè)設(shè)計(jì)模式,但必定在項(xiàng)目中都似曾相識(shí)。文件存儲(chǔ)的方式不同,同時(shí)文件的獲取和刪除也不同保存,獲取,刪除后的響應(yīng)也是相同的,也不考慮了。此時(shí)引入是解決問題的最佳方式。

閱讀原文:把「策略模式」應(yīng)用到實(shí)際項(xiàng)目中

無論你知不知道這個(gè)設(shè)計(jì)模式,但必定在項(xiàng)目中都似曾相識(shí)。倘若僅僅聊理論必然枯燥乏味,只有理論和實(shí)戰(zhàn)相結(jié)合方可達(dá)到人劍合一的境界。

首先,我來說個(gè)需求,倘若是你遇到該如何做?你可停留幾分鐘,想出你的解決方式,可在下方留言,說出你的想法。

需求

用戶有文件上傳的需求,而我們要負(fù)責(zé)對文件進(jìn)行存儲(chǔ),由于我們的系統(tǒng)可能會(huì)多帶帶給個(gè)別客戶私有化部署(部署盡量少依賴中間件能服務(wù)等),同時(shí)我們也會(huì)自己運(yùn)營成為自己的SaaS服務(wù)(保證服務(wù)的高可用等)。

所以我們有兩點(diǎn)需求:

要在SaaS版本中將文件存入分布式存儲(chǔ)系統(tǒng)fastDfs中

客戶的私有部署中將文件?存儲(chǔ)在數(shù)據(jù)庫中

思路 尋找異同點(diǎn)

文件上傳過程這個(gè)無論什么版本部署都是一樣的,所以暫不考慮。

文件存儲(chǔ)的方式不同,同時(shí)文件的獲取和刪除也不同

保存,獲取,刪除后的響應(yīng)也是相同的,也不考慮了。

開始抽象

當(dāng)前我們考慮的就是文件的存儲(chǔ),獲取和刪除了。同樣的行為,不同的實(shí)現(xiàn),我們必定想到定義一個(gè)接口:

/**
 * 文件存儲(chǔ)接口
 * Identify表示文件的唯一標(biāo)識(shí),可任意類型
 * T 表示 上傳下載的返回類型,可任意類型
 *
 * @author flyhero
 * @date 2019-02-01 11:18 AM
 */
public interface IStorageService {

    /**
     * 上傳文件
     *
     * @param file
     * @return
     */
    T upload(MultipartFile file);

    /**
     * 下載文件
     *
     * @param identify
     * @return
     */
    T download(Identify identify);

    /**
     * 刪除文件
     *
     * @param identify
     */
    void delete(Identify identify);
}
兩種不同的實(shí)現(xiàn)

存儲(chǔ)FastDfs

@Slfj
@Service("fastDfsServiceImpl")
public class FastDfsServiceImpl implements IStorageService {

    @Override
    @Transactional(rollbackFor = Exception.class)
    public FileVo upload(MultipartFile multipartFile){
        logger.info("存儲(chǔ)在fastDfs……");
    }

    @Override
    public FileVo download(String hash) {
        logger.info("從fastDfs下載文件");
        return null;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void delete(String hash) {
        logger.info("從fastDfs刪除文件");
    }
}

存儲(chǔ) 數(shù)據(jù)庫

@Slfj
@Service("databaseServiceImpl")
public class DatabaseServiceImpl implements IStorageService {

    @Override
    @Transactional(rollbackFor = Exception.class)
    public FileVo upload(MultipartFile file) {
        logger.info("存儲(chǔ)在database……");
        return null;
    }

    @Override
    public FileVo download(String hash) {
        logger.info("從database下載文件");
        return null;
    }

    @Override
    public void delete(String hash) {
        logger.info("從database刪除文件");
    }
}

調(diào)用

@Service
public class FileServiceImpl implements FileService {

//  同一個(gè)接口根據(jù)不同的名稱調(diào)用不同的實(shí)現(xiàn)
//  @Qualifier("databaseServiceImpl")
    @Qualifier("fastDfsServiceImpl")
    @Autowired
    private IStorageService storageService;
  
    public void save(MultipartFile file){
        if (null == file) {
            throws new Exception("文件不能為空");
        }
        FileVo fileVo = storageService.upload(file);
    }
}
疑惑

可能有人會(huì)說了:這怎么和我了解的策略模式不一樣啊,策略模式不是這樣的嗎?

你說的對!但這是在沒有任何框架下的設(shè)計(jì)模式,而我們現(xiàn)在普遍使用的都是Spring框架,那么標(biāo)準(zhǔn)的策略模式中的Context去哪里了?

引入Context的作用

首先我們要知道引入Context的作用,是為了避免高層直接與策略接口直接交互,為什么呢?因?yàn)槲覀儾呗阅J浇涌诠δ芟鄬Ρ容^單一,而有些高層模塊可能需要一些比較復(fù)雜的交互。

若直接調(diào)用接口,則需要對每個(gè)實(shí)現(xiàn)增加邏輯;

若直接調(diào)用前,執(zhí)行增強(qiáng)邏輯,那么多個(gè)地方使用時(shí),會(huì)存在重復(fù)增強(qiáng)邏輯,并可能忘掉。

此時(shí)引入Context是解決問題的最佳方式。

而我們的FileServiceImpl就相當(dāng)于Context的作用,由于我們使用Spring框架且使用了三層架構(gòu),暴露上傳文件、下載文件、刪除文件是在controller層三個(gè)不同的方法中(或不同的controller中),為了避免幾個(gè)地方使用的存儲(chǔ)策略不同,我直接在Context中來指定使用的策略,當(dāng)需要切換時(shí)也非常方便,只需要更改IStorageService的注解即可。

總結(jié) 優(yōu)點(diǎn)

策略實(shí)現(xiàn)類可自由切換

易于擴(kuò)展,若還有新的策略只要新增策略接口一個(gè)實(shí)現(xiàn)類即可

不必使用條件語句進(jìn)行決定使用哪個(gè)策略

缺點(diǎn)

策略類一旦增多,調(diào)用者要清楚的知道各種策略的區(qū)別

如果你有不同的看法,還望不吝指教。

更多精彩技術(shù)文章盡在微信公眾號(hào):碼上實(shí)戰(zhàn)

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/74282.html

相關(guān)文章

  • 一文理清21種設(shè)計(jì)模式:用實(shí)例分析和對比

    摘要:設(shè)計(jì)模式無論是對于最底層的的編碼實(shí)現(xiàn)還是較高層的架構(gòu)設(shè)計(jì)都有著重要的指導(dǎo)作用。所謂光說不練假把式,今天我就把項(xiàng)目中常見的應(yīng)用場景涉及到的主要設(shè)計(jì)模式及其相關(guān)設(shè)計(jì)模式總結(jié)一下,用實(shí)例分析和對比的方式在一片文章中就把最常見的種設(shè)計(jì)模式梳理清楚。 設(shè)計(jì)模式無論是對于最底層的的編碼實(shí)現(xiàn)還是較高層的架構(gòu)設(shè)計(jì)都有著重要的指導(dǎo)作用。所謂光說不練假把式,今天我就把項(xiàng)目中常見的應(yīng)用場景涉及到的主要設(shè)計(jì)模...

    PrototypeZ 評論0 收藏0
  • 常見設(shè)計(jì)模式的定義,應(yīng)用場景和方法

    摘要:命令模式的由來,其實(shí)是回調(diào)函數(shù)的一個(gè)面向?qū)ο蟮奶娲?,命令模式早已融入到了語言之中。 模式是對某情景下,針對某種問題的某種解決方案。而一個(gè)設(shè)計(jì)模式是用來解決一個(gè)經(jīng)常出現(xiàn)的設(shè)計(jì)問題的經(jīng)驗(yàn)方法。這么說來,每個(gè)模式都可能有著自己的意圖,應(yīng)用場景,使用方法和使用后果。本文的行文思路和目的皆在于了解各個(gè)模式的定義,應(yīng)用場景和用實(shí)例說明如何在前端開發(fā)中使用。 本文所設(shè)計(jì)到的概念和實(shí)例大多來自《H...

    xuxueli 評論0 收藏0
  • JS設(shè)計(jì)模式——策略模式

    摘要:版本策略模式在上個(gè)例子中雖然初步實(shí)現(xiàn)了策略模式,但是是仿照的傳統(tǒng)面向?qū)ο笳Z言,而的實(shí)現(xiàn)更為簡單,直接把原來的實(shí)例定義成函數(shù),原先的類用函數(shù)來委托。 1. 介紹 策略模式是JS設(shè)計(jì)模式中一大重要的模式有著廣泛的應(yīng)用 2. 定義 定義一系列的算法,把它們一個(gè)個(gè)封裝起來,并且使它們可以相互替換 3. 應(yīng)用 根據(jù)等級、工資計(jì)算獎(jiǎng)金等類似情況、使用不同的動(dòng)畫效果、表單驗(yàn)證等 4. 思想 把算法實(shí)...

    Jrain 評論0 收藏0

發(fā)表評論

0條評論

最新活動(dòng)
閱讀需要支付1元查看
<