JAVA 设计模式-策略模式

简介: 策略模式(Strategy Pattern) 也叫 政策模式(Policy Pattern)。指的是对象具备某个行为,但是在不同的场景中,该行为有不同的实现算法

JAVA设计模式-策略模式

什么是策略模式

策略模式(Strategy Pattern) 也叫 政策模式(Policy Pattern)指的是对象具备某个行为,但是在不同的场景中,该行为有不同的实现算法。比如一个人的交税比率与他的工资有关,不同的工资水平对应不同的税率。

策略模式使用的就是面向对象的继承和多态机制,从而实现同一行为在不同场景下具备不同实现。

策略模式本质:分离算法,选择实现

场景

·       针对同一类型问题,有多种处理方式,每一种都能独立解决问题;

·       算法需要自由切换的场景;

·       需要屏蔽算法规则的场景;

优缺点

优点

·       算法多样性,且具备自由切换功能;

·       有效避免多重条件判断,增强了封装性,简化了操作,降低出错概率;

·       扩展性良好,策略类遵顼 里氏替换原则,可以很方便地进行策略扩展;

缺点

·       策略类数量增多,且所有策略类都必须对外暴露,以便客户端能进行选择;

模式讲解

基础用法

大家都知道商城经常会有优惠活动,但是优惠策略会有多种可能。比如:领取优惠券、返现促销、拼团优惠等。

我们可以通过策略模式来实现。

抽象类

首先创建一个促销策略的抽象类:

public interface IPromotionStrategy {
    void doPromotion();
}



实现类

然后分别创建优惠券抵扣策略、返现促销策略、拼团优惠策略及无优惠策略。

public class CouponStrategy implements IPromotionStrategy {
    public void doPromotion() {
        System.out.println("使用优惠券抵扣");
    }
}
public class CashbackStrategy implements IPromotionStrategy {
    public void doPromotion() {
        System.out.println("返现,直接打款到支付宝账号");
    }
}
public class GroupbuyStrategy implements IPromotionStrategy {
    public void doPromotion() {
        System.out.println("5人成团,可以优惠");
    }
}
public class EmptyStrategy implements IPromotionStrategy {
    public void doPromotion() {
        System.out.println("无优惠");
    }
}



然后创建促销活动方案类:

public class PromotionActivity {
    private IPromotionStrategy strategy;
    public PromotionActivity(IPromotionStrategy strategy) {
        this.strategy = strategy;
    }
    public void execute(){
        strategy.doPromotion();
    }
}



策略模式在云巧中的应用

4A 组件的 SDK 中,通过策略模式实现了支持多种登录方式

定义登录的关键接口

public interface IClientForSession {
    /**
     * 根据 token 获取用户信息
     * @param accessToken
     * @return
     */
    ReturnT<UserInfo> describeUserSessionInfo(String accessToken);
    /**
     * 销毁 session 会话
     * @param sessionId
     * @return
     */
    ReturnT invalidSessionId(String sessionId);
}



通过实现关键接口对接不同的用户中心

对接 CAS

