【设计模式 行为型】策略模式

这篇具有很好参考价值的文章主要介绍了【设计模式 行为型】策略模式。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

它允许在运行时根据需要选择算法的行为。该模式通过将算法封装成独立的类,使得它们可以相互替换,而不影响使用算法的客户端代码。

策略模式主要包含以下角色:

  1. 环境(Context):环境对象持有一个策略对象的引用,它提供了一个接口用于执行具体的算法。
  2. 抽象策略(Strategy):定义了策略类的统一接口,用于约束具体策略类的行为。
  3. 具体策略(Concrete Strategy):实现了抽象策略定义的接口,具体实现算法逻辑。

下面以一个简单的支付系统为例来说明策略模式的应用:

// 抽象策略类
public interface PaymentStrategy {
    void pay(double amount);
}

// 具体策略类
public class AliPayStrategy implements PaymentStrategy {
    public void pay(double amount) {
        System.out.println("使用支付宝支付:" + amount + "元");
        // 具体的支付逻辑
    }
}

public class WeChatPayStrategy implements PaymentStrategy {
    public void pay(double amount) {
        System.out.println("使用微信支付:" + amount + "元");
        // 具体的支付逻辑
    }
}

// 环境类
@Data
@NoArgsConstructor
public class PaymentContext {
    private PaymentStrategy strategy;

    public void pay(double amount) {
        strategy.pay(amount);
    }
}

在上述示例中,我们定义了一个抽象策略类PaymentStrategy,并有两个具体的策略类AliPayStrategyWeChatPayStrategy分别实现了支付宝支付和微信支付的具体逻辑。

环境类PaymentContext持有一个策略对象的引用,并提供了设置策略和支付方法。客户端通过设置不同的策略对象来实现不同的支付方式。这样,客户端代码与具体的支付算法解耦,可以动态地在运行时切换支付策略。

下面是使用策略模式实现的客户端代码:

javaCopy Codepublic class Client {
    public static void main(String[] args) {
        PaymentContext context = new PaymentContext();

        // 使用支付宝支付
        PaymentStrategy aliPayStrategy = new AliPayStrategy();
        context.setPaymentStrategy(aliPayStrategy);
        context.pay(100.0);

        // 使用微信支付
        PaymentStrategy weChatPayStrategy = new WeChatPayStrategy();
        context.setPaymentStrategy(weChatPayStrategy);
        context.pay(200.0);
    }
}

运行上述客户端代码,输出如下:

Copy Code 使用支付宝支付:100.0 元
使用微信支付:200.0 元

通过策略模式,我们可以轻松地在运行时切换不同的支付方式,而不需要改动客户端代码。策略模式将算法的选择和使用进行了解耦,提高了代码的灵活性和可维护性。同时,策略模式也符合开闭原则,当需要新增一种支付方式时,只需要添加新的具体策略类即可,无需修改原有代码逻辑。

public class Client {
    public static void main(String[] args) {
        double price = 100.0;
        String type = "normal";
        double discount = 1.0;

        // 根据商品类型设置折扣率
        if (type.equals("vip")) {
            discount = 0.9;
        } else if (type.equals("member")) {
            discount = 0.95;
        } else if (type.equals("promotion")) {
            discount = 0.8;
        }

        double actualPrice = price * discount;
        System.out.println("商品的实际价格为:" + actualPrice);
    }
}

上述代码中,我们根据商品类型手动设置相应的折扣率,然后计算实际价格。这样的代码虽然简单,但存在以下问题:

  1. 客户端代码与具体的折扣算法高度耦合,如果需要更改算法,例如新增一种商品类型,就需要修改客户端代码,这会导致代码的可维护性变差。
  2. 没有遵循开闭原则,当需要新增一种商品类型时,就需要修改原有代码逻辑,这样会影响到其他代码的稳定性。

因此,采用策略模式能更好地解决这些问题,实现代码的松耦合和可维护性。

public class CeLue {

    public static void main(String[] args) {
        double price = 100.0;
        String type = "vip";
        PayStrategy conType = getPayStrategy(type);
        PayContext payContext = new PayContext(conType);
        payContext.pay(price);
    }

    private static PayStrategy getPayStrategy(String type) {
        switch (type) {
            case "vip":
                return new VipType();
            default:
                return new NormalType();
        }
    }
}

interface PayStrategy {
    void pay(double amount);
}

class NormalType implements PayStrategy {
    @Override
    public void pay(double amount) {
        System.out.println("普通支付" + amount + "元");
    }
}

class VipType implements PayStrategy {
    @Override
    public void pay(double amount) {
        System.out.println("vip支付" + amount * 0.9 + "元");
    }
}

class PayContext {
    private PayStrategy payStrategy;

    public PayContext(PayStrategy payStrategy) {
        this.payStrategy = payStrategy;
    }

    public void pay(double amount) {
        payStrategy.pay(amount);
    }

}

分享一个案例:统一认证登录

认证接口类 AuthService

public interface AuthService {

  UserExt execute(AuthParamsDto authParamsDto);

}

它的实现类 可以是密码登录PasswordAuthServiceImpl 手机号登录PhoneAuthServiceImpl 微信登录WxAuthServiceImpl 等,获取前缀,拼接bean名称,Spring上下文拿到bean

