どのような戦略パターンがあります
戦略モードアルゴリズムのパッケージである、とアルゴリズムの使用は、異なるオブジェクト管理に委任セグメンテーションアルゴリズム自体オフの責任である、そして最終的にアドレス倍数に実現することができるの判断ならば。
1.環境(コンテキスト)役割:戦略への参照を保持します。
2.抽象戦略(ストラテジー)の役割:これは通常、インターフェースや抽象クラスによって実装、抽象的役割です。このロールは、すべてのクラスのインターフェイスに必要な具体的な戦略を提供します。
3.具体的な戦略(ConcreteStrategy)役割:関連するアルゴリズムや振る舞いをパッケージ化。
定義された戦略インターフェース - >異なる戦略クラスを実装- >戦略は、マルチ状態を使用して呼び出し、またはそうでなければ
なぜ我々はと呼ばれているポリシーモードを行うには
政策として理解することができる場合は、各裁判官。
戦略モードの長所と短所
利点
アルゴリズムは自由に(役割を切り替えることがない高レベルのマスキングアルゴリズムを)切り替えることができます
複数の条件を使用しないでください(ほとんど同じ判決様々なアルゴリズムが存在することになる場合には、それを維持することは困難です)
グッドスケーラビリティ(キャンセレーションアルゴリズムを自由に追加することができ 、全体的な機能に影響を与えずに)
短所
クラス戦略の数の増加(各クラスの再利用のための戦略が必要で、アルゴリズムを増やす場合は、それが唯一のクラスを追加することができ、非常に小さいです)
すべてのポリシーは、外部被ばくクラスの必要があります(ストラテジーの使用を理解する必要があります使用し、必要な工場モード、プロキシモードなど他のモードを、補完します)
戦略モードのシナリオ
重合決済プラットフォーム
たとえば、この時には、そのようなアリペイ、マイクロチャネルの有料、キビの支払いなどが必要バット多くのサードパーティ決済インターフェースを、重合時間の決済プラットフォームを構築します。
伝統コード判断すれば、後半のメンテナンスが非常に悪いです!
S プリングの枠組みのモデルに使用される戦略
ClassPathXmlApplicationContext春は、基礎となるリソースインタフェースを戦略パターンを使用して
春のためのリソースは、次のインタフェースの実装クラスを提供します。
UrlResource :ネットワークリソースへの実装クラスへのアクセス。
A ClassPathResource :クラスローダ実装クラスのリソースでのアクセスパス。
FileSystemResource :ファイルシステムの実装クラスのリソースへのアクセス。
ServletContextResource :に関してアクセスのServletContextは、クラスパスリソースを実装します。
InputStreamResource :入力ストリームのリソースにアクセスするための実装クラス。
ByteArrayResourceを好む:実装クラスは、バイトのリソースの配列にアクセスします。
1 、新しいClassPathXmlApplicationContext( "");
コンストラクタへ2.。
3。
4.SpringBean 初期 SimpleInstantiationStrategy
SimpleInstantiationStrategy簡単な初期化戦略
CglibSubclassingInstantiationStrategy CGLIB初期化戦略
策略模式架构图
策略模式环境搭建
创建项目名称 springboot_ strategy
Maven依赖信息
1 <parent> 2 <groupId>org.springframework.boot</groupId> 3 <artifactId>spring-boot-starter-parent</artifactId> 4 <version>2.0.1.RELEASE</version> 5 </parent> 6 <dependencies> 7 <!-- sprinboot web --> 8 <dependency> 9 <groupId>org.springframework.boot</groupId> 10 <artifactId>spring-boot-starter-web</artifactId> 11 </dependency> 12 <dependency> 13 <groupId>org.projectlombok</groupId> 14 <artifactId>lombok</artifactId> 15 <version>1.16.10</version> 16 </dependency> 17 <dependency> 18 <groupId>commons-lang</groupId> 19 <artifactId>commons-lang</artifactId> 20 <version>2.6</version> 21 </dependency> 22 <dependency> 23 <groupId>org.mybatis.spring.boot</groupId> 24 <artifactId>mybatis-spring-boot-starter</artifactId> 25 <version>1.1.1</version> 26 </dependency> 27 <!-- mysql 依赖 --> 28 <dependency> 29 <groupId>mysql</groupId> 30 <artifactId>mysql-connector-java</artifactId> 31 </dependency> 32 </dependencies>
PayStrategy(抽象角色)
1 public interface PayStrategy { 2 3 /** 4 * 共同算法实现骨架 5 * @return 6 */ 7 public String toPayHtml(); 8 }
ConcreteStrategy (具体实现角色)
1 @Component 2 public class AliPayStrategy implements PayStrategy { 3 public String toPayHtml() { 4 return "调用支付宝支付接口"; 5 } 6 }
1 @Component 2 public class XiaoMiPayStrategy implements PayStrategy { 3 public String toPayHtml() { 4 return "调用小米支付接口"; 5 } 6 }
PayContextService (上下文)
@RestController public class PayContextService { @Autowired private PaymentChannelMapper paymentChannelMapper; @Autowired private SpringUtils springUtils;
@RequestMapping("/toPayHtml") public String toPayHtml(String payCode){ // 1.验证参数 if(StringUtils.isEmpty(payCode)){ return "payCode不能为空!"; } // 2.使用PayCode查询 PaymentChannelEntity paymentChannel = paymentChannelMapper.getPaymentChannel(payCode); if(paymentChannel==null){ return "该渠道为空..."; } // 3.获取策略执行的beanid String strategyBeanId = paymentChannel.getStrategyBeanId(); // 4.使用strategyBeanId获取对应spring容器bean信息 PayStrategy payStrategy = springUtils.getBean(strategyBeanId, PayStrategy.class); // 5.执行具体策略算法 return payStrategy.toPayHtml(); } }
SpringUtils(工具类)
1 @Component 2 public class SpringUtils implements ApplicationContextAware { 3 4 private static ApplicationContext applicationContext; 5 6 @Override 7 public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { 8 this.applicationContext = applicationContext; 9 } 10 11 //获取applicationContext 12 public static ApplicationContext getApplicationContext() { 13 return applicationContext; 14 } 15 16 //通过name获取 Bean. 17 public static Object getBean(String name){ 18 return getApplicationContext().getBean(name); 19 } 20 21 //通过class获取Bean. 22 public static <T> T getBean(Class<T> clazz){ 23 return getApplicationContext().getBean(clazz); 24 } 25 26 //通过name,以及Clazz返回指定的Bean 27 public static <T> T getBean(String name,Class<T> clazz){ 28 return getApplicationContext().getBean(name, clazz); 29 } 30 31 }
枚举类
1 public enum PayEnumStrategy { 2 3 /** 4 * 支付宝支付 5 */ 6 ALI_PAY("com.mayikt.strategy.impl.AliPayStrategy"), 7 /** 8 * 银联支付 9 */ 10 UNION_PAY("com.mayikt.strategy.impl.UnionPayStrategy"); 11 PayEnumStrategy(String className) { 12 this.setClassName(className); 13 } 14 15 public String getClassName() { 16 return className; 17 } 18 19 public void setClassName(String className) { 20 this.className = className; 21 } 22 23 /** 24 * class完整地址 25 */ 26 private String className; 27 28 }
StrategyFactory
1 public class StrategyFactory { 2 public static PayStrategy getPayStrategy(String strategyType) { 3 try { 4 // 1.获取枚举中className 5 String className = PayEnumStrategy.valueOf(strategyType).getClassName(); 6 // 2.使用java反射技术初始化类 7 return (PayStrategy) Class.forName(className).newInstance(); 8 } catch (Exception e) { 9 return null; 10 } 11 } 12 }
数据库访问层
相关SQL语句:
1 DROP TABLE IF EXISTS `payment_channel`; 2 CREATE TABLE `payment_channel` ( 3 `ID` int(11) NOT NULL AUTO_INCREMENT COMMENT 'ID', 4 `CHANNEL_NAME` varchar(32) NOT NULL COMMENT '渠道名称', 5 `CHANNEL_ID` varchar(32) NOT NULL COMMENT '渠道ID', 6 `strategy_bean_id` varchar(255) DEFAULT NULL COMMENT '策略执行beanid', 7 PRIMARY KEY (`ID`,`CHANNEL_ID`) 8 ) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=utf8 COMMENT='支付渠道 '; 9 10 -- ---------------------------- 11 -- Records of payment_channel 12 -- ---------------------------- 13 INSERT INTO `payment_channel` VALUES ('4', '支付宝渠道', 'ali_pay', 'aliPayStrategy'); 14 INSERT INTO `payment_channel` VALUES ('5', '小米支付渠道', 'xiaomi_pay', 'xiaoMiPayStrategy');
实体类
1 @Data 2 public class PaymentChannelEntity { 3 /** ID */ 4 private Integer id; 5 /** 渠道名称 */ 6 private String channelName; 7 /** 渠道ID */ 8 private String channelId; 9 /** 10 * 策略执行beanId 11 */ 12 private String strategyBeanId; 13 14 }
数据库访问层
1 public interface PaymentChannelMapper { 2 @Select("\n" + 3 "SELECT id as id ,CHANNEL_NAME as CHANNELNAME ,CHANNEL_ID as CHANNELID,strategy_bean_id AS strategybeanid\n" + 4 "FROM payment_channel where CHANNEL_ID=#{payCode}") 5 public PaymentChannelEntity getPaymentChannel(String payCode); 6 }
优点:策略模式最终帮助我们解决在实际开发中多重if判断问题、提高扩展性、维护性增强、提高代码可读性。
缺点:后期维护不同策略类是非常多、定义类比较多、代码量增大。
优点大于缺点。