日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > asp.net >内容正文

asp.net

精讲23种设计模式-策略模式~聚合短信服务和聚合支付服务

發布時間:2024/9/27 asp.net 36 豆豆
生活随笔 收集整理的這篇文章主要介紹了 精讲23种设计模式-策略模式~聚合短信服务和聚合支付服务 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

文章目錄

          • 一、設計模式
            • 1. 為什么需要使用設計模式
            • 2. 設計模式的分類
            • 3. 什么是策略模式
            • 4. 為什么叫做策略模式
            • 5. 策略模式優缺點
            • 6. 策略模式應用場景
            • 7. Spring框架中使用的策略模式
          • 二、策略模式~聚合短信服務
            • 2.1. 依賴引入
            • 2.2. 抽象公共行為接口
            • 2.3. 具體策略接口實現類
            • 2.4. 策略枚舉
            • 2.5. 獲取具體策略實現
            • 2.6. 策略工廠
            • 2.7. 聚合短信服務測試
          • 三、聚合短信服務2
            • 3.1. 策略工廠調整
            • 3.2. 聚合短信測試
          • 四、聚合短信3
            • 4.1. 策略上下文
            • 4.2. SpringContext上下文工具類
            • 4.3. 聚合短信測試
          • 五、聚合短信+聚合支付(企業內部升級)
            • 5.1. 相關SQL語句
            • 5.2. 策略實體
            • 5.3. 策略接口
            • 5.4.策略上下文
            • 5.5. 聚合短信和聚合支付測試
            • 5.6. mapper掃描配置
            • 5.7. 依賴
            • 5.8. yml配置
            • 5.9. 開源地址

一、設計模式
1. 為什么需要使用設計模式

使用設計模式可以重構整體架構代碼、提交代碼復用性、擴展性、減少代碼冗余問題。

2. 設計模式的分類

創建型模式
工廠方法模式、抽象工廠模式、單例模式、建造者模式、原型模式。
結構型模式
適配器模式、裝飾器模式、代理模式、外觀模式、橋接模式、組合模式、享元模式
行為模式
策略模式、模板方法模式、觀察者模式、迭代子模式、責任鏈模式、命令模式、備忘錄模式、狀態模式、訪問者模式、中介者模式、解釋器模式。

策略模式

3. 什么是策略模式

策略模式是對算法的包裝,是把使用算法的責任和算法本身分割開來,委派給不同的對象管理,最終可以實現解決多重if判斷問題。

1.環境(Context)角色:持有一個Strategy的引用。
2.抽象策略(Strategy)角色:這是一個抽象角色,通常由一個接口或抽象類實現。此角色給出所有的具體策略類所需的接口。
3.具體策略(ConcreteStrategy)角色:包裝了相關的算法或行為。

定義策略接口->實現不同的策略類->利用多態或其他方式調用策略

4. 為什么叫做策略模式

每個if判斷都可以理解為就是一個策略。

5. 策略模式優缺點

優點
算法可以自由切換(高層屏蔽算法,角色自由切換)
避免使用多重條件判斷(如果算法過多就會出現很多種相同的判斷,很難維護)
擴展性好(可自由添加取消算法 而不影響整個功能)
缺點
策略類數量增多(每一個策略類復用性很小,如果需要增加算法,就只能新增類)
所有的策略類都需要對外暴露(使用的人必須了解使用策略,這個就需要其它模式來補充,比如工廠模式、代理模式)

6. 策略模式應用場景

聚合支付平臺
比如搭建聚合支付平臺的時候,這時候需要對接很多第三方支付接口,比如支付寶、微信支付、小米支付等。
通過傳統if代碼判斷的,后期的維護性非常差!
這時候可以通過策略模式解決多重if判斷問題。

7. Spring框架中使用的策略模式

ClassPathXmlApplicationContext Spring底層Resource接口采用策略模式

Spring 為 Resource 接口提供了如下實現類:
UrlResource:訪問網絡資源的實現類。
ClassPathResource:訪問類加載路徑里資源的實現類。
FileSystemResource:訪問文件系統里資源的實現類。
ServletContextResource:訪問相對于 ServletContext 路徑里的資源的實現類:
InputStreamResource:訪問輸入流資源的實現類。
ByteArrayResource:訪問字節數組資源的實現類。
1、new ClassPathXmlApplicationContext("");
2.進入該構造函數


