策略模式,看一篇就够了

策略模式


在策略模式中,一个类的行为或其算法可以在运行时更改。这种类型的设计模式属于行为型模式。

在策略模式中,我们创建表示各种策略的对象和一个行为随着策略对象改变而改变的context对象。策略对象改变 context 对象的执行算法。

​ 策略模式是一种行为型模式,它将对象和行为分开,将行为定义为 一个行为接口具体行为的实现。策略模式最大的特点是行为的变化,行为之间可以相互替换。每个if判断都可以理解为就是一个策略。本模式使得算法可独立于使用它的用户而变化。

1. 介绍

意图:定义一系列的算法,把它们一个个封装起来,并且使它们可相互替换。

主要解决:在有多种算法相似的情况下,使用 if…else 所带来的复杂和难以维护。

何时使用:一个系统有许多许多类,而区分它们的知识他们直接的行为。

如何解决:将这些算法封装成一个一个的类,任意地替换。

关键代码:实现同一个接口。

应用实例:

  1. 诸葛亮的锦囊妙计,每一个锦囊就是一个策略。
  2. 旅行的出游方式,选择骑自行车、坐汽车,每一种旅行方式都是一个策略
  3. Java AWT中的 LayoutManager

优点:

  1. 算法可以自由切换。
  2. 避免使用多重条件判断。
  3. 扩展性良好。
  4. 策略模式提供了对“开闭原则”的完美支持,用户可以在不修改原有系统的基础上选择算法或行为,也可以灵活地增加新的算法或行为。

缺点:

  1. 策略类会增多,可以通过使用享元模式在一定程度上减少对象的数量。
  2. 所有策略类都需要对外暴露。即客户端必须知道所有的策略类,并自行决定使用哪一个策略类。

使用场景:

  1. 如果在一个系统里面有许多类,它们之间的区别仅在于它们的行为,那么使用策略模式可以动态地让一个对象在许多行为中选择一种行为。
  2. 一个系统需要动态地在几种算法中选择一种。
  3. 如果一个对象有很多的行为,如果不用恰当的模式,这些行为就只好使用多重的条件选择语句来实现。

注意事项:如果一个系统的策略多于四个,就需要考虑混合模式,解决策略类膨胀的问题。

2. 模式结构

策略模式包含如下角色:

  • Strategy:抽象策略类。策略是一个接口,该接口定义若干个算法标识,即定义了若干个抽象方法。
  • Context:环境类/上下文类
    • 上下文是依赖于接口的类(是面向策略设计的类),即上下文包含用策略(接口)声明的变量。
    • 上下文提供一个方法,该方法委托策略变量调用具体策略所实现的策略接口中的方法(实现接口的类重写策略(接口)中的方法,来完成具体功能)
  • 具体策略类:策略实现类,具体策略是实现策略接口的类。具体策略实现策略接口所定义的抽象方法,即给出算法标识的具体方法。(说白了就是重写策略类的方法!)

3. 示例

示例1

现在将创建一个将定义加、减、乘计算的策略接口(Strategy接口)和实现了Strategy接口的实体策略类。Context 是一个使用了某种策略的类。

StrategyPatternDemo是测试类,使用 Context 和策略对象来掩饰 Context 在它所配置或使用的策略 改变时的行为变化。

在这里插入图片描述

步骤一:创建一个策略接口

public interface Strategy {
    public int doOperation(int num1, int num2);
}

步骤二:创建接口的实现类

OperationAdd类:

public class OperationAdd implements Strategy {
    @Override
    public int doOperation(int num1, int num2) {
        return num1 + num2;
    }
}

OperationSubtract类:

public class OperationSubtract implements Strategy {
    @Override
    public int doOperation(int num1, int num2) {
        return num1 - num2;
    }
}

OperationMultiply类:

public class OperationMultiply implements Strategy {
    @Override
    public int doOperation(int num1, int num2) {
        return num1 * num2;
    }
}

步骤三:创建 Context 类

public class Context {

    private Strategy strategy;

    public Context(Strategy strategy) {
        this.strategy = strategy;
    }

    public int executeStrategy(int num1, int num2) {
        return strategy.doOperation(num1,num2);
    }
}

步骤四:使用 Context 来查看当它改变策略 Strategy 时的行为变化。

public class StrategyPatternDemo {
    public static void main(String[] args) {
        Context context = new Context(new OperationAdd());
        System.out.println("10 + 5 = " + context.executeStrategy(10,5));

        context = new Context(new OperationSubtract());
        System.out.println("10 - 5 = " + context.executeStrategy(10,5));

        context = new Context(new OperationMultiply());
        System.out.println("10 * 5 = " + context.executeStrategy(10,5));

    }
}

步骤五:执行程序,输出结果:

10 + 5 = 15
10 - 5 = 5
10 * 5 = 50

示例2

