浅析Java设计模式之四策略模式


title: 浅析Java设计模式之四策略模式
date: 2018-12-29 17:26:17
categories: 设计模式
description: 浅析Java设计模式之四策略模式

1. 目录

Celue-1

  • 1. 目录
  • 2. 概念
    • 2.1. 应用场景
    • 2.2. 优缺点
      • 2.2.1. 优点
      • 2.2.2. 缺点
  • 3. 模式结构
  • 4. 样例
    • 4.1. 定义策略
    • 4.2. 定义具体策略
    • 4.3. 定义上下文
    • 4.4. 实现效果
  • 5. 拓展

2. 概念

策略模式是我们 Java 开发中最最基础的开发模式,我们在日常生活中都可以找到与之相关。现实中我们各种为实现某种目标而选择的具体某种行为,都可以归纳为之策略。

20230819163824

我们选择去旅行,对于交通工具的选择上,我们有飞机、客车、高铁、自驾等做种选择,每一种选择都代表一种策略,都为了我们去旅行这个目标而服务。

而在软件开发中我们也常遇到类似的情况,当为实现某一个功能存在多种算法或者策略,我们可以根据环境或者条件的不同选择不同的算法或者策略来完成该功能,如数据排序策略有冒泡排序、选择排序、插入排序、二叉树排序等。

所以这里给策略( Strategy )模式下个定义,模式定义一系列算法,并将每个算法封装起来,使它们可以相互替换,且算法的变化不会影响使用算法的客户。

总之,所以在本质上策略的设计模式属于行为型模式一种,通过定义的一套算法类,进行封装,让算法类之间可以相互替换,从而达到一种按照调用侧/实现侧去决定目标实现。策略模式可以最大程度的避免代码中 if else 以及 switch 语句。

2.1. 应用场景

  • 在需要多实现场景下,但只在算法或行为上略有差异
  • 在算法或行为上须自由完成切换
  • 需要解脱或者屏蔽多条件判断的场景

2.2. 优缺点

2.2.1. 优点

  • 算法或行为可自由切换
  • 避免在实现过程中,使用多重条件判断
  • 实现结构上具备扩展性良好和可读性

2.2.2. 缺点

  • 策略的基础条件随着业务增长会增多,可能存在臃肿
  • 不是很安全,因为所有的策略条件都对外暴露

3. 模式结构

策略模式 的实现包含三个组成部分,分别为 策略类具体策略类上下文

  • Strategy:策略类,用于定义所有支持算法的公共接口;
  • ConcreteStrategy:是具体策略类,封装了具体的算法或行为,继承于 Strategy
  • Context:是上下文,用一个 ConcreteStrategy 来配置,维护一个对 Strategy 对象的引用

STRATEGY

4. 样例

此处假定我们在商场购物,选购的商品为 桌面电脑,那么在用户支付的环节,对支付的手段,可以有多种选择,例如 现金信用卡积分 等。那么我们在设计过程中,就遵循这种这种实现。

20230820135049

4.1. 定义策略

抽象一个付款方式,我们没有指明具体是哪一种付款方式,留给实现类去具体说明。


public interface Payment {

    void payment();
}

4.2. 定义具体策略

  • 现金

public class Cash implements Payment{

    @Override
    public void payment() {
        System.out.println("现金付款");
    }
}

  • 信用卡

public class Credit implements Payment{

    @Override
    public void payment() {
        System.out.println("信用卡付款");
    }
}

  • 积分

public class Points implements Payment{

    @Override
    public void payment() {
        System.out.println("积分付款");
    }
}

4.3. 定义上下文

public class Shopping {

    private Payment payment;

    public Shopping(Payment payment) {
        this.payment = payment;
    }

    public void buyDesktop(){
        System.out.println("购买台式机");
        payment.payment();
    }

}

4.4. 实现效果


@DisplayName("策略应用")
@Test
public void testStrategy() {
    Payment payment = new Cash();
    Shopping shopping = new Shopping(payment);
    shopping.buyDesktop();
}

20220830152421

5. 拓展

在我们上面使用 策略模式 的设计中,如果当存在的具体策略很多时,策略的客户端在管理所有策略将变得很臃肿且复杂,那如果在环境类中使用一个策略工厂模式来管理具体策略类,那么将大大减少客户端的工作复杂度。


package io.github.rothschil.design.strategy.factory;

import cn.hutool.core.util.ClassUtil;
import io.github.rothschil.design.strategy.Payment;
import io.github.rothschil.design.strategy.StrategyEnum;

