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;
    }
}
目录
相关文章
|
2月前
|
设计模式 算法 Kotlin
Kotlin - 改良设计模式 - 策略模式
Kotlin - 改良设计模式 - 策略模式
54 4
|
6天前
|
设计模式 存储 缓存
前端必须掌握的设计模式——策略模式
策略模式(Strategy Pattern)是一种行为型设计模式,旨在将多分支复杂逻辑解耦。每个分支类只关心自身实现,无需处理策略切换。它避免了大量if-else或switch-case代码,符合开闭原则。常见应用场景包括表单验证、风格切换和缓存调度等。通过定义接口和上下文类,策略模式实现了灵活的逻辑分离与扩展。例如,在国际化需求中,可根据语言切换不同的词条包,使代码更加简洁优雅。总结来说,策略模式简化了多条件判断,提升了代码的可维护性和扩展性。
|
2月前
|
设计模式 消息中间件 搜索推荐
Java 设计模式——观察者模式:从优衣库不使用新疆棉事件看系统的动态响应
【11月更文挑战第17天】观察者模式是一种行为设计模式,定义了一对多的依赖关系,使多个观察者对象能直接监听并响应某一主题对象的状态变化。本文介绍了观察者模式的基本概念、商业系统中的应用实例,如优衣库事件中各相关方的动态响应,以及模式的优势和实际系统设计中的应用建议,包括事件驱动架构和消息队列的使用。
|
2月前
|
设计模式 算法 Kotlin
Kotlin教程笔记(53) - 改良设计模式 - 策略模式
Kotlin教程笔记(53) - 改良设计模式 - 策略模式
49 1
|
2月前
|
设计模式 前端开发 JavaScript
JavaScript设计模式及其在实战中的应用,涵盖单例、工厂、观察者、装饰器和策略模式
本文深入探讨了JavaScript设计模式及其在实战中的应用,涵盖单例、工厂、观察者、装饰器和策略模式,结合电商网站案例,展示了设计模式如何提升代码的可维护性、扩展性和可读性,强调了其在前端开发中的重要性。
40 2
|
2月前
|
设计模式 Java 数据库连接
Java编程中的设计模式:单例模式的深度剖析
【10月更文挑战第41天】本文深入探讨了Java中广泛使用的单例设计模式,旨在通过简明扼要的语言和实际示例,帮助读者理解其核心原理和应用。文章将介绍单例模式的重要性、实现方式以及在实际应用中如何优雅地处理多线程问题。
42 4
|
2月前
|
设计模式 算法 Kotlin
Kotlin教程笔记(53) - 改良设计模式 - 策略模式
Kotlin教程笔记(53) - 改良设计模式 - 策略模式
51 2
|
3月前
|
设计模式 Java 程序员
[Java]23种设计模式
本文介绍了设计模式的概念及其七大原则,强调了设计模式在提高代码重用性、可读性、可扩展性和可靠性方面的作用。文章还简要概述了23种设计模式,并提供了进一步学习的资源链接。
58 0
[Java]23种设计模式
|
3月前
|
设计模式 算法 Kotlin
Kotlin教程笔记(53) - 改良设计模式 - 策略模式
本教程详细讲解Kotlin语法,适合深入学习。快速入门可参考“简洁”系列教程。本文通过游泳运动员的案例,介绍策略模式及其在Kotlin中的改良应用,利用高阶函数简化代码结构,提高灵活性。
43 3
|
2月前
|
设计模式 JavaScript Java
Java设计模式:建造者模式详解
建造者模式是一种创建型设计模式,通过将复杂对象的构建过程与表示分离,使得相同的构建过程可以创建不同的表示。本文详细介绍了建造者模式的原理、背景、应用场景及实际Demo,帮助读者更好地理解和应用这一模式。