设计原则之依赖倒置原则

依赖倒置原则

定义
1.高层模块不应该依赖低层模块,两者都应该依赖于抽象
2.抽象不应该依赖于细节
3.细节应该依赖于抽象

解释:
1.什么是低层模块?
就是原子逻辑组成低层模块。
2.什么是高层模块?
就是原子逻辑的再组装,就变成了高层模块。
3.什么是抽象?
抽象就是接口或者抽象类。
4.什么是细节?
细节就是实现类。

那上面三句话的意思就是:
高层模块不依赖低层模块,容易理解,模块之间的依赖应该通过接口或者抽象类,而不应该通过实现类
抽象不应该依赖细节,就是说接口或者抽象类不应该依赖于实现类
细节应该依赖抽象的意思就是说,实现类应该依赖于抽象的接口或者抽象类。

如果不依赖抽象,依赖实现,我们看看会是什么结果?

public class Benz{
	public void run(){
		System.out.println("奔驰车在路上跑");
	}
}

public class Driver{
	//这里依赖的是具体实现
	public void drive(Benz benz){
		benz.run();
	}
}

public class Client{
	public static void main(String args[]){
		Benz benz = new Benz();
		Driver driver = new Driver();
		driver.drive();
	}
}

这里可以看到,奔驰车在跑,当需要扩展添加宝马车时,我们完全可以添加一台宝马车.

public class Bmw{
	public void run(){
		System.out.println("宝马车在路上跑");
	}
}

但是drive方法依赖的是具体实现,怎么让司机驾驶宝马车呢?这样就比较麻烦,所以说依赖于具体实现不利于扩展。

再来看看,如果是依赖抽象呢?

public interface ICar {
    /**
     * 汽车就应该能在路上跑
     */
    public void run();
}

public interface IDriver {
    /**
     * 司机就应该会驾驶汽车
     */
    public void drive(ICar car);
}

再添加实现类。

public class Benz implements ICar {
    @Override
    public void run(){
        System.out.println("奔驰车在路上跑");
    }
}

public class Bmw implements ICar{
    @Override
    public void run() {
        System.out.println("宝马车在路上跑");
    }
}

public class Driver implements IDriver{
    @Override
    public void drive(ICar car) {
        car.run();
    }
}
public class Client {
    public static void main(String[] args) {
        IDriver iDriver = new Driver();
        ICar car = new Bmw();
        iDriver.drive(car);
    }
}

由上面的代码可以看到,在drive方法里传递的是抽象,而不是实现,那么当需要宝马车的时候,只需要修改高层模块,以及扩展所需要的宝马车,其他实现根本不需要改变。这样就可以减少耦合性,提高扩展性了。

依赖的传递

常见的又三种方式传递依赖,上面的代码中已经有了接口传递依赖的例子:

//接口传递依赖,应该依赖抽象
public void drive(ICar icar);

还有两种方式传递依赖:

1.构造函数传递依赖

public class UserServiceImpl implements UserService{
	private UserDao userDao;	
	public UserServiceImpl(UserDao userDao){
		this.userDao = userDao;
	}
}

这就是构造函数传递依赖。

setter方法传递依赖

public class UserController{
	private UserService userService;
	//setter方法传递依赖
	public void setUserService(UserService userService){
		this.userService = userService;
	}
}

总结:
依赖倒置原则是最难以实现的原则,但是它又是实现开闭原则的重要途径。在开发的时候,遵守原则固然是一件好事,但是也要根据实际情况决定。

依赖倒置原则的基本要求:

1.每个类都应该尽量有接口或者抽象类,甚至接口或抽象类都具备
2.变量的表面类型应该是接口或抽象类,而不是实现类
3.任何类都不应该由具体类派生。也就暗含了第一条,最好是有接口或抽象类,但是实际中可能难以做到,实在做不到,应该保证尽量少继承实现类。
4.尽量不要重写基类的方法:如果基类是一个抽象类,并且这个方法已经实现了,子类尽量不要去重写这个基类的抽象方法。
5.结合里氏替换原则使用:
①接口负责定义public属性和方法,并声明与其他对象的依赖关系
②抽象类负责公共构造部分的实现
③实现类准确的实现业务逻辑

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值