- 贯穿设计模式:用一个电商项目详解设计模式
- 伟山育琪
- 833字
- 2024-12-28 11:44:57
1.4 合成复用原则
合成复用原则,又称为组合/聚合复用原则(Composition/Aggregate Reuse Principle,CARP)。该原则要求在代码复用时,要尽量先使用组合或者聚合等关联关系(也就是包含、使用属性成员的方式)来实现,其次才考虑使用继承关系来实现。
合成复用原则,在部分资料中将其称之为设计模式的第七个原则,所以部分资料中会有“设计模式七大原则”的字眼。对于设计模式原则而言,六大原则也好,七大原则也罢,两种说法并无对错之分。随着设计模式的应用越来越多,将来可能还会有其他原则的出现。正因为如此,由于各种资料对设计模式原则介绍的不统一性,所以笔者没有将该原则纳入章节重点。虽然没有纳入章节重点,但笔者依然会在此小节对合成复用原则进行详细的说明。
为了更加清晰地说明合成复用原则,笔者提出了一个常见的小问题:“我们在SpringMVC或SpringBoot项目的接口开发过程中,Controller层如何调用Service层的方法呢?”
相信大部分读者都能够迅速地给出答案,使用@Autowired注解,将Service注入到Controller就可以了,正确的代码示例如下:
从以上代码示例中可以看出,我们通过@Autowired注解将UserService注入到了UserController,我们可以随时对UserService中的方法进行调用,这就是合成复用原则之中提到的“要尽量先使用组合或者聚合等关联关系(也就是包含,使用属性成员的方式)来实现”。依赖注入,就是合成复用原则最具代表性、最经典的案例体现。
大家试想一下,如果我们采用继承的方式进行UserService方法调用,就会出现如下“毁三观”的代码。
虽然依然能够达成我们调用UserService中方法的目的,但是这样的代码书写方式无疑增大了UserController和UserService的耦合性,而且违背了我们长久以来的开发方式。部分读者可能会有疑问:“难道合成复用原则下,所有的代码都不使用继承了吗?各种源码中,很多代码的类继承、接口实现都是有问题的吗?”解答这些疑问,首先要理解类继承和接口实现的核心思想,两个能够成为父子关系的类或接口必然有相似的特性,或者有扩展的需要,如子类LinkedHashMap与父类HashMap,再如DefaultListableBeanFactory子类与BeanFactory接口的关系,都是同宗同族,且子类都进行了扩展操作。然而以上代码示例中,仅仅为了调用UserService的方法而进行的继承,则是一种错误的方式。