规格模式 Specification Pattern
创始人
2024-02-11 01:57:34
0

Specification Pattern

不了解 SOLID 的可以扫一眼这个:SOLID,面向对象设计五大基本原则。

今天扫 SOLID JS 的时候,授课者对 OCP 的一个实现方式利用了 Specification Pattern,所以这里也进行一下补充学习。

不过讲道理来说,因为 JavaScript 是一个弱类型的语言,所以很难强制让子类去实现其他语言中 interface/abstract 的函数,这也是一个局限了。

使用案例为,假设需要实现一个过滤器(filter),最初的实现方式如下:

const COLOR = Object.freeze({RED: 'red',GREEN: 'green',BLUE: 'blue',
});const SIZE = Object.freeze({SMALL: 'small',MEDIUM: 'medium',LARGE: 'large',
});class Product {constructor(name, color, size) {this.name = name;this.color = color;this.size = size;}
}class ProductFilter {filterByColor(products, color) {return products.filter((p) => p.color === color);}filterBySize(products, size) {return products.filter((p) => p.size === size);}
}const apple = new Product('Apple', COLOR.GREEN, SIZE.SMALL);
const tree = new Product('Tree', COLOR.GREEN, SIZE.LARGE);
const house = new Product('House', COLOR.BLUE, SIZE.LARGE);const products = [apple, tree, house];const pf = new ProductFilter();console.log('Green products:');
for (const p of pf.filterByColor(products, COLOR.GREEN)) {console.log(` * ${p.name} is green.`);
}

可以看到之后如果要写其他的 filter,也是可以继续在 ProductFilter 实现的,不过这里有几个问题:

  1. 继续实现其他的 filter 就要修改现有的代码
  2. 每一次新的需求来了,都需要额外实现新需求,这会引起 state space explosion 的问题,毕竟 3 个变量的 AND 操作,就需要 7 个方法去进行实现(A, B, C, A+B, B+C, A+C, A+B+C)。

一个解决这个问题的方法是使用 specification pattern,修改代码如下:

// should be done through inheritance, but js doesn't reenforce inheritance
// class Specification {}class ColorSpecification {constructor(color) {this.color = color;}isSatisfied(item) {return item.color === this.color;}
}class SizeSpecification {constructor(size) {this.size = size;}isSatisfied(item) {return item.size === this.size;}
}class FilterSpecs {filter(items, spec) {return items.filter((x) => spec.isSatisfied(x));}
}const fs = new FilterSpecs();console.log('Green products with specs:');
for (const p of fs.filter(products, new ColorSpecification(COLOR.GREEN))) {console.log(` * ${p.name} is green.`);
}

对于 AND 操作的实现补充如下:

class AndSpecifications {constructor(...specs) {this.specs = specs;}isSatisfied(item) {return this.specs.every((x) => x.isSatisfied(item));}
}console.log('Large and green products:');
const specs = new AndSpecifications(new ColorSpecification(COLOR.GREEN),new SizeSpecification(SIZE.LARGE)
);for (const p of fs.filter(products, specs)) {console.log(` * ${p.name} is green and large.`);
}

使用 specification pattern 的优势就在于极大地减少了函数的实现,原本对于 AND 的操作,3 个条件就需要实现 7 个方法,而后如果有更多的需求,就需要些更多的方法去满足这些需求,对于 nnn 个需求来说,就会有 n+n−1,+...+1n + n-1, + ... + 1n+n−1,+...+1,也就是 n2n^2n2 个方法。。使用了 specification pattern 现在只需要实现 3+1 个,并且如果之后有其他的需求了,在实现对应的基类后,只需要调用 AndSpecifications 并将对应的 specs 传进去就行,换言之,只需要实现 n+1n+1n+1 个方法。

同样的,如果对 OR,XOR 操作也有需求,那么 specification pattern 就能省下大量的代码和开发时间。