public class IClientForSessionImpl implements IClientForSession {
    private static final String SSO_SESSIONID = "xxl_sso_sessionid";
    private static CloseableHttpClient httpClient;
    @Autowired
    SsoParameter ssoParameter;
    static {
        httpClient = HttpClientBuilder.create().build();
    }
    @Override
    public ReturnT<UserInfo> describeUserSessionInfo(String accessToken) {
        Map<String, String> params = new HashMap<>();
        params.put("cacheKey", cacheKey(accessToken));
        String result = doPost(ssoParameter.getLoginServerUrlInternal(), "sso-server/usercenter/sysCache/cacheValAqusitionByCacheKey", params);
        if (result != null) {
           BaseResult<SysCacheResVO> baseResult = JSONObject.parseObject(result, new TypeReference<BaseResult<SysCacheResVO>>(){});
            Object objectValue = null;
           if(!ObjectUtils.isEmpty(result) && !ObjectUtils.isEmpty(baseResult.getData())){
                SysCacheResVO sysCacheResVO = JSON.parseObject(JSON.toJSONString(baseResult.getData()), SysCacheResVO.class);
                objectValue = sysCacheResVO.getCacheValueObj();
            }
            if (objectValue != null) {
                XxlSsoUserVo xxlUser = JSON.parseObject(JSON.toJSONString(objectValue), XxlSsoUserVo.class);
                //todo 登录时间校验
                if (xxlUser != null) {
                    UserInfo userInfo = new UserInfo();
                   userInfo.setSessionId(accessToken);
                    BaseUserInfo baseUserInfo = new BaseUserInfo();
                   baseUserInfo.setUserId(xxlUser.getUserid());
                   baseUserInfo.setUserName(xxlUser.getUsername());
                   userInfo.setBaseInfo(baseUserInfo);
                   ReturnT<UserInfo> res = new ReturnT<UserInfo>();
                   res.setData(userInfo);
                    return res;
                }
            }
        }
        return null;
    }
    @Override
    public ReturnT invalidSessionId(String sessionId) {
        return ReturnT.SUCCESS;
    }
    private String doPost(String ssoServerUrl, String action, Map<String, String> params) {
        String url = ssoServerUrl + "/" + action;
        HttpPost post = new HttpPost(url);
       post.setHeader("Content-Type", MediaType.APPLICATION_JSON_VALUE);
//        List<NameValuePair> pairs = new ArrayList<NameValuePair>();
        if (params != null) {
//            for (Map.Entry<String, String> entry : params.entrySet()) {
//                pairs.add(new BasicNameValuePair(entry.getKey(), entry.getValue()));
//            }
            try {
                try {
                    post.setEntity(new StringEntity(JSON.toJSONString(params), "UTF-8"));
                } catch (Exception e) {
                    e.printStackTrace();
                }
            } catch (Exception e) {
            }
        }
        // 响应模型
        CloseableHttpResponse response = null;
        String result = null;
        try {
            // 由客户端执行(发送)Get请求
            response = httpClient.execute(post);
            // 从响应模型中获取响应实体
            HttpEntity responseEntity = response.getEntity();
            if (responseEntity != null) {
                result = EntityUtils.toString(responseEntity);
            }
        } catch (Exception e) {
        } finally {
            if (response != null) {
                try {
                    response.close();
                } catch (IOException e) {
                }
            }
        }
        return result;
    }

对接 IDaaS

public class IClientForSessionImpl implements IClientForSession {
    @Autowired
    HttpServletRequest request;
    @Autowired
    SsoParameter ssoParameter;
   @Value("${idaas.client.id}")
    private String clientId;
   @Value("${idaas.client.secret}")
    private String clientSecret;
    @Override
    public ReturnT<UserInfo> describeUserSessionInfo(String accessToken) {
        Map<String, String> params = new HashMap<>();
       params.put(ssoParameter.getAccessTokenKey(), accessToken);
       params.put("grant_type", "authorization_code");
        params.put("client_id", clientId);
       params.put("client_secret", clientSecret);
        String ssoServerUrl = ssoParameter.getFouraServiceUrl() + "/oauth/token" +
                "?" + ssoParameter.getAccessTokenKey() + "=" + accessToken +
               "&grant_type=authorization_code" +
               "&client_id=" + clientId +
                "&client_secret=" + clientSecret +
               "&redirect_uri=" + URLEncoder.encode(SsoUtil.getCallerHost(request) + ssoParameter.getLoginPath());
        String result = HttpUtil.doPost(ssoServerUrl, null, null);
        if (result != null) {
            String userAccessToken = JSON.parseObject(result).getString("access_token");
            String describeUserUrl = ssoParameter.getFouraServiceUrl()
                    + "/api/bff/v1.2/oauth2/userinfo?access_token="
                    + userAccessToken;
            String userResult = HttpUtil.doGet(describeUserUrl);
            if (userResult != null) {
                JSONObject userMap = JSON.parseObject(userResult).getJSONObject("data");
                BaseUserInfo baseUserInfo = new BaseUserInfo();
               baseUserInfo.setUserId(userMap.getString("sub"));
               baseUserInfo.setUserCode((String)userMap.getString("sub"));
               baseUserInfo.setUserName((String)userMap.getString("nickname"));
                OrgInfo orgInfo = new OrgInfo();
                orgInfo.setId(1L);
               orgInfo.setOrgId(userMap.getString("ou_id"));
               orgInfo.setOrgName(userMap.getString("ou_name"));
                List<OrgInfo> orgList = new ArrayList();
                orgList.add(orgInfo);
                UserInfo userInfo = new UserInfo();
               userInfo.setBaseInfo(baseUserInfo);
               userInfo.setOrgInfoList(orgList);
               userInfo.setSessionId(userAccessToken);
                ReturnT<UserInfo> res = new ReturnT<UserInfo>();
                res.setData(userInfo);
                return res;
            }
        }
        return null;
    }
    @Override
    public ReturnT invalidSessionId(String sessionId) {
        return ReturnT.SUCCESS;
    }
}
文衡
+关注
目录
打赏
0
0
0
0
0
分享
相关文章
【高薪程序员必看】万字长文拆解Java并发编程!(8):设计模式-享元模式设计指南
🌟 ​大家好,我是摘星!​ 🌟今天为大家带来的是并发编程中的经典对象复用设计模式-享元模式,废话不多说让我们直接开始。
63 0
设计模式觉醒系列(04)策略模式|简单工厂模式的升级版
本文介绍了简单工厂模式与策略模式的概念及其融合实践。简单工厂模式用于对象创建,通过隐藏实现细节简化代码;策略模式关注行为封装与切换,支持动态替换算法,增强灵活性。两者结合形成“策略工厂”,既简化对象创建又保持低耦合。文章通过支付案例演示了模式的应用,并强调实际开发中应根据需求选择合适的设计模式,避免生搬硬套。最后推荐了JVM调优、并发编程等技术专题,助力开发者提升技能。
【设计模式】【行为型模式】策略模式(Strategy)
一、入门 什么是策略模式? 策略模式是一种行为设计模式,允许在运行时选择算法或行为。它将算法封装在独立的类中,使得它们可以互换,而不影响客户端代码。 为什么需要策略模式? 策略模式的主要目的是解决算法
70 14
Kotlin - 改良设计模式 - 策略模式
Kotlin - 改良设计模式 - 策略模式
97 4
Java 设计模式:装饰者模式(Decorator Pattern)
装饰者模式属于结构型设计模式,允许通过动态包装对象的方式为对象添加新功能,提供比继承更灵活的扩展方式。该模式通过组合替代继承,遵循开闭原则(对扩展开放,对修改关闭)。
「全网最细 + 实战源码案例」设计模式——策略模式
策略模式(Strategy Pattern)是一种行为型设计模式,用于定义一系列可替换的算法或行为,并将它们封装成独立的类。通过上下文持有策略对象,在运行时动态切换算法,提高代码的可维护性和扩展性。适用于需要动态切换算法、避免条件语句、经常扩展算法或保持算法独立性的场景。优点包括符合开闭原则、运行时切换算法、解耦上下文与策略实现、减少条件判断;缺点是增加类数量和策略切换成本。示例中通过定义抽象策略接口和具体策略类,结合上下文类实现动态算法选择。
163 8
「全网最细 + 实战源码案例」设计模式——策略模式
前端必须掌握的设计模式——策略模式
策略模式(Strategy Pattern)是一种行为型设计模式,旨在将多分支复杂逻辑解耦。每个分支类只关心自身实现,无需处理策略切换。它避免了大量if-else或switch-case代码,符合开闭原则。常见应用场景包括表单验证、风格切换和缓存调度等。通过定义接口和上下文类,策略模式实现了灵活的逻辑分离与扩展。例如,在国际化需求中,可根据语言切换不同的词条包,使代码更加简洁优雅。总结来说,策略模式简化了多条件判断,提升了代码的可维护性和扩展性。
Java 设计模式——观察者模式:从优衣库不使用新疆棉事件看系统的动态响应
【11月更文挑战第17天】观察者模式是一种行为设计模式,定义了一对多的依赖关系,使多个观察者对象能直接监听并响应某一主题对象的状态变化。本文介绍了观察者模式的基本概念、商业系统中的应用实例,如优衣库事件中各相关方的动态响应,以及模式的优势和实际系统设计中的应用建议,包括事件驱动架构和消息队列的使用。
130 6
Kotlin教程笔记(53) - 改良设计模式 - 策略模式
Kotlin教程笔记(53) - 改良设计模式 - 策略模式
81 1
JavaScript设计模式及其在实战中的应用,涵盖单例、工厂、观察者、装饰器和策略模式
本文深入探讨了JavaScript设计模式及其在实战中的应用,涵盖单例、工厂、观察者、装饰器和策略模式,结合电商网站案例,展示了设计模式如何提升代码的可维护性、扩展性和可读性,强调了其在前端开发中的重要性。
102 2

热门文章

最新文章

AI助理

你好,我是AI助理

可以解答问题、推荐解决方案等