规格(Specification)即类/对象的属性,比如产品的颜色、尺寸和价格,如果业务规则的变化和组合很多,而且和规格相关,包括很多的条件判断,那么适合将这些业务规则放到专门的规格对象中,这就是规格模式(Specification Pattern)

规格模式有三种形式:

  • 用于验证,验证一个对象的状态是否符合要求。
  • 用于筛选过滤,从一个集合中筛选出符合指定要求的对象。(Java 8可以使用stream 很方便filter出符合条件的对象,不需要用规格模式)
  • 按需创建指定规格的产品。

案例:根据颜色、尺寸、价格等规格筛选出指定规格的产品。

下面的代码展示Builder, Factory, Intercepter, Composite 和 Specification模式。

//Builder设计模式
public class Product {private String name;private float price;private Color color;private ProductSize productSize;private Product(String name) {this.name = name;}public static Product withName(String name) {return new Product(name);}public Product withColor(Color color) {this.color = color;return this;}public Product withSize(ProductSize productSize) {this.productSize = productSize;return this;}public Product withPrice(float price) {this.price = price;return this;}public String getName() {return name;}public float getPrice() {return price;}public Color getColor() {return color;}public ProductSize getProductSize() {return productSize;}@Overridepublic String toString() {return "Product{" +"name='" + name + '\'' +", price=" + price +", color=" + color +", productSize=" + productSize +'}';}
}enum ProductSize {SMALL, MEDIUM, LARGE, NOT_APPLICATION
}
//Specifiction模式和Composite模式中定义的抽象接口
public interface ISpecification<T> {boolean isSatisfiedBy(T candidate);ISpecification and(ISpecification other); //FactoryISpecification andNot(ISpecification other); //FactoryISpecification or(ISpecification other); //FactoyISpecification orNot(ISpecification other); //FactoryISpecification not(); //Factory
}
public abstract class CompositeSpecification<T> implements ISpecification<T> {@Overridepublic abstract boolean isSatisfiedBy(T candidate);@Overridepublic ISpecification and(ISpecification other) {return new AndSpecification(this, other);}@Overridepublic ISpecification andNot(ISpecification other) {return new AndNotSpecification(this, other);}@Overridepublic ISpecification or(ISpecification other) {return new OrSpecification(this, other);}@Overridepublic ISpecification orNot(ISpecification other) {return new OrNotSpecification(this, other);}@Overridepublic ISpecification not() {return new NotSpecification(this);}
}
//颜色规格类,也是intercepter模式的终结表达式类
public class ColorSpecification extends CompositeSpecification<Product> {private Color color;public ColorSpecification(Color color) {if(color == null) throw new IllegalArgumentException("color is a must");this.color = color;}@Overridepublic boolean isSatisfiedBy(Product candidate) {return this.color.equals(candidate.getColor());}
}
//价格规格类,也是intercepter模式的终结表达式类
public class PriceSpecification extends CompositeSpecification<Product> {private float price;public PriceSpecification(float price) {if(price <= 0) throw new IllegalArgumentException("price must be greater than 0");this.price = price;}public boolean isSatisfiedBy(Product candidate) {return this.price == candidate.getPrice();}
}
//低于指定价格规格类,也是intercepter模式的终结表达式类
public class BelowPriceSpecification extends CompositeSpecification<Product> {private float priceThreshold;public BelowPriceSpecification(float priceThreshold) {if(priceThreshold <= 0) throw new IllegalArgumentException("price threshold must be greater than 0");this.priceThreshold = priceThreshold;}public boolean isSatisfiedBy(Product candidate) {return this.priceThreshold > candidate.getPrice();}
}
//尺寸规格类,也是intercepter模式的终结表达式类
public class SizeSpecification extends CompositeSpecification<Product> {private ProductSize size;public SizeSpecification(ProductSize size) {if(size == null) throw new IllegalArgumentException("size is a must");this.size = size;}@Overridepublic boolean isSatisfiedBy(Product candidate) {return this.size == candidate.getProductSize();}
}
//规格类和intercepter模式的“and”非终结表达式类
public class AndSpecification<T> extends CompositeSpecification<T> {private final ISpecification<T> left;private final ISpecification<T> right;public AndSpecification(ISpecification<T> left, ISpecification<T> right) {this.left = left;this.right = right;}@Overridepublic boolean isSatisfiedBy(T candidate) {return left.isSatisfiedBy(candidate) && right.isSatisfiedBy(candidate);}
}
//规格类和intercepter模式的“not and”非终结表达式类
public class AndNotSpecification<T> extends CompositeSpecification<T> {private final ISpecification<T> left;private final ISpecification<T> right;public AndNotSpecification(ISpecification<T> left, ISpecification<T> right) {this.left = left;this.right = right;}@Overridepublic boolean isSatisfiedBy(T candidate) {return left.isSatisfiedBy(candidate) && !right.isSatisfiedBy(candidate);}
}
//规格类和intercepter模式的“or”非终结表达式类
public class OrSpecification<T> extends CompositeSpecification<T> {private final ISpecification<T> left;private final ISpecification<T> right;public OrSpecification(ISpecification<T> left, ISpecification<T> right) {this.left = left;this.right = right;}@Overridepublic boolean isSatisfiedBy(T candidate) {return left.isSatisfiedBy(candidate) || right.isSatisfiedBy(candidate);}
}
//规格类和intercepter模式的“not or”非终结表达式类
public class OrNotSpecification<T> extends CompositeSpecification<T> {private final ISpecification<T> left;private final ISpecification<T> right;public OrNotSpecification(ISpecification<T> left, ISpecification<T> right) {this.left = left;this.right = right;}@Overridepublic boolean isSatisfiedBy(T candidate) {return left.isSatisfiedBy(candidate) || !right.isSatisfiedBy(candidate);}
}
//规格类和intercepter模式的“not”非终结表达式类
public class NotSpecification<T> extends CompositeSpecification<T> {private final ISpecification<T> spec;public NotSpecification(ISpecification<T> spec) {this.spec = spec;}@Overridepublic boolean isSatisfiedBy(T candidate) {return !spec.isSatisfiedBy(candidate);}
}
//测试类
public class ProductFindingService {private List<Product> inMemoryProducts = new ArrayList<>();{inMemoryProducts.add(Product.withName("A").withColor(Color.RED).withSize(ProductSize.MEDIUM).withPrice(10.00f));inMemoryProducts.add(Product.withName("B").withColor(Color.YELLOW).withSize(ProductSize.SMALL).withPrice(20.00f));inMemoryProducts.add(Product.withName("C").withColor(Color.PINK).withSize(ProductSize.LARGE).withPrice(9.99f));inMemoryProducts.add(Product.withName("D").withColor(Color.WHITE).withSize(ProductSize.SMALL).withPrice(10.00f));inMemoryProducts.add(Product.withName("E").withColor(Color.RED).withSize(ProductSize.NOT_APPLICATION).withPrice(200.00f));}/*** Using lambert expression to select products** @param predicate* @return*/public List<Product> selectBy(Predicate<Product> predicate) {return inMemoryProducts.stream().filter(predicate).collect(Collectors.toList());}/*** Using specification pattern to select products** @param specification* @return*/public List<Product> selectBy(ISpecification<Product> specification) {return inMemoryProducts.stream().filter(specification::isSatisfiedBy).collect(Collectors.toList());}public static void main(String[] args) {ProductFindingService productFindingService = new ProductFindingService();//method 1: using lambda expression to select the products with Color=Red and Price < 20.00productFindingService.selectBy(e -> e.getColor().equals(Color.RED) && e.getPrice() < 20.00f).forEach(System.out::println);//method 2 using specification pattern to select the products with Color=Red and Price < 20.00productFindingService.selectBy(new ColorSpecification(Color.RED).and(new BelowPriceSpecification(20.00f))).forEach(System.out::println);}
}

返回 设计模式

规格模式(Specification)相关推荐

