内容提要
• 结合代码介绍了设计模式背后包含的多种实用的设计原则
• 同时给出“基于项目介绍设计原则”的方式
• 给出了若干亮点说辞,同时介绍了如何在面试时引出该话题
依赖倒转原则能减少修改所影响范围
• 模块间(类之间)的依赖关系(比如相互调用)是通过接口和抽象类 发生,实现类之间不发生(或尽量少发生)依赖关系;
• 接口或抽象类不依赖于实现类,相反实现类应该依赖接口或抽象类 ;
• 如下不好的范例中,订单管理类依赖于数据库管理类,两者并不是接 口或抽象类;
依赖倒转原则能减少修改所影响范围
• 定义Connection接口,让JDBCDBConnection实现这个接口
• 让订单管理类依赖于接口
• 接口的方法没方法体,所以稳定。假设之后要用Hadoop来管理订单 ,由于调用和实现分离,就可以把修改范围限定在数据库相关模块
单一职责原则能让类更稳定
• 每个类(或模块)应该只具体单一的职责,即在其中只实现一种功能 ,否则就需要拆分类或者模块
• 如下的添加订单方法里,混杂了实现多种功能的代码,职责不单一
• 变更其中任何一种功能,都会影响该方法,从而增加测试负担
单一职责原则能让类更稳定
• 可以通过拆分,尽可能让一个方法(或模块)干可能少种类的活 • 上例中,可以把数据库相关代码拆分到DAO层里
• 更可以通过AOP方式,再把写日志的逻辑拆分出去
继承时需要遵循的里氏替换原则
• 子类可以实现父类的抽象方法,但不能覆盖父类的非抽象方法
• 如果子类要扩展功能,可以增加自己特有的方法
• 违背里氏替换原则的后果,同一方法再三层里有不同的实现,不仅维 护困难,且增加了多态调用时的复杂度
继承时需要遵循的里氏替换原则
• 如果子类要扩展功能,可以增加自己特有的方法 • SuperManage子类里,不覆盖login方法,同时添加发邮件的方法, 可以通过Spring的AOP思路,把login和sendMail方法关联到一起
通过合成复用原则优化继承的使用场景
• 有个数据库管理类DBManager,其中封装了连接和操作数据库的方法
• 开发一个订单管理模块,其中需要用到连接数据库的方法。不好的做 法是,让订单管理模块继承(extends)数据库管理类DBManager
通过合成复用原则优化继承的使用场景
• 合成复用原则的核心思想是,优先使用组合和聚合,只有当父子类之 间存在逻辑上的从属关系时,才考虑使用继承
• 聚合表示整体和部分的弱关系,组合则表示强关联关系
• 滥用继承,订单类里会误用数据库类里不该暴露的方法,且由于耦合 性过强,数据库代码的修改会影响到订单模块
出彩的说辞
• 设计模式种类是有限的,但项目里遇到的实际问题种类是无限的,所 以我在开发时,会进一步用到设计模式背后包含的设计原则 • 在项目的xx模块里,用到了观察者模式,具体在观察者类里,不在其 中放其它种类的务代码,这符合单一职责模式,事实上,后期虽然有 需求变更,但这块代码基本没动过,同时结合案例代码和框图说明
• 在项目里,我们定义类之间的关系时,会遵循“合成复用原则“,只 在具有从属关系的类之间才使用继承,否则会使用聚合或组合,这样 类之间的耦合度就比较低,如果改其中的一个类,就不会影响到其它 的,再结合案例和框图说明
引出设计原则话题的方式
• 在介绍项目时,提一句:在详细设计阶段,我们会根据合成复用原则 定义父子类之间的关系,或使用xx原则,达到xx效果,然后展开
• 在介绍项目里提一句,对于这个项目,我们专门讨论了编码规范,其 中包含xx等设计原则,然后展开
• 被问到设计模式相关问题时,回答完之后再带一句,并且,我们还会 应用包含在设计模式背后的设计原则,然后展开
• 就准备一个业务功能点,介绍项目时说,在实现其中的xx功能时,我 们用到了观察者模式,(或其它模式),介绍完以后再说,同时,我 们用到了其中xx设计原则,再展开
总结以引出该话题的方式
1. 结合项目代码,讲述了若干设计原则
2. 给出了若干高大上的说辞
3. 给出了在面试时引出关于设计原则话题的方式