设计模式-规格模式

news2024/12/23 17:15:44
设计模式专栏

    • 模式介绍
    • 模式特点
    • 应用场景
    • 规格模式和策略模式的区别和联系
    • 代码示例
      • Java实现规格模式
      • Python实现规格模式
    • 规格模式在spring中的应用


模式介绍

规格模式(Specification Pattern)是一种行为设计模式,其目的是将业务规则封装成可重用的对象,并能够动态地组合这些规则,以实现更复杂的业务逻辑。规格模式的基本介绍如下:

  1. 定义:规格模式可以认为是组合模式的一种扩展。在程序中,某些条件决定了业务逻辑,这些条件可以抽离出来以某种关系(与、或、非)进行组合,从而灵活地对业务逻辑进行定制。在查询、过滤等应用场合中,通过预定义多个条件,然后使用这些条件的组合来处理查询或过滤,而不是使用逻辑判断语句来处理,可以简化整个实现逻辑。这里的每个条件都是一个规格,多个规格(条件)通过串联的方式以某种逻辑关系形成一个组合式的规格。规格模式属于结构型设计模式。
  2. 意图:将一个业务规则表示为一个对象,并且将多个规则组合成更为复杂的规则。该模式可以将规则的表示与规则的实现分离,从而实现可扩展性、可维护性和可重用性。
  3. 应用场景:
  • 验证对象:检验对象本身是否满足某些业务要求或者是否已经为实现某个业务目标做好了准备。
  • 从集合中选择符合特定业务规则的对象或对象子集。
  • 指定在创建新对象的时候必须要满足某种业务要求。

规格模式是一种常用的软件设计模式,通过将业务规则封装成可重用的对象并动态组合,可以灵活地定制业务逻辑,简化实现过程,提高系统的可维护性和可扩展性。

在这里插入图片描述

模式特点

规格模式的特点主要有以下几个方面:

  1. 可维护性:规格模式将业务规则进行抽象和组合,使得规则的实现与表示分离,便于业务规则的维护和更新。
  2. 可扩展性:通过组合多个规则,规格模式可以实现更为复杂的规则,从而支持业务的变化和扩展。
  3. 可重用性:将业务规则封装成对象,可以在不同的场景中进行复用,从而减少代码冗余。
  4. 复杂性:规格模式的实现过程较为复杂,需要花费一定的时间和精力。
  5. 灵活的业务逻辑定制:规格模式允许通过组合多个规格来灵活地定制业务逻辑,这在查询、过滤等应用场合中尤其有用。
  6. 适合从集合中选择对象:规格模式非常适合在多个对象中筛选查找,或者在业务规则不适于放在任何已有实体或值对象中,而且规则变化和组合会掩盖对象的基本含义的情况。

规格模式提供了一种结构化的方式来组合和表示业务规则,使得系统更具可维护性、可扩展性和可重用性。同时,这种模式也有助于简化实现逻辑,并使得业务逻辑更加灵活和可定制。

在这里插入图片描述

应用场景

规格模式主要适用于以下应用场景:

  1. 验证对象:检验对象本身是否满足某些业务要求或者是否已经为实现某个业务目标做好了准备。
  2. 从集合中选择符合特定业务规则的对象或对象子集
  3. 指定在创建新对象的时候必须要满足某种业务要求

规格模式主要应用于需要根据一系列的业务规则来对对象进行筛选、过滤、匹配或组合的场景中。这些场景需要能够灵活地定义和组合规则,以应对业务需求的变化和扩展。

在这里插入图片描述

规格模式和策略模式的区别和联系

规格模式和策略模式是两种不同的软件设计模式,它们各自有着不同的目的和应用场景。

  1. 规格模式(Specification Pattern):
  • 定义:规格模式是一种行为设计模式,其目的是将业务规则封装成可重用的对象,并能够动态地组合这些规则,以实现更复杂的业务逻辑。
  • 意图:将一个业务规则表示为一个对象,并且将多个规则组合成更为复杂的规则。该模式可以将规则的表示与规则的实现分离,从而实现可扩展性、可维护性和可重用性。
  • 应用场景:验证对象、从集合中选择符合特定业务规则的对象或对象子集、指定在创建新对象的时候必须要满足某种业务要求。
  1. 策略模式(Strategy Pattern):
  • 定义:策略模式是一种行为设计模式,它提供了一系列的算法,并将每一个算法封装起来,使它们可以互相替换。策略模式的目的是使算法的变化独立于使用它们的客户端代码。
  • 意图:策略模式通过将一系列算法封装成独立的策略类,使得算法可以独立于客户端代码进行变化。这种设计模式使得客户端代码可以更加专注于业务逻辑,而不必关心具体的算法实现。
  • 应用场景:避免冗长的 if-else 或 switch 分支判断、提供框架的扩展点、当需要多个功能相似的类并且需要它们之间可以灵活切换时。