  1. 规格模式 Specification Pattern

    Specification Pattern 不了解 SOLID 的可以扫一眼这个:SOLID,面向对象设计五大基本原则. 今天扫 SOLID JS 的时候,授课者对 OCP 的一个实现方式利用了 Sp ...

  2. php 规格,PHP 设计模式系列之 specification规格模式_PHP

    Plus.php left = $left; $this->right = $right; } /** * 返回两种规格的逻辑与评估 * * @param Item $item * * @ret ...

  3. 【设计模式】【27】规格模式

    应用场景 规格模式,英文名Specification Pattern 该模式将对产品特征的判断标准封装成规格类,专门用来判断产品是否合格 这种设计模式主要用于结果判断类的业务,比如我们做单元测试时,有 ...

  4. 分享我对领域驱动设计(DDD)的学习成果

    本文内容提要: 1. 领域驱动设计之领域模型 2. 为什么建立一个领域模型是重要的 3. 领域通用语言(Ubiquitous Language) 4. 将领域模型转换为代码实现的最佳实践 5. 领域建 ...

  5. 领域驱动/DDD模型初识

    原文:http://www.jdon.com/45378 转自: 领域模型的行为设计 在领域模型的行为设计中我们提到 2013-04-22 15:37 "@banq"的内容 我们把 ...

  6. 领域驱动设计战术模式:实体

    领域驱动设计战术部分,是一组面向业务的设计模式,是基于技术的一种思维方式,相对开发人员来说更接地气,是提升个人格局比较好的切入点. 该文章为战术模式的第三篇,重心讲解实体模式. 实体是具有唯一标识的概 ...

  7. 《.NET应用架构设计:原则、模式与实践》新书博客--试读-持续更新

    新书目录: 前言 第一部分 架构与设计的原则和模式    第1章 架构与设计的流程和核心概念/2               1.1 正确认识软件架构/2                      1 ...

  8. 设计模式(十四)中介者模式

    相关文章 设计模式(一)设计六大原则 设计模式(二)单例模式的七种写法 设计模式(三)建造者模式 设计模式(四)简单工厂模式 设计模式(五)观察者模式 设计模式(六)代理模式 设计模式(七)装饰模式 ...

  9. 电商后台开发之商品规格组合算法

    前言  最近接了私活,关于器械商城的项目,最后收尾阶段,发现发布商品还是存在着问题,对于多个相同/不同的商品规格输出成商品时,需要依据规格名对规格值进行排列组合,保证所有规格值都可以进行选择. 核心代 ...

  10. 一文理解 DDD 领域驱动设计!

    来源丨SpringForAll社区 2004年Eric Evans 发表Domain-Driven Design –Tackling Complexity in the Heart of Softwa ...

最新文章

  1. Python实现阿里云aliyun服务器里的文件上传与下载
  2. jvm性能调优实战 - 29使用 jstat 摸清线上系统的JVM运行状况
  3. 分布式、高并发、多线程,到底有什么区别?
  4. 浙大python判断两个字符串是否为变位词_python数据结构与算法 变位词
  5. Spring Cloud原理详解
  6. web通讯录之搜索功能
  7. arm-linux-gcc 没有那个文件或目录
  8. excel内容少却文件很大_009- EXCEL文件的表格内的数据内容明明不多,但是文件却变得很大...
  9. idea中 mybatis 的 mapper.xml 新建没有 头文件
  10. 12 个轻量级的 JavaScript 库
  11. conda - 创建虚拟环境并配置tensorflow-gpu
  12. 编译安装mysql-5.5.33
  13. Spring AOP 之 Introductions
  14. 手机通讯录式排序php,Android获取手机通讯录-根据排序方式进行
  15. 【CZY选讲·Triangle】
  16. 指定JDK运行Jar包
  17. Wow64(32位进程)注入DLL到64位进程
  18. 时空大数据与众包计算学习总结
  19. libjpeg-turbo使用教程
  20. 全志平台ubuntu14.04+安卓7.1+openjdk-8编译

热门文章

  1. 外置MOS LED驱动IC7195
  2. 入侵检测技术框架总论
  3. 外汇EA是什么?EA可靠吗?EA有什么缺点?
  4. webview 边距_如何使用javascript删除Android webview中的内置边距
  5. 交易偏见--《别做正常的傻瓜》摘记2
  6. MediaSession框架全解析
  7. python实现匿名发邮件_python 发送匿名邮件或无发件人
  8. OC中__kindof的用法
  9. 搭建外网能访问的web服务器
  10. 给Date加上23时59分59秒