​ 现在有一个商店售卖货物,但是针对不同的人会有折扣,目前的折扣是普通人不打折,中级人士是打折10%,高级人士是20%,传统实现如下:

    public Double computeMoney(String type, Double primitivemoney, int n) {
        // 中级计费
        if (type.equals("middle")) {
            return primitivemoney * n - primitivemoney * n * 0.1;
        }
        // 高级计费
        if (type.equals("high")) {
            return primitivemoney * n - primitivemoney * n * 0.2;
        }
        // 初级 计费
        return primitivemo\ney;
    }

现在用策略模式实现:

步骤一:创建策略接口

public interface ComputeStrategy {
    /**
     * 计算money的抽象方法
     * @param money 单价
     * @param n 数量
     * @return
     */
    public double compute(double money, int n);
}

步骤二:创建接口的实现类

普通人士:

public class PrimaryMember implements ComputeStrategy {
    // 初级不打折
    @Override
    public double compute(double money, int n) {
        return money * n;
    }
}

中级人士:

public class MiddleMember implements ComputeStrategy {
    // 中级 10%
    @Override
    public double compute(double money, int n) {
        return money * n - money * n * 0.1;
    }
}

高级人士:

public class HighMember implements ComputeStrategy {
    // 高级 20%
    @Override
    public double compute(double money, int n) {
        return money * n - money * n * 0.2;
    }
}

步骤三:创建Context类

public class MemberContext {

    private ComputeStrategy computeStrategy;

    public MemberContext(ComputeStrategy computeStrategy) {
        this.computeStrategy = computeStrategy;
    }

    public double computeMoney(double money, int n) {
        return computeStrategy.compute(money, n);
    }
}

步骤四:测试

    public static void main(String[] args) {
        //具体的行为策略
        ComputeStrategy primary = new PrimaryMember();
        ComputeStrategy middle = new MiddleMember();
        ComputeStrategy high = new HighMember();

        // 用户选择不同的策略
        MemberContext primaryContext = new MemberContext(primary);
        MemberContext middleContext = new MemberContext(middle);
        MemberContext highContext = new MemberContext(high);

        // 计算 单价300 数量1
        System.out.println("普通价: "+ primaryContext.computeMoney(300,1));
        System.out.println("中级价: "+ middleContext.computeMoney(300,1));
        System.out.println("高级价: "+ highContext.computeMoney(300,1));
    }

步骤五:运行程序,输出结果:

普通价: 300.0
中级价: 270.0
高级价: 240.0

4. 策略模式适用场景

在如下情况可以使用策略模式:

  • 一个系统需要动态地在几种算法中选择一种。
  • 如果一个对象有很多行为,如果不用恰当的模式,这些行为就只好使用多重的条件选择语句来实现。
  • 如果在一个系统里面有许多类,它们之间的区别仅在于他们的行为,那么使用策略模式可以动态地让一个对象在许多行为中选择一种行为。
  • 不希望客户端知道复杂的、与算法相关的数据结构,在具体策略类中封装算法和相关的数据结构,提高算法的保密性与安全性。

在生活中比较常见的应用模式有:

1、电商网站支付方式,一般分为银联、微信、支付宝,可以采用策略模式

2、电商网站活动方式,一般分为满减送、限时折扣、包邮活动,拼团等可以采用策略模式

  • 17
    点赞
  • 63
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 10
    评论
学习数据库管理系统是一项复杂而庞大的任务,通过一篇CSDN文章无法全面覆盖所有相关知识。然而,可以通过一篇文章提供一些基本概念和入门指导。 首先,数据库管理系统(DBMS)是一种软件工具,用于管理和组织数据库。它可以提供数据存储、检索、更新和管理的功能。了解DBMS的不同类型和常见的DBMS软件是学习数据库管理系统的第一步。 其次,学习数据库设计是非常重要的。在设计数据库时,需要考虑表格、字段、关系、键等概念。了解关系数据库的范式(如第一范式、第二范式、第三范式等)以及关系代数和SQL查询语言也是必要的。 此外,了解事务处理和并发控制是数据库管理系统学习的重点。事务是指一系列数据库操作的逻辑单元,具有原子性、一致性、隔离性和持久性特性。掌握事务处理的概念和技术,以及处理并发访问数据库时可能发生的问题和解决方案,对于成为数据库管理系统专家至关重要。 最后,学习数据库性能优化和安全管理也是数据库管理系统学习的重要内容。了解如何优化数据库查询、索引设计、缓存策略和数据库分区等,可以提高数据库的性能和响应时间。同时,了解如何保护数据库的安全性、备份和恢复数据也是数据库管理系统学习的重要一环。 综上所述,学习数据库管理系统需要掌握数据库类型和软件、数据库设计、事务处理和并发控制、性能优化以及安全管理等知识。通过阅读CSDN等相关文章可以初步了解这些概念和技术,但需要进一步深入学习和实践才能真正掌握数据库管理系统。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 10
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

白居不易.

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值