区别:

  • 规格模式关注的是业务规则的动态组合和表达,通过将业务规则封装成可重用的对象来实现更复杂的业务逻辑。
  • 策略模式关注的是算法的独立性和变化,通过将一系列算法封装成独立的策略类,使得算法可以独立于客户端代码进行变化。

联系:

  • 两者都属于行为设计模式,旨在通过不同的方式解决业务逻辑或算法的动态性问题。
  • 在某些情况下,规格模式和策略模式可以结合使用。例如,在规格模式中,可以将每个规格视为一个独立的策略类,通过将多个规格组合在一起形成更复杂的业务逻辑。而在策略模式中,也可以使用规格模式来封装不同的算法选择逻辑。

总的来说,规格模式和策略模式虽然有所不同,但在某些情况下它们是可以结合使用的。在选择使用哪种模式时,应根据具体的应用场景和需求来决定。

在这里插入图片描述

代码示例

Java实现规格模式

规格模式在Java中的实现主要涉及到创建规格接口和具体规格类,然后通过组合这些规格类来实现更复杂的业务逻辑。

以下是一个简单的Java实现规格模式的示例:

// 定义规格接口
public interface Specification {
    boolean isSatisfied();
}

// 具体规格类
public class SpecificationA implements Specification {
    @Override
    public boolean isSatisfied() {
        // 具体实现
        return true;
    }
}

public class SpecificationB implements Specification {
    @Override
    public boolean isSatisfied() {
        // 具体实现
        return true;
    }
}

// 组合多个规格类
public class CompositeSpecification implements Specification {
    private List<Specification> specifications = new ArrayList<>();

    public void add(Specification spec) {
        specifications.add(spec);
    }

    @Override
    public boolean isSatisfied() {
        for (Specification spec : specifications) {
            if (!spec.isSatisfied()) {
                return false;
            }
        }
        return true;
    }
}

在上述示例中,我们定义了一个规格接口Specification,然后创建了两个具体规格类SpecificationASpecificationB,它们都实现了Specification接口。我们还创建了一个组合规格类CompositeSpecification,它可以包含多个规格对象,并通过循环检查每个规格对象是否满足条件,来确定整个组合规格是否满足。

通过使用组合规格类,我们可以根据业务需求动态地组合多个规格对象,从而实现更复杂的业务逻辑。例如,我们可以创建一个组合规格对象,然后向其中添加多个具体规格对象,最后通过调用组合规格对象的isSatisfied()方法来判断是否满足所有条件。这种设计模式使得规则的表示与规则的实现分离,提高了系统的可维护性和可重用性。

Python实现规格模式

规格模式在Python中的实现方式与Java类似,主要是通过定义规格接口和具体规格类,然后通过组合这些规格类来实现更复杂的业务逻辑。

以下是一个Python实现规格模式的示例:

# 定义规格接口
class Specification:
    def is_satisfied(self):
        pass

# 具体规格类
class SpecificationA(Specification):
    def is_satisfied(self):
        # 具体实现
        return True

class SpecificationB(Specification):
    def is_satisfied(self):
        # 具体实现
        return True

# 组合多个规格类
class CompositeSpecification(Specification):
    def __init__(self):
        self.specifications = []

    def add(self, spec):
        self.specifications.append(spec)

    def is_satisfied(self):
        for spec in self.specifications:
            if not spec.is_satisfied():
                return False
        return True

在上述示例中,我们定义了一个规格接口Specification,然后创建了两个具体规格类SpecificationASpecificationB,它们都继承了Specification类。我们还创建了一个组合规格类CompositeSpecification,它可以包含多个规格对象,并通过循环检查每个规格对象是否满足条件,来确定整个组合规格是否满足。

通过使用组合规格类,我们可以根据业务需求动态地组合多个规格对象,从而实现更复杂的业务逻辑。例如,我们可以创建一个组合规格对象,然后向其中添加多个具体规格对象,最后通过调用组合规格对象的is_satisfied()方法来判断是否满足所有条件。这种设计模式使得规则的表示与规则的实现分离,提高了系统的可维护性和可重用性。

在这里插入图片描述

规格模式在spring中的应用

