当前位置: 首页 > article >正文

设计模式简述(二十)规格模式

规格模式

  • 描述
    • 组件
  • 使用

描述

规格模式并不在传统的23设计模式中,属于后面扩展的设计模式。
简单描述就是对一批数据进行多条件(包括逻辑组合、有点装饰器的感觉,可以不断套娃)匹配。

组件

  • 实体
package dp.spec;/*** TODO** @author kal* @version 1.0.0* @date 2025/5/25 23:13*/
public class User {private Long id;private String name;private Integer age;private String gender;public User(Long id, String name, Integer age, String gender) {this.id = id;this.name = name;this.age = age;this.gender = gender;}public Long getId() {return id;}public void setId(Long id) {this.id = id;}public String getName() {return name;}public void setName(String name) {this.name = name;}public Integer getAge() {return age;}public void setAge(Integer age) {this.age = age;}public String getGender() {return gender;}public void setGender(String gender) {this.gender = gender;}@Overridepublic String toString() {return "User{" +"id=" + id +", name='" + name + '\'' +", age=" + age +", gender='" + gender + '\'' +'}';}public static class UserBuilder {private Long id;private String name;private Integer age;private String gender;public static UserBuilder builder() {return new UserBuilder();}public UserBuilder id(Long id) {this.id = id;return this;}public UserBuilder name(String name) {this.name = name;return this;}public UserBuilder age(Integer age) {this.age = age;return this;}public UserBuilder gender(String gender) {this.gender = gender;return this;}public User build() {return new User(this.id, this.name, this.age, this.gender);}}
}
  • 通用匹配接口
public interface IUserSelector {List<User> query(IUserSpec spec);
}
  • 匹配接口实现
public class UserSelector implements IUserSelector {private final List<User> userList;public UserSelector(List<User> userList) {this.userList = userList;}@Overridepublic List<User> query(IUserSpec spec) {List<User> result = new ArrayList<>();userList.forEach(user -> {if (spec.match(user)) {result.add(user);}});return result;}
}
  • 规格接口
public interface IUserSpec {boolean match(User user);IUserSpec and(IUserSpec userSpec);IUserSpec or(IUserSpec userSpec);IUserSpec not();
}
  • 实现组合逻辑的抽象规格类
public abstract class CompositeSpec implements IUserSpec {@Overridepublic IUserSpec and(IUserSpec userSpec) {return new AndSpec(this, userSpec);}@Overridepublic IUserSpec or(IUserSpec userSpec) {return new OrSpec(this, userSpec);}@Overridepublic IUserSpec not() {return new NotSpec(this);}
}
  • 组合规格
public class AndSpec extends CompositeSpec {private final IUserSpec first;private final IUserSpec second;public AndSpec(IUserSpec first, IUserSpec second) {this.first = first;this.second = second;}@Overridepublic boolean match(User user) {return first.match(user) && second.match(user);}
}public class OrSpec extends CompositeSpec {private final IUserSpec first;private final IUserSpec second;public OrSpec(IUserSpec first, IUserSpec second) {this.first = first;this.second = second;}@Overridepublic boolean match(User user) {return first.match(user) || second.match(user);}
}public class NotSpec extends CompositeSpec {private final IUserSpec first;public NotSpec(IUserSpec first) {this.first = first;}@Overridepublic boolean match(User user) {return !first.match(user);}
}
  • 具体业务规格
public class GenderEqSpec extends CompositeSpec {private final String gender;public GenderEqSpec(String gender) {this.gender = gender;}@Overridepublic boolean match(User user) {return Objects.equals(user.getGender(), gender);}
}public class NameEqSpec extends CompositeSpec {private final String name;public NameEqSpec(String name) {this.name = name;}@Overridepublic boolean match(User user) {return Objects.equals(user.getName(), name);}
}

使用