4.SpringBean初始化 SimpleInstantiationStrategy

SimpleInstantiationStrategy 簡單初始化策略
CglibSubclassingInstantiationStrategy CGLIB初始化策略

二、策略模式~聚合短信服務

2.1. 依賴引入
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.6.4</version><relativePath/> <!-- lookup parent from repository --></parent><groupId>com.gblfy</groupId><artifactId>design-pattern</artifactId><version>0.0.1-SNAPSHOT</version><name>design-pattern</name><description>design-pattern</description><properties><java.version>1.8</java.version></properties><dependencies><!--字符串工具類--><dependency><groupId>org.apache.commons</groupId><artifactId>commons-lang3</artifactId><version>3.12.0</version></dependency><!--數據json處理--><dependency><groupId>com.alibaba</groupId><artifactId>fastjson</artifactId><version>1.2.79</version></dependency><!--SpringMVC--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><optional>true</optional></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency></dependencies><build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId><configuration><excludes><exclude><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId></exclude></excludes></configuration></plugin></plugins></build></project>
2.2. 抽象公共行為接口

MsgStrategy

package com.gblfy.strategy;/*** 抽象公共行為接口** @author gblfy* @date 2022-03-13*/ public interface MsgStrategy {/*** 共同行為方法** @param phone* @return*/String sendMsg(String phone); }
2.3. 具體策略接口實現類

調用(阿里云)短信息服務

package com.gblfy.strategy.impl;import com.gblfy.strategy.MsgStrategy; import org.springframework.stereotype.Service;/*** 調用(阿里云)短信息服務** @author gblfy* @date 2022-03-13*/ @Service public class AliYunStrategy implements MsgStrategy {@Overridepublic String sendMsg(String phone) {return "調用(阿里云)短信息服務";} }

調用(華為云)短信息服務

package com.gblfy.strategy.impl;import com.gblfy.strategy.MsgStrategy; import org.springframework.stereotype.Service;/*** 調用(華為云)短信息服務** @author gblfy* @date 2022-03-13*/ @Service public class HuaWeiStrategy implements MsgStrategy {@Overridepublic String sendMsg(String phone) {return "調用(華為云)短信息服務";} }

調用(騰訊云)短信息服務