import java.util.HashMap;
import java.util.Map;
import java.util.Set;

public class StrategyFactory {

    private static Map<String, Payment> PAYMENT_MAP = new HashMap<>();

    public StrategyFactory() {

        // 反射出子类
        Set<Class<?>> sets = ClassUtil.scanPackageBySuper("io.github.rothschil", Payment.class);
        for (Class<?> it : sets) {
            try {
                Payment payment = (Payment)it.newInstance();
                PAYMENT_MAP.put(it.getSimpleName(), payment);
            } catch (InstantiationException | IllegalAccessException ignored) {

            }
        }
    }

    public Payment get(StrategyEnum keyEnum) {
        return PAYMENT_MAP.get(keyEnum.getKey());
    }

}


那我们对我们上面的测试类也进行改造下,


    @DisplayName("策略应用")
    @Test
    public void testStrategy2() {
        StrategyFactory strategyFactory = new StrategyFactory();
        Payment payment = strategyFactory.get(StrategyEnum.CASH);
        Shopping shopping = new Shopping(payment);
        shopping.buyDesktop();
    }

20230820144426

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/83185.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【自动电压调节器】无功功率控制的终端电压控制研究(Simulink)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…

【IMX6ULL驱动开发学习】07.驱动程序分离的思想之平台总线设备驱动模型和设备树

一、驱动程序分离的思想 【IMX6ULL驱动开发学习】05.字符设备驱动开发模板&#xff08;包括读写函数、poll机制、异步通知、定时器、中断、自动创建设备节点和环形缓冲区&#xff09;_阿龙还在写代码的博客-CSDN博客 之前编写驱动程序的代码存在不少弊端&#xff1a;移植性差…

Redis从基础到进阶篇(一)

目录 一、了解NoSql 1.1 什么是Nosql 1.2 为什么要使用NoSql 1.3 NoSql数据库的优势 1.4 常见的NoSql产品 1.5 各产品的区别 二、Redis介绍 2.1什么是Redis 2.2 Redis优势 2.3 Redis应用场景 2.4 Redis下载 三、Linux下安装Redis 3.1 环境准备 3.2 Redis的…

广告牌安全传感器,实时监测事故隐患尽在掌握

在现代城市中&#xff0c;广告牌作为商业宣传的重要媒介&#xff0c;已然成为城市中一道独特的风景线。然而&#xff0c;随着城市迅速发展&#xff0c;广告牌的安全问题也引起了大众关注。广告招牌一般悬挂于建筑物高处&#xff0c;量大面大。由于设计、材料、施工方法的缺陷&a…

windows电脑系统自带的画图工具如何实现自由拼图

1.首先选中你要拼接的第一张图片&#xff0c;右键选着编辑&#xff0c;会自动打开自带的画图工具 然后就是打开第一张图片&#xff0c;如下图所示 接着就是将画布托大&#xff0c;如下图所示。 然后点击选择&#xff0c;选择下面的空白区域&#xff0c;选着区域的范围要比准备拼…

企微配置回调服务

1、企微配置可信域名 2、企微获取成员userID 3、企微获取用户敏感数据 4、企微配置回调服务 文章目录 一、简介1、概述2、相关文档地址 二、企微配置消息服务器1、配置消息接收参数2、参数解析3、参数拼接规则 三、代码编写—使用已有库1、代码下载2、代码修改3、服务代码编写 …

阿里云轻量应用服务器和云服务器有什么区别?2023更新

阿里云轻量应用服务器和云服务器ECS有什么区别&#xff1f;ECS是专业级云服务器&#xff0c;轻量应用服务器是轻量级服务器&#xff0c;轻量服务器使用门槛更低&#xff0c;适合个人开发者或中小企业新手使用&#xff0c;可视化运维&#xff0c;云服务器ECS适合集群类、高可用、…

gor工具http流量复制、流量回放,生产运维生气

gor是一款流量复制回放工具&#xff0c;gor工具的官网&#xff1a;https://goreplay.org/ 1、对某个端口的http流量进行打印 ./gor --input-raw :8000 --output-stdout 2、对流量实时转发&#xff0c;把81端口流量转发到192.168.3.221:80端口 ./gor --input-raw :81--output-ht…

Qt+Pyhton实现麒麟V10系统下word文档读写功能