规格模式在Spring框架中也有广泛的应用,主要涉及到查询和条件组合等场景。以下是一些具体的例子:

  1. Spring Data JPA的Specification接口:Spring Data JPA提供了一个Specification接口,用于构建查询条件。用户可以通过实现该接口来定义自己的查询条件,然后通过Repository的findAll方法传入Specification对象,即可执行相应条件的查询。
  2. Spring MVC的HandlerMethodArgumentResolver:在Spring MVC中,可以通过实现HandlerMethodArgumentResolver接口来定义请求参数的处理方式。该接口的resolveArgument方法可以用来解析请求参数,并生成相应的对象。在方法参数上使用@RequestParam注解,即可将请求参数绑定到对应的对象属性上。
  3. Spring Security的SecurityExpressionRoot:在Spring Security中,可以使用SecurityExpressionRoot类来构建安全表达式。该类提供了一系列的方法来构建条件表达式,例如hasRole、hasAuthority等。通过将这些表达式组合起来,可以实现复杂的权限控制逻辑。

规格模式在Spring框架中有着广泛的应用,可以帮助用户灵活地构建查询条件、处理请求参数和实现复杂的权限控制逻辑。

在这里插入图片描述

设计模式-策略模式

设计模式-多例模式

设计模式-观察者模式

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【笔记】书生·浦语大模型实战营——第三课(基于 InternLM 和 LangChain 搭建你的知识库)

【参考&#xff1a;tutorial/langchain at main InternLM/tutorial】 【参考&#xff1a;(3)基于 InternLM 和 LangChain 搭建你的知识库_哔哩哔哩_bilibili-【OpenMMLab】】 笔记 基础作业 这里需要等好几分钟才行 bug&#xff1a; 碰到pandas相关报错就卸载重装 输出文字…

【野火i.MX6ULL开发板】开发板连接网络(WiFi)与 SSH 登录、上电自动登录、设置静态IP、板子默认参数

0、前言 参考之前自己写的&#xff1a; http://t.csdnimg.cn/g60P8 参考资料&#xff1a; [野火]《Linux基础与应用开发实战指南——基于i.MX6ULL开发板》_20230323 从野火官网下载 参考博客&#xff1a; http://t.csdnimg.cn/8uh4O 参考官方文档&#xff1a; https://doc.…

【算法每日一练]-练习篇 #Tile Pattern #Swapping Puzzle # socks

目录 今日知识点&#xff1a; 二维前缀和 逆序对 袜子配对(感觉挺难的&#xff0c;又不知道说啥) Tile Pattern Swapping Puzzle socks Tile Pattern 331 题意&#xff1a;有一个10^9*10^9的方格。W表示白色方格&#xff0c;B表示黑色方格。每个(i,j)方的颜色由(i…

PowerDesigner简介以及简单使用

软件简介&#xff1a; PowerDesigner是Sybase公司开发的数据库设计工具&#xff0c;开发人员能搞利用PowerDesigner开发数据流程图、各数据模型如物理数据模型&#xff0c;可以分别从概念数据模型(Conceptual Data Model)和物理数据模型(Physical Data Model)两个层次对数据库…

一点一点,照亮你的美

一、实验要求 当鼠标点击屏幕时&#xff0c;随机出现大大小小的星星闪烁&#xff0c;犹如夜晚的星空 二、实验思路 设置图片的大小 设置事件&#xff08;当鼠标点一下&#xff0c;获取一张图片&#xff09; 设置图片的位置 设置鼠标的位置和图片的相对位置 设置随机大小 …

如何使用GaussDB创建脱敏策略(MASKING POLICY)

目录 一、前言 二、GaussDB中的脱敏策略 1、数据脱敏的定义 2、创建脱敏策略的语法说明 三、在GaussDB中如何创建数据脱敏策略(示例) 1、创建脱敏策略的一般步骤 2、GaussDB数据库中创建脱敏策略的完整示例 1&#xff09;开启安全策略开关&#xff0c;以初识用户omm登录…

这6个设计小白学习网站,海量免费学习教程!

划到最后“阅读原文”——领取工具包&#xff08;超过1000工具&#xff0c;免费素材网站分享和行业报告&#xff09; Hi&#xff0c;我是胡猛夫~&#xff0c;专注于分享各类价值网站、高效工具&#xff01; ​更多资源&#xff0c;更多内容&#xff0c;欢迎交流&#xff01;公…

Unity编辑器扩展(外挂)

每日一句:未来的样子藏在现在的努力里 目录 什么是编译器开发 C#特性[System.Serializable] 特殊目录 命名空间 /*检视器属性控制*/ //添加变量悬浮提示文字 //给数值设定范围&#xff08;最小0&#xff0c;最大150&#xff09; //指定输入框&#xff0c;拥有5行 //默认…

寄快递选哪个平台便宜?快递优惠券免费领取!

寄快递选哪个平台便宜&#xff1f;快递优惠券免费领取&#xff01; 对于市场来说&#xff0c;快递业是非常重要的一部分&#xff0c;它业既贯通市场流通消费投资出口的各环节&#xff0c;又关联一二三各产业。根据相关数据显示&#xff0c;我国的快递行业正呈现势如破竹的劲头&…