package com.gblfy.strategy.impl;import com.gblfy.strategy.MsgStrategy; import org.springframework.stereotype.Service;/*** 調用(騰訊云)短信息服務** @author gblfy* @date 2022-03-13*/ @Service public class TencentStrategy implements MsgStrategy {@Overridepublic String sendMsg(String phone) {return "調用(騰訊云)短信息服務";} }
2.4. 策略枚舉
package com.gblfy.enums;/*** 策略枚舉,存放所有策略的實現** @author gblfy* @date 2022-03-13*/ public enum SmsEnumStrategy {/*** 支付寶短信*/ALI_SMS("com.gblfy.strategy.impl.AliYunStrategy"),/*** 華為云短信*/HUAWEI_SMS("com.gblfy.strategy.impl.HuaWeiStrategy"),/*** 騰訊云短信*/TENCENT_SMS("com.gblfy.strategy.impl.TencentStrategy");/*** class 名稱*/private String className;SmsEnumStrategy(String className) {this.setClassName(className);}public String getClassName() {return className;}public void setClassName(String className) {this.className = className;} }
2.5. 獲取具體策略實現
package com.gblfy.strategy;import com.gblfy.factory.StrategyFactory; import org.apache.commons.lang3.StringUtils; import org.springframework.stereotype.Component;/*** 獲取具體策略實現** @author gblfy* @date 2022-03-13*/ @Component public class SmsContextStrategy {/*** 獲取具體策略實現*/public String getStrategy(String strategyId, String phone) {if (StringUtils.isEmpty(strategyId)) {return "paycode 不能為空";}// 第1種:使用策略工廠獲取具體策略的實現MsgStrategy msgStrategy = StrategyFactory.getPayStrategy(strategyId);if (msgStrategy == null) {return ",沒有找到具體策略的實現...";}return msgStrategy.sendMsg(phone);} }
2.6. 策略工廠
package com.gblfy.factory;import com.gblfy.enums.SmsEnumStrategy; import com.gblfy.strategy.MsgStrategy;/*** 使用策略工廠獲取具體策略實現** @author gblfy* @date 2022-03-13*/ public class StrategyFactory {//工廠初始化public static MsgStrategy getPayStrategy(String strategyType) {try {// 1.獲取枚舉中classNameString className = SmsEnumStrategy.valueOf(strategyType).getClassName();// 2.使用java反射技術初始化類return (MsgStrategy) Class.forName(className).newInstance();} catch (Exception e) {return null;}} }
2.7. 聚合短信服務測試
/*** 測試鏈接:* http://localhost:8080/sendMsgByEnumSfactory?strategyId=ALI_SMS&phone=123456* http://localhost:8080/sendMsgByEnumSfactory?strategyId=HUAWEI_SMS&phone=123456* http://localhost:8080/sendMsgByEnumSfactory?strategyId=TENCENT_SMS&phone=123456*/ package com.gblfy.controller;import com.gblfy.strategy.SmsContextStrategy; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController;@RestController public class MsgController {@Autowiredprivate SmsContextStrategy contextStrategy;/*** 使用枚舉+工廠+策略模式實現聚合短信服務* * @param strategyId 策略ID* @param phone 手機號碼* @return*/@GetMapping("/sendMsgByEnumSfactory")public String sendMsgByEnumSfactory(@RequestParam("strategyId") String strategyId,@RequestParam("phone") String phone) {return contextStrategy.getStrategy(strategyId, phone);}/*** 測試鏈接:* http://localhost:8080/sendMsgByEnumSfactory?strategyId=ALI_SMS&phone=123456* http://localhost:8080/sendMsgByEnumSfactory?strategyId=HUAWEI_SMS&phone=123456* http://localhost:8080/sendMsgByEnumSfactory?strategyId=TENCENT_SMS&phone=123456*/ }

三、聚合短信服務2

1.使用工廠模式初始化具體策略class
2.將所有具體實現的策略存放到map集合中(枚舉類中)
3.key:ALI_PAY value:com.gblfy.service.AliPayStrategy

3.1. 策略工廠調整
package com.gblfy.factory;import com.gblfy.strategy.MsgStrategy; import com.gblfy.strategy.impl.AliYunStrategy; import com.gblfy.strategy.impl.HuaWeiStrategy; import com.gblfy.strategy.impl.TencentStrategy;import java.util.Map; import java.util.concurrent.ConcurrentHashMap;public class FactoryStrategy {private static Map<String, MsgStrategy> msgStrategyMap = new ConcurrentHashMap<>();static {msgStrategyMap.put("huawei", new HuaWeiStrategy());msgStrategyMap.put("tencent", new TencentStrategy());msgStrategyMap.put("aliyun", new AliYunStrategy());}public static MsgStrategy getContextStrategy(String strategyId) {return msgStrategyMap.get(strategyId);} }
3.2. 聚合短信測試
package com.gblfy.controller;import com.gblfy.factory.FactoryStrategy; import com.gblfy.strategy.MsgStrategy; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController;@RestController public class MsgController {/*** 使用工廠+策略模式實現聚合短信服務** @param strategyId* @param phone* @return*/@GetMapping("/sendMsgByfactory")public String sendMsgByfactory(@RequestParam("strategyId") String strategyId,@RequestParam("phone") String phone) {MsgStrategy contextStrategy = FactoryStrategy.getContextStrategy(strategyId);return contextStrategy.sendMsg(phone);}/*** 測試鏈接:* http://localhost:8080/sendMsgByfactory?strategyId=huawei&phone=123456* http://localhost:8080/sendMsgByfactory?strategyId=tencent&phone=123456* http://localhost:8080/sendMsgByfactory?strategyId=aliyun&phone=123456*/ }
四、聚合短信3

使用springIOC代替反射,提高效率,動態切換(無需改動項目)

4.1. 策略上下文
package com.gblfy.strategy;import com.gblfy.utils.SpringContextUtils; import org.apache.commons.lang3.StringUtils; import org.springframework.stereotype.Component;@Component public class StrategyContext {public MsgStrategy getStrategy(String strategyId) {if (StringUtils.isEmpty(strategyId)) {return null;}return SpringContextUtils.getBean(strategyId, MsgStrategy.class);}}
4.2. SpringContext上下文工具類
package com.gblfy.utils;import org.springframework.beans.BeansException; import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationContextAware; import org.springframework.stereotype.Component;/*** 獲取Spring上下文工具類** @author gblfy* @date 2022-03-13*/ @Component public class SpringContextUtils implements ApplicationContextAware {private static ApplicationContext applicationContext;@Overridepublic void setApplicationContext(ApplicationContext applicationContext) throws BeansException {SpringContextUtils.applicationContext = applicationContext;}//獲取applicationContextpublic static ApplicationContext getApplicationContext() {return applicationContext;}//通過name獲取 Bean.public static Object getBean(String name) {return getApplicationContext().getBean(name);}//通過class獲取Bean.public static <T> T getBean(Class<T> clazz) {return getApplicationContext().getBean(clazz);}//通過name,以及Clazz返回指定的Beanpublic static <T> T getBean(String name, Class<T> clazz) {return getApplicationContext().getBean(name, clazz);}}
4.3. 聚合短信測試
/*** 使用工廠+策略模式+SpringIOC實現聚合短信服務** @param strategyId* @param phone* @return*/@GetMapping("/sendMsgBySpringIOC")public String sendMsgBySpringIOC(@RequestParam("strategyId") String strategyId,@RequestParam("phone") String phone) {MsgStrategy contextStrategy = strategyContext.getStrategy(strategyId);return contextStrategy.sendMsg(phone);}/*** 測試鏈接:* http://localhost:8080/sendMsgBySpringIOC?strategyId=aliYunStrategy&phone=123456* http://localhost:8080/sendMsgBySpringIOC?strategyId=huaWeiStrategy&phone=123456* http://localhost:8080/sendMsgBySpringIOC?strategyId=tencentStrategy&phone=123456*/
五、聚合短信+聚合支付(企業內部升級)
5.1. 相關SQL語句
drop database IF EXISTS `design_pattern`; create database `design_pattern`; use `design_pattern`;SET NAMES utf8mb4; SET FOREIGN_KEY_CHECKS = 0;-- ---------------------------- -- Table structure for gblfy_strategy -- ---------------------------- DROP TABLE IF EXISTS `gblfy_strategy`; CREATE TABLE `gblfy_strategy` (`id` int NOT NULL AUTO_INCREMENT COMMENT 'ID',`strategy_name` varchar(32) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '策略名稱',`strategy_id` varchar(32) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '策略ID',`strategy_type` int NOT NULL COMMENT '策略類型(0-支付服務,1-短信服務)',`strategy_bean_id` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '策略執行beanid實例',`deleted` int NOT NULL COMMENT '邏輯刪除字段(0-有效 1-無效,默認為0)',PRIMARY KEY (`id`) USING BTREE ) ENGINE = InnoDB AUTO_INCREMENT = 11 CHARACTER SET = utf8 COLLATE = utf8_general_ci COMMENT = '策略配置表' ROW_FORMAT = Dynamic;-- ---------------------------- -- Records of gblfy_strategy -- ---------------------------- INSERT INTO `gblfy_strategy` VALUES (6, '騰訊云短信', 'tencent_sms', 1, 'tencentStrategy', 0); INSERT INTO `gblfy_strategy` VALUES (7, '阿里云短信', 'aliYun_sms', 1, 'aliYunStrategy', 0); INSERT INTO `gblfy_strategy` VALUES (8, '華為云短信', 'huaWei_sms', 1, 'huaWeiStrategy', 0); INSERT INTO `gblfy_strategy` VALUES (9, '阿里支付', 'ali_pay', 0, 'aliPayStrategy', 0); INSERT INTO `gblfy_strategy` VALUES (10, '銀聯支付', 'yinlian_pay', 0, 'unionPayStrategy', 0);SET FOREIGN_KEY_CHECKS = 1;
5.2. 策略實體
package com.gblfy.entity;import com.baomidou.mybatisplus.annotation.*; import lombok.Data;@Data @TableName("gblfy_strategy") public class GblfyStrategy {// 策略配置主鍵@TableId(value = "id", type = IdType.ASSIGN_ID)private Long id;//策略名稱(阿里云短信、銀聯支付)@TableField("strategy_name")private String strategyName;//策略ID@TableField("strategy_id")private String strategyId;//策略類型(發短信或者調用支付)@TableField("strategy_type")private String strategyType;//策略具體執行beanId@TableField("strategy_bean_id")private String strategyBeanId;//邏輯刪除字段@TableLogicprivate Integer deleted; }
5.3. 策略接口
package com.gblfy.mapper;import com.baomidou.mybatisplus.core.mapper.BaseMapper; import com.gblfy.entity.GblfyStrategy;/*** 策略接口** @author gblfy* @date 2022-03-13*/ public interface StragegyMapper extends BaseMapper<GblfyStrategy> { }
5.4.策略上下文
package com.gblfy.strategy;import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.gblfy.entity.GblfyStrategy; import com.gblfy.mapper.StragegyMapper; import com.gblfy.utils.SpringContextUtils; import org.apache.commons.lang3.StringUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component;@Component public class StrategyContext {@Autowiredprivate StragegyMapper stragegyMapper;// public MsgStrategy getStrategy(String strategyId) {// if (StringUtils.isEmpty(strategyId)) {// return null;// }// return SpringContextUtils.getBean(strategyId, MsgStrategy.class);// }// public <T> T getStrategy(String stragegyId,Class<T> t){// if (StringUtils.isEmpty(stragegyId)){// return null;// }// return SpringContextUtils.getBean(stragegyId, t);// }public <T> T getStrategy(String stragegyId, String stragegyType, Class<T> t) {if (StringUtils.isEmpty(stragegyId)) {return null;}if (StringUtils.isEmpty(stragegyType)) {return null;}if (t == null) {return null;}//根據策略id和策略類型查詢具體策略實例beanIdGblfyStrategy gblfyStrategy = stragegyMapper.selectOne(new QueryWrapper<GblfyStrategy>().lambda().eq(GblfyStrategy::getStrategyId, stragegyId).eq(GblfyStrategy::getStrategyType, stragegyType));if (gblfyStrategy == null) {return null;}String strategyBeanId = gblfyStrategy.getStrategyBeanId();if (StringUtils.isEmpty(strategyBeanId)) {return null;}return SpringContextUtils.getBean(strategyBeanId, t);} }
5.5. 聚合短信和聚合支付測試
/*** 多個不同服務(短信+支付)抽象封裝* mysql+SpringIOC+策略模式實現聚合短信服務和聚合支付服務** @param strategyId* @param stragegyType* @param phone* @return*/@GetMapping("/sendMsgByMysqlAndSpringIOC")public String sendMsgBySpringIOC(@RequestParam("strategyId") String strategyId,@RequestParam("stragegyType") String stragegyType,@RequestParam("phone") String phone) {MsgStrategy strategy = strategyContext.getStrategy(strategyId, stragegyType, MsgStrategy.class);if (strategy == null) {return "當前渠道已關閉或者不存在,請核實!";}return strategy.sendMsg(phone);}/*** 測試鏈接(聚合短信):* http://localhost:8080/sendMsgByMysqlAndSpringIOC?strategyId=ali_pay&stragegyType=1&phone=123456* http://localhost:8080/sendMsgByMysqlAndSpringIOC?strategyId=ali_pay&stragegyType=1&phone=123456* http://localhost:8080/sendMsgByMysqlAndSpringIOC?strategyId=ali_pay&stragegyType=1&phone=123456** 測試鏈接(聚合支付):* http://localhost:8080/sendMsgByMysqlAndSpringIOC?strategyId=ali_pay&stragegyType=0&phone=123456*/
5.6. mapper掃描配置
package com.gblfy.config;import org.mybatis.spring.annotation.MapperScan; import org.springframework.context.annotation.Configuration;@Configuration @MapperScan("com.gblfy.mapper") public class MybatisPlusConfig {}
5.7. 依賴
<!--mybatis-plus 持久化--><dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-boot-starter</artifactId><version>3.5.1</version></dependency><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><scope>runtime</scope></dependency>
5.8. yml配置
server:port: 8080 spring:datasource:username: rootpassword: 123456driver-class-name: com.mysql.cj.jdbc.Driverurl: jdbc:mysql://127.0.0.1:3306/design_pattern?useUnicode=true&characterEncoding=UTF-8 logging:level:com.gblfy.mapper: DEBUG mybatis-plus:configuration:log-impl:mapper-locations: classpath:mappers/*.xml
5.9. 開源地址

https://gitee.com/gblfy/design-pattern

總結

以上是生活随笔為你收集整理的精讲23种设计模式-策略模式~聚合短信服务和聚合支付服务的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。