【设计模式-4.1】行为型——策略模式

说明:本文介绍设计模式中的行为型设计模式中的,策略模式;

计算器

策略模式属于行为型设计模式,关注对象的行为。例如,目前有一个计算器类,可对两个数进行加减计算,如下:

(Calculator,计算器类)

/**
 * 计算器
 */
public class Calculator {
    /**
     * 加法
     */
    public static int add(int a, int b) {
        return a + b;
    }

    /**
     * 减法
     */
    public static int subtract(int a, int b) {
        return a - b;
    }
}

(Client,客户端,使用计算器的加法、减法)

/**
 * 客户端
 */
public class Client {
    public static void main(String[] args) {
        // 1. 加法
        System.out.println(Calculator.add(1, 2));

        // 2. 减法
        System.out.println(Calculator.subtract(1, 2));
    }
}

执行结果;

在这里插入图片描述

从这个简单的例子中就可以看出问题,扩展性差,如果需要增加乘法、减法或其他种种两个数运算的方法,都需要去修改计算器类。

我们可以考虑将计算器类中的计算方法抽出来称为一个抽象方法,让所有计算方法类都去实现这个接口,然后在计算器类中注入一个计算方法。如下:

(Computation,计算接口)

/**
 * 计算接口
 */
public interface Computation {

    /**
     * 计算方法
     */
    int compute(int num1, int num2);
}

(AddCompute,加法实现)

/**
 * 加法计算
 */
public class AddCompute implements Computation{

    @Override
    public int compute(int num1, int num2) {
        return num1 + num2;
    }
}

(SubCompute,减法实现)

/**
 * 减法计算
 */
public class SubCompute implements Computation{

    @Override
    public int compute(int num1, int num2) {
        return num1 - num2;
    }
}

(Calculator,计算器类,注入一个计算对象)

/**
 * 计算器
 */
public class Calculator {

    private Computation computation;

    public void setComputation(Computation computation) {
        this.computation = computation;
    }

    /**
     * 计算方法
     */
    public int compute(int num1, int num2) {
        return this.computation.compute(num1, num2);
    }
}

(Client,客户端,使用什么计算,就new什么计算方式)

/**
 * 客户端
 */
public class Client {
    public static void main(String[] args) {
        Calculator calculator = new Calculator();
        calculator.setComputation(new AddCompute());

        // 1. 加法
        System.out.println(calculator.compute(1, 2));

        // 2. 减法
        calculator.setComputation(new SubCompute());
        System.out.println(calculator.compute(1, 2));
    }
}

运行结果;

在这里插入图片描述

通过策略模式,将多种计算方法,从类中抽出来成一个个具体实现类,再创建一个统一的接口,使其实现该接口。这样,不论以后有多少计算方式,都可以创建具体实现类,实现其接口来添加,而不需要对现有的系统做改动。提高了扩展性。

登录方式

策略模式在项目开发中的一个应用是,对多种登录方式的整合。如下:

(LoginMethod,登录方式接口)

/**
 * 登录方式
 */
public interface LoginMethod {

    /**
     * 登录
     * @return
     */
    String login();
}

(PhoneServiceImpl,具体实现类,手机号登录,Bean名称:phone)

import org.springframework.stereotype.Service;

@Service("phone")
public class PhoneServiceImpl implements LoginMethod {
    @Override
    public String login() {
        return "手机号登录";
    }
}

(PasswordServiceImpl,具体实现类,账号密码登录,Bean名称:password)

import org.springframework.stereotype.Service;

@Service("password")
public class PasswordServiceImpl implements LoginMethod {
    @Override
    public String login() {
        return "账号密码登录";
    }
}

(WXLoginServiceImpl,具体实现类,微信登录,Bean名称:wx)

import org.springframework.stereotype.Service;

@Service("wx")
public class WXLoginServiceImpl implements LoginMethod {
    @Override
    public String login() {
        return "微信登录";
    }
}

(LoginController,登录Controller,传递登录类型)

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping
public class LoginController {

    @Autowired
    private LoginService loginService;

    @PostMapping("/login")
    public String login(String loginType) {
        return loginService.executeLogin(loginType);
    }
}

(LoginService,登录接口)

public interface LoginService {

    /**
     * 根据登录方式执行登录
     *
     * @param loginType
     * @return
     */
    String executeLogin(String loginType);
}