双位置继电器DLS-5/2TH 额定电压:110VDC 触点形式:7开3闭 柜内安装

系列型号&#xff1a; DLS-5/1电磁式双位置继电器; DLS-5/2电磁式双位置继电器; DLS-5/3电磁式双位置继电器; DLS-5/2G电磁式双位置继电器; DLS-5/3 220VDC双位置继电器 一、用途 1.1用途 DLS-5双位置继电器(以下简称产品)用于各种保护与自动控制系统中&#xff0c;作为切换…

x-cmd pkg | magick - 开源图像处理工具

目录 简介首次用户功能特点类似工具与竞品进一步探索 简介 magick 是由 ImageMagick 提供的一个功能强大且多功能的开源图像处理工具&#xff0c;可以灵活高效地处理图像文件&#xff0c;例如格式转换、图像大小调整、图像裁减、图像拼接、图像色彩校正和图像合成等常见的图像…

神州战神z7ra7重装教程

UEFI模式下装的系统&#xff0c;开机速度明显比Legacy模式下装的系统开机速度更快 关键点&#xff1a; ①.U盘格式必须为FAT32 ②.不可以使用ISO镜像制作UEFI安装U盘&#xff0c;而是使用微软官方的工具。 ③.开机BIOS设置&#xff0c;最好将Secure boot设置为Disabled&#xf…

[Kubernetes]8. K8s使用Helm部署mysql集群(主从数据库集群)

上一节讲解了K8s包管理工具Helm、使用Helm部署mongodb集群(主从数据库集群),这里来看看K8s使用Helm部署mysql集群(主从数据库集群) 一.Helm 搭建mysql集群 1.安装mysql不使用persistence(无本地存储) 无本地存储:当重启的时候,数据库消失 (1).打开官网的应用中心 打开应用中…

Linux内存管理:(六)页交换算法

文章说明&#xff1a; Linux内核版本&#xff1a;5.0 架构&#xff1a;ARM64 参考资料及图片来源&#xff1a;《奔跑吧Linux内核》 Linux 5.0内核源码注释仓库地址&#xff1a; zhangzihengya/LinuxSourceCode_v5.0_study (github.com) 1. 引言 在Linux操作系统中&#x…

【AI】CycleGan对抗生成网络遥感影像生成地图效果测试

今天看到一个有趣的项目&#xff0c;CycleGan对抗生成网络把马生成成斑马&#xff0c;还有一个测试用例是用遥感影像生成平面地图的效果&#xff0c;效果如下图所示&#xff0c;我大学是遥感专业&#xff0c;看到遥感影像就触动了我的原神&#xff0c;于是原神启动&#xff0c;…

@Transactional 事务注解

第一、先简单介绍一下Spring事务的传播行为 所谓事务的传播行为是指&#xff0c;如果在开始当前事务之前&#xff0c;一个事务上下文已经存在&#xff0c;此时有若干选项可以指定一个事务性方法的执行行为。在TransactionDefinition定义中包括了如下几个表示传播行为的常量&…

C++学习笔记——返回对象

一、返回对象 当我们说一个函数返回对象时&#xff0c;意味着该函数的返回值是一个对象。这种情况下&#xff0c;函数可以通过创建对象的副本、返回对象的引用或者返回对象的指针来实现。 返回对象的副本&#xff1a; 当一个函数返回对象的副本时&#xff0c;函数内部会创建一…

VSCode使用MinGW编译器,配置C/C++环境

目录 一、安装VSCode 二、安装MinGW编译器 1、配置环境变量 2、测试配置是否成功 三、配置VSCode 1、安装所需扩展 2、新建代码存放文件夹 3、添加配置文件 4、配置文件内容 &#xff08;1&#xff09;c_cpp_properties.json &#xff08;2&#xff09;launch.json …

11 个 Python全栈开发工具集

前言 以下是专注于全栈开发不同方面的 Python 库;有些专注于 Web 应用程序开发&#xff0c;有些专注于后端&#xff0c;而另一些则两者兼而有之。 1. Taipy Taipy 是一个开源的 Python 库&#xff0c;用于构建生产就绪的应用程序前端和后端。 它旨在加快应用程序开发&#xf…

数字战场上的坚固屏障:雷池社区版(WAF)

黑客的挑战 智能语义分析算法&#xff1a; 黑客们常利用复杂技术进行攻击&#xff0c;但雷池社区版的智能语义分析算法能深入解析攻击本质&#xff0c;即使是最复杂的攻击手法也难以逃脱。 0day攻击防御&#xff1a; 传统防火墙难以防御未知攻击&#xff0c;但雷池社区版能有效…