调用,我用的是SpringsSecurity框架并重写了 UserDetailsService文章来源地址https://www.toymoban.com/news/detail-807833.html

    @Autowired
    ApplicationContext applicationContext;

    //传入的是AuthParamsDto的json串
    @Override
    public UserDetails loadUserByUsername(String s) throws UsernameNotFoundException {
        AuthParamsDto authParamsDto = null;
        try {
            //将认证参数转为AuthParamsDto类型
            authParamsDto = JSON.parseObject(s, AuthParamsDto.class);
        } catch (Exception e) {
            log.info("认证请求不符合项目要求:{}",s);
            throw new RuntimeException("认证请求数据格式不对");
        }
        //认证方式
        String authType = authParamsDto.getAuthType();
        //从spring容器中拿具体的认证bean实例
        AuthService authService = applicationContext.getBean(authType + "_authservice", AuthService.class);
        //开始认证,认证成功拿到用户信息
        XcUserExt xcUserExt = authService.execute(authParamsDto);

        return getUserPrincipal(xcUserExt);
    }
@Data
public class AuthParamsDto {

    private String username; //用户名
    private String password; //域  用于扩展
    private String cellphone;//手机号
    private String checkcode;//验证码
    private String checkcodekey;//验证码key
    private String authType; // 认证的类型   password:用户名密码模式类型    sms:短信模式类型
    private Map<String, Object> payload = new HashMap<>();//附加数据,作为扩展,不同认证类型可拥有不同的附加数据。如认证类型为短信时包含smsKey : sms:3d21042d054548b08477142bbca95cfa; 所有情况下都包含clientId

}

到了这里,关于【设计模式 行为型】策略模式的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 设计模式(4)--对象行为(9)--策略

    1. 意图     定义一系列的算法,把它们一个个封装起来,并且使它们可相互替换。     本模式使得算法可独立于使用它的客户而变化。 2. 三种角色    抽象策略(Strategy)、具体策略(Concrete Strategy)、上下文环境(Context) 3. 优点     3.1 可重用的相关算法系列。     3.2 一个替代继

    2024年02月04日
    浏览(33)
  • 软件设计模式与体系结构-设计模式-行为型软件设计模式-策略模式

    策略模式(Strategy Pattern)是一种行为型设计模式,它定义了一系列算法,并将每个算法封装在独立的类中,使它们可以相互替换。策略模式使得算法可以独立于使用它们的客户端而变化。 下面是一个使用策略模式的简单代码示例,以解释其工作原理: 在上述示例中,策略模

    2024年02月13日
    浏览(106)
  • 【设计模式与范式:行为型】61 | 策略模式(下):如何实现一个支持给不同大小文件排序的小程序?

    上一节课,我们主要介绍了策略模式的原理和实现,以及如何利用策略模式来移除 if-else 或者 switch-case 分支判断逻辑。今天,我们结合“给文件排序”这样一个具体的例子,来详细讲一讲策略模式的设计意图和应用场景。 除此之外,在今天的讲解中,我还会通过一步一步地

    2024年02月10日
    浏览(31)
  • 【十五】设计模式~~~行为型模式~~~状态模式(Java)

    【学习难度:★★★☆☆,使用频率:★★★☆☆】 在很多情况下,一个对象的行为取决于一个或多个动态变化的属性,这样的属性叫做状态,这样的对象叫做有状态的(stateful)对象,这样的对象状态是从事先定义好的一系列值中取出的。当一个这样的对象与外部事件产生互

    2024年02月07日
    浏览(32)
  • 【Java 设计模式】行为型之命令模式

    命令模式(Command Pattern)是一种行为型设计模式,用于将请求封装为对象,使得可以参数化客户端对象,并且能够排队、记录请求,以及支持撤销操作。在本文中,我们将深入研究Java中命令模式的定义、结构、使用场景以及如何在实际开发中应用。 命令模式是一种行为型设

    2024年01月23日
    浏览(33)
  • 【Java 设计模式】行为型之状态模式

    状态模式(State Pattern)是一种行为型设计模式,用于通过将对象的行为封装到不同的状态类中,使得对象在不同的状态下具有不同的行为。状态模式允许对象在内部状态发生改变时改变其行为,而无需修改其代码。在本文中,我们将深入研究Java中状态模式的定义、结构、使

    2024年01月24日
    浏览(38)
  • 【Java 设计模式】行为型之责任链模式

    责任链模式(Chain of Responsibility Pattern)是一种行为型设计模式,用于将请求发送者和接收者解耦,使得多个对象都有机会处理请求。责任链模式通过创建一个处理请求的链,将请求沿着链传递,直到有一个对象能够处理为止。在本文中,我们将深入研究Java中责任链模式的定

    2024年01月24日
    浏览(40)
  • 【玩转23种Java设计模式】行为型模式篇:模板模式

    软件设计模式(Design pattern),又称设计模式,是一套被反复使用、多数人知晓的、经过分类编目的、代码设计经验的总结。使用设计模式是为了可重用代码、让代码更容易被他人理解、保证代码可靠性、程序的重用性。 汇总目录链接:【玩转23种Java设计模式】学习目录汇总

    2024年02月16日
    浏览(26)
  • 【玩转23种Java设计模式】行为型模式篇:责任链模式

    软件设计模式(Design pattern),又称设计模式,是一套被反复使用、多数人知晓的、经过分类编目的、代码设计经验的总结。使用设计模式是为了可重用代码、让代码更容易被他人理解、保证代码可靠性、程序的重用性。 汇总目录链接:【玩转23种Java设计模式】学习目录汇总

    2024年02月13日
    浏览(24)
  • Java设计模式之行为型-命令模式(UML类图+案例分析)

    目录 一、基础概念 二、UML类图 三、角色设计 四、案例分析 4.1、基本实现 4.2、点餐案例  五、总结 1、将一个请求封装为一个对象,使您可以用不同的请求对客户进行参数化。 2、对请求排队或记录请求日志,以及支持可撤销的操作。 3、将命令对象与执行命令的对象分离,

    2024年02月16日
    浏览(26)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包