5、依赖倒置原则
定义
依赖倒置原则(dependence inversion principle): 高层模块不应该依赖低层模块,两者都应该依赖其抽象;抽象不应该依赖细节,细节应该依赖抽象是程序要依赖于抽象接口,不要依赖于具体实现。简单的说就是要求对抽象进行编程,不要对实现进行编程,这样就降低了客户与实现模块间的耦合。
规则
- 每个类尽量提供接口或抽象类,或者两者都具备。
- 变量的声明类型尽量是接口或者是抽象类。
- 任何类都不应该从具体类派生。
- 使用继承时尽量遵循里氏替换原则。
示例
错误示例:
class Customer { public void shopping(ShaoguanShop shop) { //购物 System.out.println(shop.sell()); } } class Customer { public void shopping(WuyuanShop shop) { //购物 System.out.println(shop.sell()); } }
添加功能的时候没有办法复用代码,顾客每更换一家商店,都要修改一次代码,这明显违背了开闭原则。存在以上缺点的原因是:顾客类设计时同具体的商店类绑定了,这违背了依赖倒置原则。解决方法是:定义“婺源网店”和“韶关网店”的共同接口 Shop,顾客类面向该接口编程,其代码修改如下:
class Customer { public void shopping(Shop shop) { //购物 System.out.println(shop.sell()); } } package principle; public class DIPtest { public static void main(String[] args) { Customer wang = new Customer(); System.out.println("顾客购买以下商品:"); wang.shopping(new ShaoguanShop()); wang.shopping(new WuyuanShop()); } } //商店 interface Shop { public String sell(); //卖 } //韶关网店 class ShaoguanShop implements Shop { public String sell() { return "韶关土特产:香菇、木耳……"; } } //婺源网店 class WuyuanShop implements Shop { public String sell() { return "婺源土特产:绿茶、酒糟鱼……"; } } //顾客 class Customer { public void shopping(Shop shop) { //购物 System.out.println(shop.sell()); } }
6、合成复用原则
定义
合成复用原则(Composite Reuse Principle,CRP)又叫组合/聚合复用原则(Composition/Aggregate Reuse Principle,CARP)。它要求在软件复用时,要尽量先使用组合或者聚合等关联关系来实现,其次才考虑使用继承关系来实现。
继承关系实现:
组合关系实现
7、迪米特法则
定义
迪米特法则(Law of Demeter,LOD)又叫作最少知识原则(The Least Knowledge Principle),一个类对于其他类知道的越少越好,就是说一个对象应当对其他对象有尽可能少的了解,只和朋友通信,不和陌生人说话 。
实现法则
- 在类的划分上,应该创建弱耦合的类。类与类之间的耦合越弱,就越有利于实现可复用的目标。
- 在类的结构设计上,尽量降低类成员的访问权限。
- 在类的设计上,优先考虑将一个类设置成不变类。
- 在对其他类的引用上,将引用其他对象的次数降到最低。
- 不暴露类的属性成员,而应该提供相应的访问器(set 和 get 方法)。
- 谨慎使用序列化(Serializable)功能。
示例
package principle; public class LoDtest { public static void main(String[] args) { Agent agent = new Agent(); agent.setStar(new Star("林心如")); agent.setFans(new Fans("粉丝我")); agent.setCompany(new Company("中国传媒有限公司")); agent.meeting(); agent.business(); } } //经纪人 class Agent { private Star myStar; private Fans myFans; private Company myCompany; public void setStar(Star myStar) { this.myStar = myStar; } public void setFans(Fans myFans) { this.myFans = myFans; } public void setCompany(Company myCompany) { this.myCompany = myCompany; } public void meeting() { System.out.println(myFans.getName() + "与明星" + myStar.getName() + "见面了。"); } public void business() { System.out.println(myCompany.getName() + "与明星" + myStar.getName() + "洽淡业务。"); } } //明星 class Star { private String name; Star(String name) { this.name = name; } public String getName() { return name; } } //粉丝 class Fans { private String name; Fans(String name) { this.name = name; } public String getName() { return name; } } //媒体公司 class Company { private String name; Company(String name) { this.name = name; } public String getName() { return name; } }