博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
设计模式之策略模式
阅读量:3912 次
发布时间:2019-05-23

本文共 6875 字,大约阅读时间需要 22 分钟。

定义:策略模式(Strategy Pattern)又叫也叫政策模式(Policy Pattern),他是将定义的算法家族,分别封装起来,让它们之间可以互相替换,从而让算法的变化不会影响到使用算法的用户.

可以避免多重分支的if…else…和switch语句

属于行为型模式

适用场景

1.假如系统中有很多类,而他们的区别仅仅在于他们的行为不同.
2.一个系统需要动态地在几种算法中选择一种.
3.需要屏蔽算法规则

优点

1.策略模式符合开闭原则
2.避免使用多重条件转移语句,如if…else…语句,switch语句
3.使用策略模式可以提高算法的保密性和安全性

缺点

1.客户端必须知道所有的策略,并且自行决定使用哪一个策略类
2.代码中会产生非常多策略类,增加维护难度.

例子

一般用法
public interface IStrategy {
void algorithm();}
public class Context {
private IStrategy mStrategy; public Context(IStrategy mStrategy){
this.mStrategy = mStrategy; } public void algorithm(){
this.mStrategy.algorithm(); }}
public class ConcreteStrategyA implements IStrategy{
@Override public void algorithm() {
System.out.println("Strategy A"); }}
public class ConcreteStrategyB implements IStrategy{
@Override public void algorithm() {
System.out.println("Strategy B"); }}
public class Test {
public static void main(String[] args) {
IStrategy strategy = new ConcreteStrategyA(); Context context = new Context(strategy); context.algorithm(); context = new Context(new ConcreteStrategyB()); context.algorithm(); }}
具体例子
public interface IPromotionStrategy {
void doPromotion();}
public class PromotionActivity {
private IPromotionStrategy strategy; public PromotionActivity(IPromotionStrategy strategy) {
this.strategy = strategy; } public void execute(){
this.strategy.doPromotion(); }}
public class CashbackStrategy implements IPromotionStrategy{
@Override public void doPromotion() {
System.out.println("使用返现策略"); }}
public class CouponStrategy implements IPromotionStrategy {
@Override public void doPromotion() {
System.out.println("使用优惠卷"); }}
public class EmptyStrategy implements IPromotionStrategy{
@Override public void doPromotion() {
System.out.println("无优惠"); }}
public class GroupBuyStrategy implements IPromotionStrategy{
@Override public void doPromotion() {
System.out.println("3人成团,可以优惠"); }}
public class PromotionStrategyFactory {
private static Map
PROMOTIONS = new HashMap<>(); private PromotionStrategyFactory(){
} static {
PROMOTIONS.put(PromotionKey.COUPON,new CouponStrategy()); PROMOTIONS.put(PromotionKey.CASHBACK,new CashbackStrategy()); PROMOTIONS.put(PromotionKey.GROUPBUY,new GroupBuyStrategy()); } private static final IPromotionStrategy EMPTY = new EmptyStrategy(); public static IPromotionStrategy getPromotionStrategy(String promotionKey){
IPromotionStrategy strategy = PROMOTIONS.get(promotionKey); return strategy == null ? EMPTY : strategy; } private interface PromotionKey{
String COUPON = "COUPON"; String CASHBACK = "CASHBACK"; String GROUPBUY = "GROUPBUY"; } public static Set
getPromotionKeys(){
return PROMOTIONS.keySet(); }}
public class Test {
public static void main(String[] args) {
PromotionStrategyFactory.getPromotionKeys(); String promotionKey = "COUPON"; IPromotionStrategy promotionStrategy = PromotionStrategyFactory.getPromotionStrategy(promotionKey); promotionStrategy.doPromotion(); }}
支付方式使用策略模式
public abstract class Payment {
public abstract String getName(); //通用逻辑放到抽象类里面实现 public MsgResult pay(String uid, double amount){
// 余额是否足够 if(queryBalance(uid) < amount){
return new MsgResult(500,"支付失败","余额不足"); } return new MsgResult(200,"支付成功","支付金额" + amount); } protected abstract double queryBalance(String uid);}
public class AliPay extends Payment{
public String getName(){
return "支付宝"; } @Override protected double queryBalance(String uid) {
return 999; }}
public class JDPay extends Payment{
public String getName(){
return "京东支付"; } @Override protected double queryBalance(String uid) {
return 988; }}
public class UnionPay extends Payment{
public String getName(){
return "银联支付"; } @Override protected double queryBalance(String uid) {
return 1000; }}
public class WechatPay extends Payment {
@Override public String getName() {
return "微信支付"; } @Override protected double queryBalance(String uid) {
return 0; }}
public class PayStrategy {
public static final String ALI_PAY = "AliPay"; public static final String JD_PAY = "JDPay"; public static final String WECHAT_PAY = "WechatPay"; public static final String UNION_PAY = "UnionNPay"; public static final String DEFAULT_PAY = ALI_PAY; private static Map
strategy = new HashMap<>(); static {
strategy.put(ALI_PAY,new AliPay()); strategy.put(JD_PAY,new JDPay()); strategy.put(WECHAT_PAY,new WechatPay()); strategy.put(UNION_PAY,new UnionPay()); } public static Payment get(String payKey){
if(!strategy.containsKey(payKey)){
return strategy.get(DEFAULT_PAY); } return strategy.get(payKey); }}
public class MsgResult {
private int code; private Object data; private String msg; public MsgResult(int code, Object data, String msg) {
this.code = code; this.data = data; this.msg = msg; } public int getCode() {
return code; } public void setCode(int code) {
this.code = code; } public String getMsg() {
return msg; } public void setMsg(String msg) {
this.msg = msg; } public Object getData() {
return data; } public void setData(Object data) {
this.data = data; } @Override public String toString() {
return "MsgResult{" + "code=" + code + ", msg='" + msg + '\'' + ", data=" + data + '}'; }}
public class Order {
private String uid; private String orderId; private double amount; public Order(String uid, String orderId, double amount) {
this.uid = uid; this.orderId = orderId; this.amount = amount; } public MsgResult pay(){
return pay(null); } public MsgResult pay(String payKey){
Payment payment = PayStrategy.get(payKey); System.out.println("欢迎使用" + payment.getName()); System.out.println("本次交易金额为: " + amount + ".开始扣款"); return payment.pay(uid,amount); }}
*/public class Test {
public static void main(String[] args) {
Order order = new Order("1","2020092709341212",521); System.out.println(order.pay(PayStrategy.JD_PAY)); }}

