依赖倒置原则的定义
依赖倒置原则的原始定义为:高层模板不应该依赖底层模板,两者都应该依赖其抽象;抽象不应该依赖细节,细节应该依赖抽象。
其核心思想是:要面向接口编程,不要面向实现编程。
依赖倒置原则是实现开闭原则的重要途径之一,它降低了客户与实现模块之间的耦合。
由于在软件设计汇总,细节具有多变性,而抽象层则相对稳定,因此以抽象为基础搭建起来的架构要比以细节为基础搭建起来的架构要稳定得多。这里的抽象指的是接口或者抽象类,而细节是指具体的实现类。
使用接口或者抽象类的目的是指定好规范和契约,而不去涉及任何具体的操作,把展现细节的任务交给它们的实现类去完成。
依赖倒置原则的作用
依赖倒置原则的主要作用如下:
- 依赖倒置原则可以降低类间的耦合性
- 依赖倒置原则可以提高系统的稳定性
- 依赖倒置原则可以减少并行并发引起的风险
- 依赖倒置原则可以提高代码的可读性和可维护性
依赖倒置原则的实现方法
依赖倒置原则的目的是通过要面向接口的变 来降低类间的耦合性,所以我们再实际编程中只要遵循如下4点,就能在项目中满足这个规则。
- 每个类尽量提供接口或抽象类,或者两者都具备。
- 变量的声明类型尽量是接口或者是抽象类
- 任何类都不应该从具体类派生
- 使用继承时尽量遵循里氏替换原则
如下以“顾客购物程序”为例来说明依赖倒置原则的应用
【例1】依赖倒置原则在“顾客购物程序”中的应用
分析:本程序反映了“顾客类”和“商店类”的关系。商店类中有sell()方法,顾客类通过该方法购物如下代码定义了顾客类通过A网店Shop购物:
class Customer
{
public void shopping(ShaoguanShop shop)
{
//购物
System.out.println(shop.sell());
}
}
但是,这种设计存在缺点,如果这个顾客可想从另外一家商店(如B网店)购物,就要将该顾客的代码唏嘘该如下:
class Customer
{
public void shopping(WuyuanShop shop)
{
//购物
System.out.println(shop.sell());
}
}
顾客每更换一家网店,就要修改一次代码,这明显违背了开闭原则。存在以上缺点的原因是:顾客类设计时同具体的商品类绑定类绑定了,这违背了依赖倒置原则。解决方案是:定义:B网店和A网店的共同接口shop,顾客类面型该接口编程,其代码修改如下:
class Customer
{
public void shopping(Shop shop)
{
//购物
System.out.println(shop.sell());
}
}
这样,不管顾客类Customer访问什么网店,或者增加新的网店,都不需要修改原来代码,其类图如图1所示。
程序代码如下:
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());
}
}
程序运行结果如下:
顾客购买以下商品:
韶关土特产:香菇、木耳……
婺源土特产:绿茶、酒糟鱼……