(LoginServiceImpl,登录实现类,使用applicationContext.getBean方法获取对应的登录具体实现类,执行其方法,执行对应的登录方式

import com.hezy.service.LoginMethod;
import com.hezy.service.LoginService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Service;

/**
 * 登录服务实现类
 */
@Service
public class LoginServiceImpl implements LoginService {

    @Autowired
    private ApplicationContext applicationContext;

    @Override
    public String executeLogin(String loginType) {
        LoginMethod loginMethod = (LoginMethod) applicationContext.getBean(loginType);
        return loginMethod.login();
    }
}

启动项目,使用apifox查看执行效果;

在这里插入图片描述


在这里插入图片描述


在这里插入图片描述

当然,这只是一个框架。实际开发,登录需要的信息很多。登录方式肯定是作为一个字段值传入的,如DTO中的一个属性值,具体的登录实现也是需要编写大量代码的,账号密码登录的是去查数据库,手机号登录的是去实现第三方SDK,微信登录的是实现微信登录的SDK。

以上就是策略模式的实现,通过两个例子可以看出,策略模式是对多种解决方案的封装,通过将解决方案设计成接口>具体实现类组合的方式,提高了系统的扩展性,非常实用。

总结

本文参考《设计模式的艺术》、《秒懂设计模式》两书

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

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

相关文章

中国湖泊面积-水位长时序数据产品(2000-2020)

今天我们分享中国湖泊面积-水位长时序数据产品(2000-2020) 该数据集包含中国典型湖泊2000-2020年最大水体面积、多年平均面积、水位变化速率及空间分布矢量。 数据溯源信息 「数据来源描述」Landsat、HJ、ZY、Jason、ENVISAT、Cryosat、ICESat和HY 「数…

【Linux】信号概念和信号的产生

文章目录 一、什么是信号?1.signal系统调用2.从硬件解析键盘数据如何输入给内核3.同步和异步 二、信号的产生1.键盘组合键2. kill命令3.系统调用接口3.1kill3.2 raise3.3abort 4.异常5.软件条件 重谈core dump标志位 一、什么是信号? 以日常为例&#x…

lv11 嵌入式开发 中断处理 15

前言:中断属于7种异常的1种,这节主要讲CPU接收到中断之后怎么处理,回顾之前的知识。 目录 1 异常 1.1 概念 1.2 异常处理机制 1.3 ARM异常源 1.4 异常模式 1.5 ARM异常响应 1.6 异常向量表 1.7 异常返回 ​编辑 1.8 IRQ异常举例 …

Android 缩减、混淆处理和优化应用

为了尽可能减小应用的大小,您应在发布 build 中启用缩减功能来移除不使用的代码和资源。启用缩减功能后,您还会受益于两项功能,一项是混淆处理功能,该功能会缩短应用的类和成员的名称;另一项是优化功能,该功…

无效的目标发行版: 21 和springboot爆错

目录 问题描述 原因分析: 问题描述 springboot爆红 调整一下这个:把这里的version调低一点应该就可以了 无效的目标发行版: 21 调整一下这个把这里的Java version调整一下,我是调整到1.8(其他没有试过) 原因分析&a…

基于ASP的购物网站设计

摘 要 随着计算机科学的不断发展和网络的迅速普及,Internet 的应用已经涉及到人们生活的方方面面,越来越多的现代企业也意识到了这一点,如何在当前的网络大发展的背景下开拓市场已经成为了企业关注的重中之重。总的来说,互联网的…

一篇五分生信临床模型预测文章代码复现——Figure 10.机制及肿瘤免疫浸润(七)

之前讲过临床模型预测的专栏,但那只是基础版本,下面我们以自噬相关基因为例子,模仿一篇五分文章,将图和代码复现出来,学会本专栏课程,可以具备发一篇五分左右文章的水平: 本专栏目录如下: Figure 1:差异表达基因及预后基因筛选(图片仅供参考) Figure 2. 生存分析,…

【计算机网络学习之路】URL概念及组成

目录 一. URL是什么 二. URL的组成 三. encode和decode 前言 本系列文章是计算机网络学习的笔记,欢迎大佬们阅读,纠错,分享相关知识。希望可以与你共同进步。 本篇讲解使用浏览器不可或缺的部分——URL 一. URL是什么 域名及DNS 我们在…

第一百八十六回 DropdownMenu组件

文章目录 1. 概念介绍2. 使用方法2.1 DropdownMenu2.1 DropdownMenuEntry 3. 示例代码4. 内容总结 我们在上一章回中介绍了"如何禁止页面跟随手机自动旋转"相关的内容,本章回中将介 绍DropdownMenu组件.闲话休提,让我们一起Talk Flutter吧。 …

Azure Machine Learning - 在 Azure AI 搜索中创建全文查询

Azure AI搜索中如果要为全文搜索生成查询,本文提供了设置请求的步骤。 本文还介绍了查询结构,并说明了字段属性和语言分析器如何影响查询结果。 关注TechLead,分享AI全维度知识。作者拥有10年互联网服务架构、AI产品研发经验、团队管理经验&a…

【Cisco Packet Tracer】交换机 学习/更新/泛洪/VLAN实验

交换机的功能是连接计算机、服务器、网络打印机、网络摄像头、IP电话等终端设备,并实现与其它交换机、无线接入点、路由器、网络防火墙等网络设备的互联,从而构建局域网络,实现所有设备之间的通信。 本文使用Cisco Packet Tracer仿真软件&…

高效转码工具Compressor for Mac,让视频处理更轻松

在现如今的数字时代,视频内容已经成为人们生活中不可或缺的一部分。无论是在社交媒体上分享生活点滴,还是在工作中制作专业的营销视频,我们都希望能够以高质量、高效率地处理和传输视频文件。而Compressor for Mac作为一款强大的视频转码工具…

电大搜题微信公众号详解,助力学习者轻松考试

作为一名电大学者,我今天要向大家介绍一个引人注目的学习利器,那就是电大搜题微信公众号。对于广西开放大学的学习者们来说,这个微信公众号无疑将是他们学习路上的得力助手。 广西开放大学一直注重学生的学习体验和教学质量,为了…

【PTA-C语言】实验三-循环结构I

如果代码存在问题,麻烦大家指正 ~ ~有帮助麻烦点个赞 ~ ~ 实验三-循环结构I 7-1 求交错序列前N项和 (分数 15)7-2 寻找250(分数 15)7-3 最大公约数和最小公倍数(分数 15)7-4 统计字符&#xff0…

搭建nfs文件目录共享

搭建nfs文件目录共享 一、简介 NFS,英文全称是Network File System,中文全称是网络文件系统,是FreeBSD支持的文件系统中的一种,它允许网络中的计算机之间通过TCP/IP网络共享资源,在NFS应用中,本地NFS的客…

执行栈和执行上下文

前端面试大全JavaScript执行栈和执行上下文 🌟经典真题 🌟执行上下文 🌟栈数据结构 🌟执行上下文生命周期 🌟真题解答 🌟总结 🌟经典真题 谈谈你对 JavaScript 执行上下文栈理解 &#…

企业计算机服务器中了locked1勒索病毒怎么解锁,locked1勒索病毒数据恢复

随着网络技术在企业的不断应用,企业的生产运营效率得到了极大提升,越来越多的企业利用网络开展工作,这也导致了企业的受到的网络安全威胁也不断增加。在本月,云天数据恢复中心陆续接到很多企业的求助,企业的计算机服务…

Screenshot To Code

序言 对于GPT-4我只是一个门外汉,至于我为什么要了解screenshot to code,只是因为我想知道,在我不懂前端设计的情况下,能不能通过一些工具辅助自己做一些简单的前端界面设计。如果你想通过此文深刻了解GPT-4或者该开源项目&#…

内部类Lambda

静态内部类 /*** 静态成员是在类加载成字节码时就已经存在的,静态只能访问静态*/ public class Demo {public static void main(String[] args) {Outer.Inner.show();} }class Outer {int num1 10;static int num2 20;static class Inner {static void show() {Outer outer …

重庆市失业金申领流程

1.领失业金的前提:非本人意愿中断就业。个人理解就是不是主动辞职才能领。 2.因此公司在处理社保减员的时候,不能是劳动者主动提出离职。 3.社保减员可选择原因:其他原因中断缴费 / 由单位提出双方协商一致解除劳动合同。 4.当社保暂停缴费…