摘要:閱讀原文把策略模式應用到實際項目中無論你知不知道這個設計模式,但必定在項目中都似曾相識。文件存儲的方式不同,同時文件的獲取和刪除也不同保存,獲取,刪除后的響應也是相同的,也不考慮了。此時引入是解決問題的最佳方式。
閱讀原文:把「策略模式」應用到實際項目中
無論你知不知道這個設計模式,但必定在項目中都似曾相識。倘若僅僅聊理論必然枯燥乏味,只有理論和實戰相結合方可達到人劍合一的境界。
首先,我來說個需求,倘若是你遇到該如何做?你可停留幾分鐘,想出你的解決方式,可在下方留言,說出你的想法。
需求用戶有文件上傳的需求,而我們要負責對文件進行存儲,由于我們的系統可能會多帶帶給個別客戶私有化部署(部署盡量少依賴中間件能服務等),同時我們也會自己運營成為自己的SaaS服務(保證服務的高可用等)。
所以我們有兩點需求:
要在SaaS版本中將文件存入分布式存儲系統fastDfs中
客戶的私有部署中將文件?存儲在數據庫中
思路 尋找異同點文件上傳過程這個無論什么版本部署都是一樣的,所以暫不考慮。
文件存儲的方式不同,同時文件的獲取和刪除也不同
保存,獲取,刪除后的響應也是相同的,也不考慮了。
開始抽象當前我們考慮的就是文件的存儲,獲取和刪除了。同樣的行為,不同的實現,我們必定想到定義一個接口:
/** * 文件存儲接口 * Identify表示文件的唯一標識,可任意類型 * 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); }
存儲FastDfs
@Slfj @Service("fastDfsServiceImpl") public class FastDfsServiceImpl implements IStorageService{ @Override @Transactional(rollbackFor = Exception.class) public FileVo upload(MultipartFile multipartFile){ logger.info("存儲在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刪除文件"); } }
存儲 數據庫
@Slfj @Service("databaseServiceImpl") public class DatabaseServiceImpl implements IStorageService{ @Override @Transactional(rollbackFor = Exception.class) public FileVo upload(MultipartFile file) { logger.info("存儲在database……"); return null; } @Override public FileVo download(String hash) { logger.info("從database下載文件"); return null; } @Override public void delete(String hash) { logger.info("從database刪除文件"); } }
調用
@Service public class FileServiceImpl implements FileService { // 同一個接口根據不同的名稱調用不同的實現 // @Qualifier("databaseServiceImpl") @Qualifier("fastDfsServiceImpl") @Autowired private IStorageService storageService; public void save(MultipartFile file){ if (null == file) { throws new Exception("文件不能為空"); } FileVo fileVo = storageService.upload(file); } }疑惑
可能有人會說了:這怎么和我了解的策略模式不一樣啊,策略模式不是這樣的嗎?
你說的對!但這是在沒有任何框架下的設計模式,而我們現在普遍使用的都是Spring框架,那么標準的策略模式中的Context去哪里了?
引入Context的作用
首先我們要知道引入Context的作用,是為了避免高層直接與策略接口直接交互,為什么呢?因為我們策略模式接口功能相對比較單一,而有些高層模塊可能需要一些比較復雜的交互。
若直接調用接口,則需要對每個實現增加邏輯;
若直接調用前,執行增強邏輯,那么多個地方使用時,會存在重復增強邏輯,并可能忘掉。
此時引入Context是解決問題的最佳方式。
而我們的FileServiceImpl就相當于Context的作用,由于我們使用Spring框架且使用了三層架構,暴露上傳文件、下載文件、刪除文件是在controller層三個不同的方法中(或不同的controller中),為了避免幾個地方使用的存儲策略不同,我直接在Context中來指定使用的策略,當需要切換時也非常方便,只需要更改IStorageService的注解即可。
總結 優點策略實現類可自由切換
易于擴展,若還有新的策略只要新增策略接口一個實現類即可
不必使用條件語句進行決定使用哪個策略
缺點策略類一旦增多,調用者要清楚的知道各種策略的區別
如果你有不同的看法,還望不吝指教。
更多精彩技術文章盡在微信公眾號:碼上實戰
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/74282.html
摘要:設計模式無論是對于最底層的的編碼實現還是較高層的架構設計都有著重要的指導作用。所謂光說不練假把式,今天我就把項目中常見的應用場景涉及到的主要設計模式及其相關設計模式總結一下,用實例分析和對比的方式在一片文章中就把最常見的種設計模式梳理清楚。 設計模式無論是對于最底層的的編碼實現還是較高層的架構設計都有著重要的指導作用。所謂光說不練假把式,今天我就把項目中常見的應用場景涉及到的主要設計模...
摘要:命令模式的由來,其實是回調函數的一個面向對象的替代品,命令模式早已融入到了語言之中。 模式是對某情景下,針對某種問題的某種解決方案。而一個設計模式是用來解決一個經常出現的設計問題的經驗方法。這么說來,每個模式都可能有著自己的意圖,應用場景,使用方法和使用后果。本文的行文思路和目的皆在于了解各個模式的定義,應用場景和用實例說明如何在前端開發中使用。 本文所設計到的概念和實例大多來自《H...
摘要:版本策略模式在上個例子中雖然初步實現了策略模式,但是是仿照的傳統面向對象語言,而的實現更為簡單,直接把原來的實例定義成函數,原先的類用函數來委托。 1. 介紹 策略模式是JS設計模式中一大重要的模式有著廣泛的應用 2. 定義 定義一系列的算法,把它們一個個封裝起來,并且使它們可以相互替換 3. 應用 根據等級、工資計算獎金等類似情況、使用不同的動畫效果、表單驗證等 4. 思想 把算法實...
閱讀 4391·2021-11-19 09:59
閱讀 3320·2021-10-12 10:12
閱讀 2631·2021-09-22 15:25
閱讀 3321·2019-08-30 15:55
閱讀 1183·2019-08-29 11:27
閱讀 1463·2019-08-28 18:06
閱讀 2736·2019-08-26 13:41
閱讀 2554·2019-08-26 13:41