public class Sample {public static void main(String[] args) {List<User> dataList = new ArrayList<>();dataList.add(User.UserBuilder.builder().id(1L).name("张三").age(10).gender("男").build());dataList.add(User.UserBuilder.builder().id(2L).name("李四").age(20).gender("女").build());dataList.add(User.UserBuilder.builder().id(3L).name("王五").age(30).gender("女").build());IUserSelector selector = new UserSelector(dataList);// 两个基本规格IUserSpec nameSpe = new NameEqSpec("张三");IUserSpec genderEqSpec = new GenderEqSpec("女");// 组合规格IUserSpec spec = nameSpe.and(genderEqSpec);List<User> result = selector.query(spec);System.out.println(result);}
}

相关文章:

设计模式简述(二十)规格模式

规格模式 描述组件 使用 描述 规格模式并不在传统的23设计模式中&#xff0c;属于后面扩展的设计模式。 简单描述就是对一批数据进行多条件&#xff08;包括逻辑组合、有点装饰器的感觉&#xff0c;可以不断套娃&#xff09;匹配。 组件 实体 package dp.spec;/*** TODO** …...

符合Python风格的对象(覆盖类属性)

覆盖类属性 Python 有个很独特的特性&#xff1a;类属性可用于为实例属性提供默认 值。Vector2d 中有个 typecode 类属性&#xff0c;bytes 方法两次用到了 它&#xff0c;而且都故意使用 self.typecode 读取它的值。因为 Vector2d 实 例本身没有 typecode 属性&#xff0c;所…...

题目 3314: 蓝桥杯2025年第十六届省赛真题-魔法科考试

题目 3314: 蓝桥杯2025年第十六届省赛真题-魔法科考试 时间限制: 3s 内存限制: 512MB 提交: 245 解决: 49 题目描述 小明正在参加魔法科的期末考试&#xff0c;考生需要根据给定的口诀组合出有效的 魔法。其中&#xff0c;老师给定了 n 个上半部分口诀 a1, a2, . . . , an 和 m…...

Java八股-Java优缺点,跨平台,jdk、jre、jvm关系,解释和编译

java优势劣势&#xff1f; 优势&#xff1a;面向对象&#xff0c;平台无关&#xff0c;垃圾回收&#xff0c;强大的生态系统 劣势&#xff1a;运行速度慢&#xff08;相比于c和rust这样的原生编译语言会比较慢&#xff09;&#xff0c;语法繁琐&#xff08;相比于python&…...

linux 内核态和用户态定时器函数使用总结

1&#xff0c;场景总结 定时器类型精度范围适用场景注意事项用户态信号定时器秒级简单任务调度、心跳检测信号处理函数中不可调用非异步安全函数timerfdepoll纳秒级高精度事件循环、多媒体处理需要配合IO多路复用机制使用内核timer_list毫秒级设备驱动、硬件交互基于jiffies时…...

支持selenium的chrome driver更新到136.0.7103.113

最近chrome释放新版本&#xff1a;136.0.7103.113 如果运行selenium自动化测试出现以下问题&#xff0c;是需要升级chromedriver才可以解决的。 selenium.common.exceptions.SessionNotCreatedException: Message: session not created: This version of ChromeDriver only s…...

硬件服务器基础

1、硬件服务器基础 2、服务器后面板 3、组件 3.1 CPU 3.2 内存 3.3 硬盘 3.4 风扇 4、服务器品牌 4.1 配置 4.2 CPU 架构 4.2.1 CPU 命名规则 4.2.2 服务器 CPU 和家用 CPU 的区别 4.2.3 CPU 在主板的位置 4.2.4 常见 CPU 安装方式 4.3 内存中组件 4.3.1 内存的分类 4.3.1.1 …...

LVS的DR模式部署

目录 一、引言&#xff1a;高并发场景下的流量调度方案 二、LVS-DR 集群核心原理与架构设计 &#xff08;一&#xff09;工作原理与数据流向 数据包流向步骤3&#xff1a; &#xff08;二&#xff09;模式特性与53网络要求 三、实战配置&#xff1a;从9环境搭建到参数调整…...

TRS收益互换平台开发实践:从需求分析到系统实现

一、TRS业务概述 TRS&#xff08;Total Return Swap&#xff09;收益互换是一种金融衍生工具&#xff0c;允许投资者通过支付固定或浮动利息&#xff0c;换取标的资产&#xff08;如股票、指数&#xff09;的收益权。典型应用场景包括&#xff1a; ​​跨境投资​​&#xff…...

测试Bug篇

本节概要&#xff1a; 软件测试的生命周期 bug的概念 buh要素 bug等级 bug生命周期 对于bug的定级与开发发生冲突如何解决 一、 软件测试的⽣命周期 软件测试贯穿于软件的整个生命周期&#xff0c;针对这句话我们⼀起来看⼀下软件测试是如何贯穿软件的整个生命周期。 软…...

【Linux系统移植】Cortex-A8 Linux系统移植(超详细)

目录 前言 一、ARM开发板ARM简介RISC和CISCARM产品分布核心板S5pv210 SOC嵌入式系统开发方式 二、嵌入式系统组成为什么要系统移植内核移植框图 三、嵌入式开发环境搭建搭建开发环境总流程设置ubuntu与windows共享目录修改用户为root用户安装NFS服务器安装tftp服务器安装交叉编…...

第十五届蓝桥杯大赛软件赛国赛Python 大学 C 组试做【本期题单: 设置密码、栈】

早上好啊大伙&#xff0c;这一期依旧是蓝桥杯备赛刷题的记录。 本期题单&#xff1a;设置密码、栈 前言 前段时间准备省赛&#xff0c;运气好进国赛了。所以就开始准备6月份的国赛。但是近期还有别的比赛要准备&#xff0c;所以刷题的速度比较慢&#xff0c;可能每一期就会有一…...

报错SvelteKitError: Not found: /.well-known/appspecific/com.chrome.devtools.json

报错信息 SvelteKitError: Not found: /.well-known/appspecific/com.chrome.devtools.json 解决方案一 更新所有依赖 npm update解决方案二&#xff08;不一定成功&#xff09; src\lib\hooks.server.ts&#xff0c;每次请求服务器时执行 import type { Handle } from &…...

word添加页眉

问题一&#xff1a; 为word文档添加页眉。 方法&#xff1a; 1、在要添加页眉的第一页页面顶端双击页眉区域&#xff0c;如果添加页眉页上面还有其他页或者与上一页添加页眉内容不同&#xff0c;记得取消“链接到前一节”&#xff08;点击使其上面没有灰色即可&#xff09;&…...

JavaScript 中的 BigInt:当普通数字不够“大“时的救星

前言 大家好&#xff01;今天我们要聊一聊 JavaScript 中那个"大"到不行的数据类型 —— BigInt。如果你曾经因为 JavaScript 的数字精度问题而抓狂&#xff0c;或者好奇为什么 9007199254740992 9007199254740993 会返回 true&#xff0c;那么这篇文章就是为你准备…...

通过mailto:实现web/html邮件模板唤起新建邮件并填写内容

一、背景 在实现网站、html邮件模板过程中&#xff0c;难免会遇到需要通过邮箱向服务提供方发起技术支持等需求&#xff0c;因此&#xff0c;我们需要通过一个功能&#xff0c;能新建邮件并提供模板&#xff0c;提高沟通效率 二、mailto协议配置说明 参数描述mailto:nameema…...

2025推客系统小程序开发:独立部署源码交付,高性价比裂变增长引擎

在私域流量争夺白热化的今天&#xff0c;源码独立部署的推客系统小程序已成为企业构建自主分销体系、降低获客成本的核心利器。基于成熟案例与技术沉淀&#xff0c;我们提供安全可控、高性价比的一站式解决方案&#xff0c;助力企业快速搭建专属推客生态&#xff0c;实现长效增…...

【Python零基础入门系列】第6篇:Python 的数据结构世界(列表、字典、集合、元组)

欢迎来到 Python 零基础入门系列的第六篇! 前面我们学会了写 Hello World、掌握了变量与数据类型、学会了控制程序流程,还能写写函数、读读文件。现在,我们要走进 Python 的数据结构世界,这也是写程序时最核心的一环之一。 你可以把“数据结构”理解成放数据的容器,或者是…...

MVCC 原理与并发控制实现

MVCC 原理与并发控制实现 1. MVCC 基本概念 MVCC(Multi-Version Concurrency Control&#xff0c;多版本并发控制)是现代数据库系统中实现并发控制的核心技术之一。与传统的锁机制不同&#xff0c;MVCC通过维护数据的多个版本来实现非阻塞读取。 关键结论&#xff1a;MVCC的核…...

CentOS 7.0重置root密码

文章目录 版本&#xff1a;CentOS 7.0内核版本&#xff1a;CentOS Linux, with Linux 3.10.0-123.el7.x86_64 服务器重启后&#xff0c;等待进入上述页面&#xff0c;按⬆⬇键&#xff0c;中断正常启动。在此页面按E&#xff0c;进入编辑模式 继续按⬇&#xff0c;找到linux16…...

YOLOV11改进策略【最新注意力机制】CVPR2025局部区域注意力机制LRSA-增强局部区域特征之间的交互

1.1网络结构 1.2 添加过程 1.2.1 核心代码 import torch import torch.nn as nn import torch.nn.functional as F from einops import rearrangedef patch_divide(x, step, ps):"""Crop image into patches.Args:x (Tensor): Input feature map of shape(b, …...

3D建模的全景图谱:从55个工具到元宇宙的数字革命

3D建模已从专业工程师的工具箱演变为全民创作的数字语言。从代码驱动的精确建模到AI自动生成纹理&#xff0c;从开源协作到程序化生成城市&#xff0c;技术正重塑我们创造虚拟世界的方式。本文将系统解析55个核心3D建模工具/插件&#xff0c;涵盖在线编辑器、开源软件、程序化生…...

Kotlin 活动事件通讯跳转深度讲解

在 Android 开发的浩瀚海洋中,活动(Activity)间的事件通讯与跳转犹如构建复杂应用程序的桥梁与纽带,而 Kotlin 语言的加入,更是为这一过程注入了简洁、优雅与高效的活力。本文将深入剖析 Kotlin 开发中安卓活动事件通讯跳转的方方面面,从基础概念到高级技巧,从代码示例到…...

vue + ant-design + xlsx 实现Excel多Sheet页导出功能

Vue Ant Design 扩展&#xff1a;实现Excel多Sheet页导出功能 引言 在复杂业务场景中&#xff0c;单一Sheet页已无法满足数据展示需求。本文将演示如何基于Vue3 Ant Design Vue xlsx技术栈&#xff0c;实现以下高级导出功能&#xff1a; 动态多Sheet页生成复杂数据集关联…...

关于 Web 安全:6. 常见 CMS 开源系统风险点

一、WordPress 开源内容管理系统&#xff08;CMS&#xff09;&#xff0c;使用 PHP MySQL 构建&#xff1b; 全球超过 40% 网站使用&#xff1b; 支持插件、主题系统&#xff0c;功能可扩展性极强&#xff1b; 也是风险点最多的系统之一&#xff0c;插件/主题贡献了大部分…...

DAY33 简单神经网络

你需要自行了解下MLP的概念。 你需要知道 梯度下降的思想激活函数的作用损失函数的作用优化器神经网络的概念 神经网络由于内部比较灵活&#xff0c;所以封装的比较浅&#xff0c;可以对模型做非常多的改进&#xff0c;而不像机器学习三行代码固定。 1. 神经网络的概念 (Th…...

OBOO鸥柏丨2025年鸿蒙生态+国产操作系统触摸屏查询一体机核心股

在信创产业蓬勃发展的当下&#xff0c;OBOO鸥柏积极响应纯国产化号召&#xff0c;推出基于华为鸿蒙HarmonyOS操作系统的触摸屏查询一体机及室内外场景广告液晶显示屏一体机上市&#xff0c;OBOO鸥柏品牌旗下显示产品均采用国产芯片&#xff0c;接入终端控制端需支持安卓Windows…...

【观成科技】Ymir勒索软件组织窃密木马RustyStealer加密通信分析

1.概述 Ymir勒索软件首次发现于2024年7月&#xff0c;采用ChaCha20加密算法对受害者文件进行加密&#xff0c;加密文件后缀为.6C5oy2dVr6。在攻击过程中&#xff0c;Ymir勒索组织利用名为RustyStealer的窃密木马获取受害企业的账号凭证&#xff0c;为后续横向移动和权限提升奠…...

Vuer开源程序 是一个轻量级的可视化工具包,用于与动态 3D 和机器人数据进行交互。它支持 VR 和 AR,可以在移动设备上运行。

​一、软件介绍 文末提供程序和源码下载 Vuer开源程序 是一个轻量级的可视化工具包&#xff0c;用于与动态 3D 和机器人数据进行交互。它支持 VR 和 AR&#xff0c;可以在移动设备上运行。 二、Our features include: 我们的功能包括&#xff1a; light-weight and performa…...

浅谈学习(费曼学习法)

我们在学习的过程中常常会面临遗忘的问题。 欸&#xff0c;之前明明学过&#xff0c;怎么感觉模模糊糊的&#xff0c;忘记了&#xff0c;当然。。。有可能是因为当时就没有听懂。 但是我经常会有一种情况&#xff0c;我觉得自己当时明明听懂了&#xff0c;理解了呀&#xff0…...