嵌套对象创建的最佳实践:结合迪米特法则的实现问询
嵌套对象创建的最佳实践(结合迪米特法则)
针对你提出的两种嵌套对象创建方案,第二种由根对象Criteria创建所有嵌套对象、客户端仅传原始数据的方案,更符合迪米特法则(最少知识原则)和开发最佳实践,具体分析如下:
方案1的问题
客户端直接创建Criteria、Filter、Operator所有对象,意味着客户端必须了解这三个类的全部构造细节——比如得知道Filter需要接收Operator实例,还得清楚Operator的参数格式。这种方式完全违反了迪米特法则:客户端没必要关心Criteria内部嵌套类的依赖关系,一旦后续Operator的构造逻辑变化(比如新增校验规则、调整参数),所有写了new Operator(...)的客户端代码都得跟着改,耦合度太高,维护成本陡增。
方案2的优势
- 客户端只需要和
Criteria交互,完全不用知道Filter、Operator的存在,完美契合迪米特法则的“最少知识”要求。 - 所有嵌套对象的创建逻辑都封装在
Criteria内部(或者后续可以拆分到专门的工厂类),后续如果Filter或Operator的结构变更,只需要修改Criteria内部的创建逻辑,客户端代码完全不用动,耦合度低,维护性拉满。 - 客户端传递的原始数据结构简单直观,使用成本更低,不用操心各种类的实例化细节。
额外优化建议
如果Criteria的创建逻辑比较复杂(比如需要支持多组过滤条件、添加校验规则),可以用构建器模式进一步封装,让客户端代码更易读、更灵活:
class CriteriaBuilder { private filters: Array<{field: string, operator: '='|'!=', value: string}> = []; addFilter(field: string, operator: '='|'!=', value: string): this { // 这里还可以加参数校验逻辑 if (!field || !value) throw new Error("字段和值不能为空"); this.filters.push({field, operator, value}); return this; } build(): Criteria { return new Criteria(this.filters.map(data => new Filter(data.field, new Operator(data.operator), data.value) )); } } // 客户端使用示例 const criteria = new CriteriaBuilder() .addFilter('field1', '=', 'value1') .addFilter('field2', '!=', 'value2') .build();
这种方式既保持了客户端的低耦合,又让代码的可读性和扩展性更强。
内容的提问来源于stack exchange,提问作者Jose Luis
相关产品推荐
相关产品推荐

