我的博客原文:
依赖倒置原则java
设计模式六大原则之三:依赖倒置原则。git
姓名 :依赖倒置原则github
英文名 :Dependence Inversion Principle编程
价值观 :大男子主义的典型表明,什么都得经过老大或者老爸赞成设计模式
伴侣 :必定是个温柔体贴的女子ide
我的介绍 :工具
给你们讲个故事,我胡乱想的,若有雷同,确定是英雄所见略同。那必须交个朋友。测试
一个小村里,有两家饭馆,虽然挂着不一样的牌子,挨在一块儿,可是老板确是表兄弟。这两兄弟抠得很,为了节省成本,密谋了一个想法:在两家饭馆谁家忙的时候,可让不忙的那家的员工过去支援一下。这样子,原本每家饭馆都须要 2 个洗碗工,总共须要 4 个,他们就只招了 3 个,省了 1 个洗碗工的成本,固然不止洗碗工,还有服务员等等。两兄弟约定了规则:this
大概经过这个小故事,描述了依赖倒置原则的基本内容。设计
下面经过代码来模拟这个故事。
这个错误的示范将就看哈,可能有些问题没描述清楚。
abstract class Boss { abstract void support(); abstract void askHelp(Boss boss); } abstract class Staff { private String name; abstract void service(); abstract void askHelp(Boss boss); public String getName() { return name; } public void setName(String name) { this.name = name; } }
class BossA extends Boss { private StaffA staffA; public BossA(StaffA staffA) { this.staffA = staffA; } @Override void support() { staffA.service(); } @Override void askHelp(Boss boss) { boss.support(); } } class BossB extends Boss { private StaffB staffB; public BossB(StaffB staffB) { this.staffB = staffB; } @Override void support() { staffB.service(); } @Override void askHelp(Boss boss) { boss.support(); } }
class StaffA extends Staff { public StaffA(String name) { this.setName(name); } @Override void service() { System.out.println(this.getName() + "提供服务"); } @Override void askHelp(Boss boss) { boss.support(); } } class StaffB extends Staff { public StaffB(String name) { this.setName(name); } @Override void service() { System.out.println(this.getName() + "提供服务"); } @Override void askHelp(Boss boss) { boss.support(); } }
/** 初始化老板和员工 */ StaffA staffA = new StaffA("A 员工"); StaffB staffB = new StaffB(" B 员工"); Boss bossA = new BossA(staffA); Boss bossB = new BossB(staffB); /** A 老板向 B 老板求支援 */ bossA.askHelp(bossB); // 打印出:B 员工提供服务 /** B 员工向 A 老板求支援 */ staffB.askHelp(bossA); // 打印出:A 员工提供服务
好像看起来实现了要求了,可是其实这段代码没有按照上面的 3 点规则编写,破坏了第 3 点规则,老板们的员工没有用员工的抽象类,破坏了细节依赖抽象这一点。设想一下,假如如今 A 老板把 A 员工辞退了,从新招了个 C 员工,那么怎么实现呢?是否是须要再新增一个 StaffC 类,而后再修改 BossA 类代码,把 StaffA 换成 StaffC。这样超级麻烦,在平时写项目中要时刻考虑这一点:在具体实现类使用其余类,是否是能够用其抽象类?
代码:
看了上面那个憋屈的代码,再来看下面简洁的代码,才会发现依赖倒置原则是多么强大。
abstract class Boss2 { private Staff2 staff; public Boss2(Staff2 staff) { this.staff = staff; } abstract void support(); abstract void askHelp(Boss2 boss); public void setStaff(Staff2 staff) { this.staff = staff; } public Staff2 getStaff() { return staff; } } abstract class Staff2 { private String name; abstract void service(); abstract void askHelp(Boss2 boss); public void setName(String name) { this.name = name; } public String getName() { return name; } }
class BossImpl extends Boss2 { public BossImpl(Staff2 staff) { super(staff); } @Override void support() { this.getStaff().service(); } @Override void askHelp(Boss2 boss) { boss.support(); } }
class StaffImpl extends Staff2{ public StaffImpl(String name) { this.setName(name); } @Override void service() { System.out.println(this.getName() + "提供服务"); } @Override void askHelp(Boss2 boss) { boss.support(); } }
/** 正确示范 */ Staff2 staffA2 = new StaffImpl("A 员工"); Staff2 staffB2 = new StaffImpl("B 员工"); Boss2 bossA2 = new BossImpl(staffA2); Boss2 bossB2 = new BossImpl(staffB2); /** A 老板向 B 老板求支援 */ bossA2.askHelp(bossB2); // 打印出:B 员工提供服务 /** B 员工向 A 老板求支援 */ staffB2.askHelp(bossA2); // 打印出:A 员工提供服务 /** A 老板辞退了 A 员工,换成了 C 员工 */ Staff2 staffC2 = new StaffImpl("C 员工"); bossA2.setStaff(staffC2); /** B 员工向 A 老板求支援 */ staffB2.askHelp(bossA2); // 打印出:C 员工提供服务
这代码相比上面错误的示范,简洁了不少,实现的功能却更灵活,这就是依赖倒置原则强大的地方,它能够将类的耦合性下降,提供灵活的处理。
代码:
总的来讲,要实现依赖倒置原则,要有『面向接口编程』这个思惟,掌握好这个思惟后,就能够很好的运用依赖倒置原则。
参考资料:《大话设计模式》、《Java设计模式》、《设计模式之禅》、《研磨设计模式》、《Head First 设计模式》
但愿文章对您有所帮助,设计模式系列会持续更新,感兴趣的同窗能够关注公众号,第一时间获取文章推送阅读,也能够一块儿交流,交个朋友。