Reference

  • Specification pattern

    wiki 上提供了不少的代码案例,包括 C#,Python,C++和 TS。

相关内容

热门资讯

隔阴伤寒有哪些症状 隔阴伤寒有哪些症状1.阴盛隔阳简称隔阳。指体内阴寒过胜,阳气被拒于外,出现内真寒而外假热的症候。临床...
妖精的尾巴中的纳兹喜欢艾露撒么... 妖精的尾巴中的纳兹喜欢艾露撒么?不喜欢,纳兹喜欢露西或者丽萨娜。杰拉尔喜欢艾露莎。之前是喜欢,但后来...
‘背诵为王“的发音是美式的还是... ‘背诵为王“的发音是美式的还是英式的美音的,现在真正的英音教学教材很少了
尚可是什么意思啊 尚可是什么意思啊尚可是什么意思啊尚可就是还行,还可以!!尚可的意思如下:1、合格的,能通过检查的。2...
王祖贤演的电影 王祖贤演的电影王祖贤演的古装片,谁有啊,越多越好倩女幽魂和青蛇《倩女幽魂》1.2.3,有三个版本哦
二四季双播什么意思 二四季双播什么意思什么跟什么啊
大海是由无数的小河汇聚尔成的,... 大海是由无数的小河汇聚尔成的,这句话对吗?对 ‘而’打错了这句话不能判断对错,这不是数学问题,而是一...
额要些 非主流 伤感 德短篇日... 额要些 非主流 伤感 德短篇日志沵已罘在昰沵亲爱惪,谢谢沵,疼爱沃,沵已罘在昰沵,沃已罘值惪记,沵说...
帮我找几本言情小说 帮我找几本言情小说古代的:比如 养成美娇娘 娃娃福姬.现代的:象 OK主人阁下 泡沫之夏现代的:我把...
我闻不到栀子花的花香 对其他常... 我闻不到栀子花的花香 对其他常见的花香都没问题。是嗅觉有缺陷吗?我闻不到栀子花的花香 对其他常见的花...
《笑傲江湖》中,武当冲虚道长的... 《笑傲江湖》中,武当冲虚道长的太极剑法究竟能排第几?我觉得吧,肯定实在风清扬老前辈之下的,毕竟风清扬...
如何让自己可以4点钟起床,11... 如何让自己可以4点钟起床,11点半睡觉?很难起来,我在手机上放了闹钟四点钟,可是太困了太难起来了,有...
一个人做淘宝必死无疑 一个人做淘宝必死无疑一个人做淘宝必死无疑一个人可以做的,一个月挣6000-20000没问题.要是说做...
2012年有什么新韩剧么 2012年有什么新韩剧么拥抱太阳的月亮 (这个最好山轮看)dreamhigh2 神的晚餐 闭逗没信嘴...
小人之心,怎么预防? 小人之心,怎么预防???害人之心不可有防人之心不可无说的就是这意思对别人坦诚布公但是也不要太轻易的相...
小学生关于致敬英雄的手抄报 关... 小学生关于致敬英雄的手抄报 关于英雄的手抄报小学生致敬英雄烈士手抄报图片其它 致敬英雄 写美篇这是我...
征春联下联:回眸05峥嵘岁月坎... 征春联下联:回眸05峥嵘岁月坎坷路步步艰辛步步高请对仗工整展望06精英时代通天道一路顺风一路发你那联...
您好,我的南天PR2 不出针,... 您好,我的南天PR2 不出针,其他正常,您知道是什么故障码检查一下针保险需要有一定维修能力。或者联系...
大学学生会创新活动策划书 大学学生会创新活动策划书  现在3月中旬! 活动从策划到实施需要一个过程,你就本月策划下月的活动吧...
万圣节前夜的南瓜灯,你会想到《... 万圣节前夜的南瓜灯,你会想到《西游记》哪个情节?万圣节前夜的南瓜灯,会想到《西游记》金平府观灯的情节...