目录 前言1.C调用python1.1 安装Python开发环境1.2 修改Qt工程配置1.3 初始化Python环境1.4 C 调用Python 函数1.5 常用的Python接口 2.python虚拟环境2.1Python虚拟环境简介2.2 virtualenv 安装及使用2.3 在C程序中配置virtualenv 虚拟环境 3.python-docx库的应用4.总结 前言 …

基于YOLOv8模型和PCB电子线路板缺陷目标检测系统(PyTorch+Pyside6+YOLOv8模型)

摘要&#xff1a;基于YOLOv8模型PCB电子线路板缺陷目标检测系统可用于日常生活中检测与定位PCB线路板瑕疵&#xff0c;利用深度学习算法可实现图片、视频、摄像头等方式的目标检测&#xff0c;另外本系统还支持图片、视频等格式的结果可视化与结果导出。本系统采用YOLOv8目标检…

panda3d加载模型复习和python面向对象编程属性学习

运行一个python示例&#xff1b;然后去除一些代码&#xff0c;只剩下加载模型相关&#xff0c;如下&#xff1b; from panda3d.core import loadPrcFileData # Configure the parallax mapping settings (these are just the defaults) loadPrcFileData("", "p…

Vue.js知识点学习的一点笔记

一、虚拟DOM 1、原生JS是命令式编程&#xff0c;当渲染在页面的数据发生一点点变化&#xff0c;需要整个重新渲染一编。vue.js渐进式框架有个虚拟DOM的概念&#xff0c;运用diff算法&#xff0c;比较新旧数据&#xff0c;相同的数据不变不重渲染&#xff0c;不同的部分新数据覆…

python 连接Redis 数据库

pip install redis python代码 import redis# 连接数据库 r redis.Redis(host192.168.56.15, port6379, db0)# 存储数据 #r.set(key, value) r.set(name, zaraNet)# 获取数据 value r.get(name) print(value)# 关闭连接&#xff08;可选&#xff09; r.close()

spring boot 整合mongodb

1、安装依赖 <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-mongodb</artifactId></dependency>2、配置数据库连接 spring:data:mongodb:host: localhostport: 27017username: xxxxxxp…

.fargo后缀勒索病毒|勒索病毒解密恢复|fargo勒索病毒解密|勒索病毒解密恢复|数据库恢复

fargo勒索病毒概述&#xff0c;fargo勒索病毒解密恢复及日常防护建议 目录&#xff1a; fargo勒索病毒介绍感染fargo勒索病毒后的表现fargo勒索病毒的感染形式如何恢复.fargo后缀勒索病毒fargo勒索病毒日常防护建议 简介&#xff1a; 河北某有限公司的财务系统&#xff0c;由…

拼多多商品详情API接入站点,实时数据json格式示例

作为国内最大的电商平台之一&#xff0c;拼多多数据采集具有多个维度。 有人需要采集商品信息&#xff0c;包括品类、品牌、产品名、价格、销量等字段&#xff0c;以了解商品销售状况、热门商品属性&#xff0c;进行市场扩大和重要决策&#xff1b; 商品数据&#xff1a;拼…

【数字实验室】时钟切换

大部分开发者使用 BUFGCTRL 或 BUFGMUX进行时钟切换&#xff0c;它们在时钟切换上可以提供无毛刺输出。然而&#xff0c;了解所涉及的原理是有好处的。 当然&#xff0c;无论我们在同步逻辑中使用哪种技术&#xff0c;重要的是要确保在进行时钟切换时输出上没有毛刺。任何故障都…

docker安装Oracle11gR2

文章目录 目录 文章目录 前言 一、前期准备 二、具体配置 2.1 配置oracle容器 2.2 配置navicat连接 总结 前言 使用docker模拟oracle环境 一、前期准备 安装好docker #拉取镜像 docker pull registry.cn-hangzhou.aliyuncs.com/helowin/oracle_11g #启动 docker run -…

YOLOv5改进系列(22)——替换主干网络之MobileViTv1(一种轻量级的、通用的移动设备 ViT)

【YOLOv5改进系列】前期回顾: YOLOv5改进系列(0)——重要性能指标与训练结果评价及分析 YOLOv5改进系列(1)——添加SE注意力机制

安防监控/视频集中存储/云存储平台EasyCVR v3.3增加首页告警类型

安防监控/视频集中存储/云存储EasyCVR视频汇聚平台&#xff0c;可支持海量视频的轻量化接入与汇聚管理。平台能提供视频存储磁盘阵列、视频监控直播、视频轮播、视频录像、云存储、回放与检索、智能告警、服务器集群、语音对讲、云台控制、电子地图、平台级联、H.265自动转码等…