转载地址:http://akjrn.baihongyu.com/

你可能感兴趣的文章
.NET架构小技巧(5)——反射,架构人员法宝III
查看>>
C# 中的 in 参数和性能分析
查看>>
.NET架构小技巧(6)——什么是好的架构
查看>>
C#中形态各异的class
查看>>
.Net 5性能改进
查看>>
InfluxDB 2.0 之Flux语法篇
查看>>
TensorFlow 2学习和工业CV领域应用 心得分享
查看>>
程序员过关斩将--真的可以用版本号的方式来保证MQ消费消息的幂等性?
查看>>
Java面试必问JVM调优,那.NET5呢?
查看>>
把 Console 部署成 Windows 服务,四种方式总有一款适合你!
查看>>
缓存一致性和跨服务器查询的数据异构解决方案canal
查看>>
BeetleX之Websocket服务使用
查看>>
【源码】常用的人脸识别数据库以及上篇性别识别源码
查看>>
深入探究ASP.NET Core Startup的初始化
查看>>
跟我一起学Redis之Redis配置文件啃了一遍之后,从尴尬变得有底气了(总结了一张思维图)...
查看>>
一路踩坑,被迫聊聊 C# 代码调试技巧和远程调试
查看>>
IdentityServer4系列 | 资源密码凭证模式
查看>>
TIOBE 11 月榜单:Python 挤掉 Java,Java的下跌趋势确立了?
查看>>
C#实现观察者模式
查看>>
使用Azure静态Web应用部署Blazor Webassembly应用
查看>>