【软考架构】案例分析-比较两种架构风格:面向对象风格和解释器风格。
来源2022年11月第1题
某电子商务公司拟升级其会员与促销管理系统,向用户提供个性化服务,提高用户的粘性。在项目立项之初,公司领导层一致认为本次升级的主要目标是提升会员管理方式的灵活性,由于当前用户规模不大,业务也相对简单,系统性能方面不做过多考虑。新系统除了保持现有的四级固定会员制度外,还需要根据用户的消费金额、偏好、重复性等相关特征动态调整商品的折扣力度,并支持在特定的活动周期内主动筛选与活动主题高度相关的用户集合,提供个性化的打折促销活动。
问题2
针对该系统的功能,李工建议采用面向对象的架构风格,将折扣力度计算和用户筛选分别封装为独立对象,通过对象调用实现对应的功能;王工则建议采用解释器(interpreters)架构风格,将折扣力度计算和用户筛选条件封装为独立的规则,通过解释规则实现对应的功能。请针对系统的主要功能,从折扣规则的可修改性、个性化折扣定义灵活性和系统性能三个方面对这两种架构风格进行比较与分析,并指出该系统更适合采用哪种架构风格。
参考答案
应该选择解释器架构风格。
**折扣规则的可修改性:**解释器更强。规则以外部化的DSL/规则表/表达式存储,运行时解析,无需改动业务类与编译部署,可快速上线与灰度;面向对象通常需要修改类层级或策略集合并重新发布,修改面相代码、耦合更深。
**个性化折扣定义灵活性:**解释器更强。可组合条件、权重、时效、冲突优先级等形成千人千面的规则集;面向对象虽可用策略/装饰/责任链等模式组合,但变体爆炸与组合复杂度上升,长期维护成本高。
系统性能:面向对象通常优于解释器。解释器涉及解析/解释执行/动态绑定带来额外开销;面向对象的静态分派与固定流程更轻量。
核心需求分析
首先,我们需要明确系统的核心升级目标:
- 主要目标:提升会员管理方式的灵活性。
- 核心功能:
- 动态折扣:根据用户消费金额、偏好、重复性等特征动态调整折扣。
- 主动营销:在特定活动周期内,根据活动主题筛选用户集合,并提供个性化打折。
性能方面,由于当前用户规模不大且业务简单,不作为优先考虑项。这意味着我们可以为了灵活性和可修改性,在一定程度上牺牲性能。
两种架构风格比较与分析
| 比较维度 | 李工 - 面向对象架构风格 | 王工 - 解释器架构风格 |
|---|---|---|
| 1. 折扣规则的可修改性 | 中等 | 高 |
| 2. 个性化折扣定义灵活性 | 中等 | 高 |
| 3. 系统性能 | 高 | 较低 |
详细分析
1. 折扣规则的可修改性
-
面向对象风格:
- 修改方式:规则逻辑被硬编码在对象的方法中。例如,可能有一个
VIPDiscountStrategy类和一个NewUserDiscountStrategy类。 - 优点:编译期检查,类型安全,不易出现语法错误。
- 缺点:修改规则需要修改代码、重新编译和部署系统。每次业务人员想调整一下“消费金额”的阈值,都需要开发工程师介入。这对于追求“灵活性”的主要目标而言,成本很高,响应速度慢。
- 修改方式:规则逻辑被硬编码在对象的方法中。例如,可能有一个
-
解释器风格:
- 修改方式:规则被抽象为一种领域特定语言 的表达式或配置。例如,一条规则可以是
(用户.消费金额 > 1000) AND (用户.偏好分类 IN ('电子产品', '家居')) -> 折扣率 = 0.85。 - 优点:规则与执行引擎分离。业务人员或运营人员可以通过修改配置文件或使用规则配置界面来动态地创建、修改和组合规则,而无需重启系统。这极大地提升了规则的可修改性和对市场的响应速度。
- 缺点:需要设计一套规则DSL,并处理可能存在的规则语法错误和逻辑冲突。
- 修改方式:规则被抽象为一种领域特定语言 的表达式或配置。例如,一条规则可以是
分析结论:在可修改性上,解释器风格明显胜出,因为它支持规则的动态更新和热配置,完美契合“提升灵活性”的主要目标。
2. 个性化折扣定义灵活性
-
面向对象风格:
- 实现方式:通过创建不同的策略类来实现个性化。例如,为“七夕情侣活动”创建一个
ValentinesDayStrategy类。 - 优点:可以实现非常复杂的内部逻辑。
- 缺点:个性化的组合能力有限。每增加一种新的用户特征组合,理论上就可能需要创建一个新的类。当规则变得复杂(例如,消费金额、最近购买时间、商品偏好、用户地域等多个条件的组合)时,会产生大量的类,导致“类爆炸”,系统难以维护。定义新的个性化规则同样需要开发工作。
- 实现方式:通过创建不同的策略类来实现个性化。例如,为“七夕情侣活动”创建一个
-
解释器风格:
- 实现方式:通过将条件(用户筛选)和动作(折扣计算)都定义为规则,可以灵活地组合。
- 优点:具备极高的灵活性。业务人员可以像搭积木一样,通过AND、OR、NOT等逻辑运算符,将任意用户属性和条件组合起来,定义出高度个性化的用户集合和折扣力度。例如,“筛选出最近30天内浏览过健身器材但未购买,且总消费金额在500-2000元之间的女性用户”这样复杂的查询,可以轻松地通过一条规则表达式定义。
- 缺点:规则引擎的复杂性较高。
分析结论:在个性化定义灵活性上,解释器风格再次胜出。它天生就是为了处理这种多条件、可自由组合的规则场景而设计的,能够轻松应对“动态调整”和“主动筛选”的需求。
3. 系统性能
-
面向对象风格:
- 性能:高。规则被编译为本地机器码执行,直接调用对象的方法,没有额外的解析开销。执行效率高。
-
解释器风格:
- 性能:较低。执行一条规则需要经过解析、语法分析、解释执行等步骤,这会产生额外的运行时开销。尤其是在规则非常复杂或用户数据量巨大时,性能劣势会更明显。
分析结论:在性能上,面向对象风格完胜。但是,题目中明确提到“当前用户规模不大,业务也相对简单,系统性能方面不做过多考虑”。因此,性能因素在本项目的决策中权重很低。
最终决策与总结
该系统更适合采用王工建议的【解释器架构风格】。
理由如下:
- 完美契合核心目标:公司的主要目标是“提升会员管理方式的灵活性”。解释器风格通过将规则外部化、可配置化,使得业务规则可以快速响应市场变化,而无需经过冗长的开发-测试-部署流程,这是面向对象风格无法比拟的。
- 支撑核心功能:
- 对于动态折扣:可以轻松定义基于多种特征的复合规则。
- 对于主动筛选用户:解释器风格本质上就是一个强大的规则引擎,其核心能力就是根据一组条件从集合中筛选出符合条件的对象(用户)。这几乎是为其量身定做的功能。
- 做出合理的权衡:在“灵活性”与“性能”的权衡中,项目背景已经给出了明确的方向——优先保障灵活性。解释器风格虽然牺牲了一些性能,但换来了业务上极大的敏捷性,这是一个非常值得的权衡。
补充建议:
为了缓解解释器风格可能带来的性能问题,可以考虑:
- 对解析后的规则进行缓存,避免重复解析。
- 对用户数据建立高效的索引,加速规则条件的判断。
- 在规则复杂度增加、用户规模增长后,可以考虑将解释器升级为性能更优的规则引擎(如Drools等),它们通常会将规则编译成更高效的执行格式。
综上所述,从实现项目核心价值的角度出发,解释器架构风格是该会员与促销管理系统升级的更优选择。
