摘要:閱讀原文把策略模式應(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兩種不同的實(shí)現(xiàn){ /** * 上傳文件 * * @param file * @return */ T upload(MultipartFile file); /** * 下載文件 * * @param identify * @return */ T download(Identify identify); /** * 刪除文件 * * @param identify */ void delete(Identify identify); }
存儲(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
摘要:設(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ì)模...
摘要:命令模式的由來,其實(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...
摘要:版本策略模式在上個(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í)...
閱讀 4426·2021-11-19 09:59
閱讀 3344·2021-10-12 10:12
閱讀 2649·2021-09-22 15:25
閱讀 3352·2019-08-30 15:55
閱讀 1198·2019-08-29 11:27
閱讀 1479·2019-08-28 18:06
閱讀 2752·2019-08-26 13:41
閱讀 2567·2019-08-26 13:41