小工具      在线工具  汉语词典  css  js  c++  java

策略模式

java,策略模式 额外说明

收录于:40天前

策略模式概述

在策略模式(Strategy Pattern)中,类或其算法的行为可以在运行时更改。这种类型的设计模式行为模型
在策略模式中,我们创建代表各种策略的对象和一个行为随着策略对象的变化而变化的 context 对象。策略对象改变上下文对象的执行算法。

介绍

目的: 定义一系列的算法,把它们一个个封装起来, 并且使它们可相互替换。
主要解决方案: 在有多种算法相似的情况下,使用 if…else 所带来的复杂和难以维护。
何时使用: 一个系统有许多许多类,而区分它们的只是他们直接的行为。
怎么解决: 将这些算法封装成一个一个的类,任意地替换。
关键代码: 实现同一个接口。
优势:

  1. 多重条件语句不易维护,而使用策略模式可以避免使用多个条件语句,如 if…else 语句、switch…case 语句。
  2. 策略模式提供了一系列的可供重用的算法族,恰当使用继承可以把算法族的公共代码转移到父类中,避免代码重复。
  3. 策略模式可以提供相同行为的不同实现,客户可以根据不同时间或空间要求选择不同的。
  4. 策略模式为开闭原则提供了完美的支持,可以在不修改原代码的情况下,灵活增加新算法。
  5. 策略模式把算法的使用放到环境类中,而将算法的实现移至具体的策略类中,实现了两者的分离。

缺点:

  1. 策略类别将会增加。
  2. 所有策略类都需要对外暴露,客户必须了解所有策略算法之间的差异,以便适时选择恰当的算法类。

使用场景:

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

应用:

  1. 诸葛亮的每一条秘诀都是一种策略。
  2. 你的出行方式,无论你选择骑自行车还是坐汽车,每一种出行方式都是一种策略。
  3. JAVA AWT 中的布局管理器。

防范措施: 如果一个系统的策略多于四个,就需要考虑使用混合模式,解决策略类膨胀的问题。

结构

三种角色

环境类(Context)
持有一个策略类的引用,最终给客户端调用。
抽象策略类(Strategy)
定义了一个公共接口,各种不同的算法以不同的方式实现这个接口,环境角色使用这个接口调用不同的算法,一般使用接口或抽象类实现。
具体策略
实现了抽象策略定义的接口,提供具体的算法实现。

结构图


案例实现

案例描述

有两种折扣方式。第一种是打折折扣,将商品总金额乘以折扣比例;二是满折折扣,达到满折扣门槛后扣除相应的折扣金额。

案例类图

代码实现

抽象策略类

折扣折扣接口

public interface Discount {
    
    /** * 实际金额 * @param money double * @return double */
    Double realMoney(Double money);
}

具体策略类

折扣类别(百分比)

public class Percentage implements Discount {
    

    private final Double rebate;

    public Percentage(Double rebate) {
    
        this.rebate = rebate;
    }

    /** * 实际金额 * * @param money double * @return double */
    @Override
    public Double realMoney(Double money) {
    
        return money * rebate;
    }
}

完全折扣类别(FullDiscount)

public class FullDiscount implements Discount {
    

    private final Double upperLimit;
    private final Double subtract;

    public FullDiscount(Double upperLimit, Double subtract) {
    
        this.upperLimit = upperLimit;
        this.subtract = subtract;
    }

    /** * 实际金额 * * @param money double * @return double */
    @Override
    public Double realMoney(Double money) {
    
        return money >= upperLimit ? money - subtract : money;
    }
}

环境类别

上下文上下文

public class Context {
    

    private Discount discount;

    public Context(Discount discount) {
    
        this.discount = discount;
    }

    public Double getRealMoney(Double money) {
    
        return discount.realMoney(money);
    }
}

demo调用

public class StrategyPattern {
    
    public static void main(String[] args) {
    
        getMoney();
    }

    private static void getMoney(){
    
        Context context = new Context(new Percentage(0.8));
        Double realMoney = context.getRealMoney(1000.0);
        System.out.println(realMoney);
        context = new Context(new FullDiscount(500.0, 100.0));
        realMoney = context.getRealMoney(realMoney);
        System.out.println(realMoney);
    }
}

关于优化

重复new来创建对象
使用构造方法时,每次调用都需要重新new一个context对象,那么,在context中加入set方法,就可以解决这个问题。
Context类:

public class Context {
    

    private Discount discount;

    public void setDiscount(Discount discount) {
    
        this.discount = discount;
    }

    public Context(Discount discount) {
    
        this.discount = discount;
    }

    public Double getRealMoney(Double money) {
    
        return discount.realMoney(money);
    }
}

演示调用示例:

public class StrategyPattern {
    
    public static void main(String[] args) {
    
        getMoneyNoNew();
    }

    private static void getMoneyNoNew(){
    
        Context context = new Context(new Percentage(0.8));
        Double realMoney = context.getRealMoney(1000.0);
        System.out.println(realMoney);
        context.setDiscount(new FullDiscount(500.0, 100.0));
        realMoney = context.getRealMoney(realMoney);
        System.out.println(realMoney);
    }

}
. . .

相关推荐

额外说明

h264中profile和level的含义

转自: https://blog.csdn.net/xiaojun111111/article/details/52090185 Profile是对视频压缩特性的描述(CABAC呀、颜色采样数等等)。Level是对视频本身特性的描述(码率、分辨率、fps

额外说明

【精通Linux系列】Centos7的防火墙及selinux介绍与端口的使用

- 作者 :“大数据小禅” - 专栏简介 :本专栏主要分享Linux技术,会涉及到常用的Linux命令操作,常用的服务部应用署以及相关运维知识,还有一些Linux系统的深层解析,Linux系列专栏地址,欢迎小伙伴们订阅! - 个人主页 :大数据小禅 -

额外说明

【1++的数据结构】之哈希(一)

-作者主页:进击的1++ - 专栏链接:【1++的数据结构】 文章目录 一,什么是哈希? 二,哈希冲突 哈希函数 哈希冲突解决 unordered_map与unordered_set 一,什么是哈希? 首先我们要知道的是哈希是一种思想----一 一映射。

额外说明

Apache Ignite学习笔记:创建缓存、存储数据、读取缓存

              使用Apache Ignite2.4 创建缓存 、存储数据、读取缓存 1  Ignite初始化         (1)初始化代码 //使用配置文件 example-default.xml 初始化Ignite Ignite ig

额外说明

ToDesk版本更新,引入RTC传输技术,是否早以替代向日葵远程控制?

文章目录 前言 一、ToDesk 介绍 二、新版本体验介绍 1、RTC (Real Time Communication)技术 2、隐私屏保护用户信息 2.1、功能体验 2.2、功能限制 3、文件传输使用更加舒适 4、流畅度纵享丝滑 5、自定义键鼠映射

额外说明

浅谈Spring如何解耦和IOC

1.传统三层架构耦合性高。 首先来谈一谈传统的web应用三层架构,这样有助于我们理解spring是怎么来降低系统的耦合度的。 如下图所示,web层通过调用相关的service来实现业务逻辑的实现,而service通过DAO层来进行数据的CRUD操作。假设

额外说明

commons-math3-3.6.1-org.apache.commons.math3.analysis.integration.gauss-包下的类-中英对照文档及源码赏析

commons-math3-3.6.1-org.apache.commons.math3.analysis.integration.gauss-包下的类-中英对照文档及源码赏析 摘要:中英对照文档、源码赏析、org.apache.commons.math

额外说明

Java讲课笔记36:初探反射机制

文章目录 零、本讲学习目标 一、认识反射 (一)Java反射机制 (二)Java反射的动态性质 (三)如何理解Java反射的原理 (四)利用反射可实现的功能 二、Java反射常用API 三、使用反射的基本步骤 四、利用反射获取类的信息 (一)获取Clas

额外说明

wordpress描述调用_如何在WordPress中添加关键字和元描述

WordPress 描述调用 您想在 WordPress 中正确添加关键字和元描述吗?元关键字和元描述可以帮助您改善网站的搜索引擎优化。在本文中,我们将向您展示如何在 WordPress 中正确添加元关键字和元描述。 您想在 WordPress 中正确添

额外说明

java和javaw的区别

1.javaw.exe运行程序时不会输出控制台信息。如果双击打开jar文件(假设已经设置了打开方式),那么控制台窗口根本不会出现。它主要用于运行带有表单的程序。应用程序,其中的“w”表示窗口,所以运行控制台程序时虽然不会报错,但也不会输出任何结果。 ja

ads via 小工具