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;
    }
}
目录
相关文章
|
11天前
|
设计模式 Java 程序员
[Java]23种设计模式
本文介绍了设计模式的概念及其七大原则,强调了设计模式在提高代码重用性、可读性、可扩展性和可靠性方面的作用。文章还简要概述了23种设计模式,并提供了进一步学习的资源链接。
28 0
[Java]23种设计模式
|
20天前
|
设计模式 算法 Kotlin
Kotlin教程笔记(53) - 改良设计模式 - 策略模式
本教程详细讲解Kotlin语法,适合深入学习。快速入门可参考“简洁”系列教程。本文通过游泳运动员的案例,介绍策略模式及其在Kotlin中的改良应用,利用高阶函数简化代码结构,提高灵活性。
27 3
|
21天前
|
设计模式 算法 Kotlin
Kotlin教程笔记(53) - 改良设计模式 - 策略模式
本教程详细讲解Kotlin语法,适合深入学习。快速入门可参考“简洁”系列教程。本文介绍策略模式在Kotlin中的应用,通过游泳运动员的例子,展示如何使用接口和高阶函数实现策略模式,使代码更简洁、灵活。
26 2
|
23天前
|
设计模式 算法 Kotlin
Kotlin教程笔记(53) - 改良设计模式 - 策略模式
Kotlin教程笔记(53) - 改良设计模式 - 策略模式
57 3
|
24天前
|
设计模式 算法 Kotlin
Kotlin教程笔记(53) - 改良设计模式 - 策略模式
Kotlin教程笔记(53) - 改良设计模式 - 策略模式
27 3
|
23天前
|
设计模式 算法 PHP
PHP中的设计模式:策略模式的深入解析与实践
【10月更文挑战第9天】 策略模式是一种行为设计模式,它允许在运行时选择算法的行为。在PHP开发中,通过使用策略模式,我们可以轻松切换算法或逻辑处理方式而无需修改现有代码结构。本文将深入探讨策略模式的定义、结构以及如何在PHP中实现该模式,并通过实际案例展示其应用价值和优势。
24 1
|
24天前
|
设计模式 算法 PHP
PHP中的设计模式:策略模式的深入解析与应用
【10月更文挑战第8天】 在软件开发的浩瀚宇宙中,设计模式如同星辰指引,照亮了代码设计与架构的航道。本文旨在深入探索PHP语境下策略模式(Strategy Pattern)的精髓,不仅剖析其内核原理,还将其融入实战演练,让理论在实践中生根发芽。策略模式,作为解决“如何优雅地封装算法族”的答案,以其独特的灵活性与扩展性,赋予PHP应用以动态变换行为的能力,而无需牵动既有的类结构。
15 2
|
25天前
|
设计模式 算法 PHP
PHP中的设计模式:策略模式的深入解析与实践
在PHP开发中,设计模式是提高代码可读性、可维护性和扩展性的重要工具。本文将深入探讨策略模式这一行为型设计模式,通过分析其定义、结构、使用场景以及在PHP中的实际应用,帮助开发者更好地理解和运用策略模式来优化自己的项目。不同于传统摘要的简洁概述,本文摘要部分将详细阐述策略模式的核心理念和在PHP中的实现方法,为读者提供清晰的指引。
|
27天前
|
设计模式 监控 算法
Java设计模式梳理:行为型模式(策略,观察者等)
本文详细介绍了Java设计模式中的行为型模式,包括策略模式、观察者模式、责任链模式、模板方法模式和状态模式。通过具体示例代码,深入浅出地讲解了每种模式的应用场景与实现方式。例如,策略模式通过定义一系列算法让客户端在运行时选择所需算法;观察者模式则让多个观察者对象同时监听某一个主题对象,实现松耦合的消息传递机制。此外,还探讨了这些模式与实际开发中的联系,帮助读者更好地理解和应用设计模式,提升代码质量。
Java设计模式梳理:行为型模式(策略,观察者等)
|
1月前
|
设计模式 算法 PHP
PHP中的设计模式:策略模式的深入解析与实践
策略模式是一种行为型设计模式,用于定义一系列算法,将每种算法都封装起来,并使它们可以互换。本文将探讨如何在PHP中实现策略模式,以及如何利用它来提高代码的灵活性和可维护性。通过具体示例,我们将看到策略模式在处理复杂业务逻辑时的优势,从而帮助开发者编写出更加清晰、易于扩展的代码。

热门文章

最新文章