设计模式六大原则(三)----依赖倒置原则

简介: 设计模式六大原则(三)----依赖倒置原则

一. 什么是依赖倒置原则



1.1 概念


依赖倒置原则(Dependence Inversion Principle, DIP), 其含义:

  1. 高层模块不应该依赖低层模块,两者都应该依赖其抽象
  2. 抽象不应该依赖细节, 细节应该依赖于抽象
  3. 要针对接口编程,不要针对实现编程


1.2 什么是依赖呢?


这里的依赖关系我们理解为UML关系中的依赖。简单的说就是A use B,那么A对B产生了依赖。具体请看下面的例子。


从上图中我们可以发现, 类A中的方法a()里面用到了类B, 其实这就是依赖关系, A依赖了B. 需要注意的是: 并不是说A中声明了B就叫依赖, 如果引用了但是没有真实调用方法, 那么叫做零耦合关系. 如下图:


1.3 依赖的关系种类


1. 零耦合关系:如果两个类之间没有耦合关系,称之为零耦合


2. 直接耦合关系: 具体耦合发生在两个具体类(可实例化的)之间,经由一个类对另一个类的直接引用造成。


3. 抽象耦合关系: 抽象耦合关系发生在一个具体类和一个抽象类(或者java接口)之间,使两个必须发生关系的类之间存在最大的灵活性。


依赖倒转原则就是要针对接口编程,不要针对实现编程。这就是说,应当使用接口或者抽象类进行变量的类型声明参数的类型声明方法的返回类型说明以及数据类型的转换等。

二. 依赖倒置的案例



2.1 初步设计方案


public class Benz {
    public void run() {
        System.out.println("奔驰跑起来了!");
    }
}
public class Driver {
    private String name;
    public Driver(String name) {
        this.name = name;
    }
    public void driver(Benz benz) {
        benz.run();
    }
}
public class CarTest {
    public static void main(String[] args) {
        Benz benz = new Benz();
        Driver driver = new Driver("张三");
        driver.driver(benz);
    }
}

有一个驾驶员张三可以驾驶奔驰汽车, 于是最开始我们思考, 会有一个驾驶员类, 有一个奔驰汽车类. 随着业务的发展, 我们发现, 驾驶员张三还可以驾驶宝马.


于是,我们定义一个BM类,


public class BM {
    public void run() {
        System.out.println("宝马跑起来了!");
    }
}

这时, 张三如果想要开宝马, 就要将宝马注册在他名下.


public class Driver {
    private String name;
    public Driver(String name) {
        this.name = name;
    }
    public void driver(Benz benz) {
        benz.run();
    }
    public void driver(BM bm) {
        bm.run();
    }
}
public class CarTest {
    public static void main(String[] args) {
        Benz benz = new Benz();
        BM bm = new BM();
        Driver driver = new Driver("张三");
        driver.driver(benz);
        driver.driver(bm);
    }
}

似乎这样就可以了, 但是这样有什么问题呢?


  1. 如果张三有一天要开大众, 还要增加一个大众车类, 同时还得挂载司机名下.
  2. 不是所有的人都要开奔驰, 开宝马. 开大众.

这就是面向实现编程的问题, 接下来我们就要考虑面向接口编程.


2.2 改进后的方案

public interface ICar {
    public void run();
}
public class Benz implements ICar{
    public void run() {
        System.out.println("奔驰跑起来了!");
    }
}
public class BM implements ICar{
    public void run() {
        System.out.println("宝马跑起来了!");
    }
}
public interface IDriver {
    public void driver(ICar car);
}
public class Driver implements IDriver{
    @Override
    public void driver(ICar car) {
        car.run();
    }
}
public class CarTest {
    public static void main(String[] args) {
        IDriver driver = new Driver();
        driver.driver(new Benz());
        driver.driver(new BM());
    }
}

修改后的代码, 提炼出来一个IDriver接口和ICar接口, 面向接口编程. IDriver的实现类驾驶员可以driver任何类型的汽车, 所以传入参数也是一个接口ICar. 任何类型的汽车, 都可以通过实现ICar接口注册为一种新的汽车类型. 当客户端调用的时候, 将对应的汽车传入就可以了.

三. 依赖的方式


3.1 依赖注入主要有三种方式:

1 构造注入,在构造的时候注入依赖
  1. Setter方法注入
  2. 接口方法中注入(汽车的例子使用的就是此方法)


3.2 依赖倒置原则在设计模式中的体现


  1. 简单工厂设计模式, 使用的是接口方法中注入
  2. 策略设计模式: 在构造函数中注入.
    具体的用法, 可以查看以下两篇文章:
    a. 简单工厂设计模式:
    b. 策略设计模式:


相关文章
|
3月前
|
设计模式
设计模式七大原则
这篇文章介绍了设计模式中的七大原则,特别强调了单一职责原则,即一个类应该只有一个引起其行为变化的原因,以确保类功能的高内聚和低耦合。
|
3月前
|
设计模式 存储 前端开发
React开发设计模式及原则概念问题之自定义Hooks的作用是什么,自定义Hooks设计时要遵循什么原则呢
React开发设计模式及原则概念问题之自定义Hooks的作用是什么,自定义Hooks设计时要遵循什么原则呢
|
2月前
|
设计模式 Java 关系型数据库
设计模式——设计模式简介和七大原则
设计模式的目的和核心原则、单一职责原则、接口隔离原则、依赖倒转原则、里氏替换原则、开闭原则、迪米特法则、合成复用原则
设计模式——设计模式简介和七大原则
|
3月前
|
设计模式 算法 开发者
设计模式问题之最小知识原则(迪米特法则)对代码设计有何影响,如何解决
设计模式问题之最小知识原则(迪米特法则)对代码设计有何影响,如何解决
|
3月前
|
设计模式 前端开发 JavaScript
React开发设计模式及原则概念问题之什么是HOC(Higher-order component),HOC遵循的设计原则都有哪些
React开发设计模式及原则概念问题之什么是HOC(Higher-order component),HOC遵循的设计原则都有哪些
|
3月前
|
设计模式 前端开发 JavaScript
React开发设计模式及原则概念问题之什么是设计模式,单一职责原则如何理解
React开发设计模式及原则概念问题之什么是设计模式,单一职责原则如何理解
|
5月前
|
设计模式 uml
设计模式学习心得之前置知识 UML图看法与六大原则(下)
设计模式学习心得之前置知识 UML图看法与六大原则(下)
37 2
|
5月前
|
设计模式 Java 数据库
深入理解设计模式六大原则
深入理解设计模式六大原则
|
7天前
|
设计模式 安全 Java
Kotlin教程笔记(51) - 改良设计模式 - 构建者模式
Kotlin教程笔记(51) - 改良设计模式 - 构建者模式
|
2月前
|
设计模式 数据库连接 PHP
PHP中的设计模式:提升代码的可维护性与扩展性在软件开发过程中,设计模式是开发者们经常用到的工具之一。它们提供了经过验证的解决方案,可以帮助我们解决常见的软件设计问题。本文将介绍PHP中常用的设计模式,以及如何利用这些模式来提高代码的可维护性和扩展性。我们将从基础的设计模式入手,逐步深入到更复杂的应用场景。通过实际案例分析,读者可以更好地理解如何在PHP开发中应用这些设计模式,从而写出更加高效、灵活和易于维护的代码。
本文探讨了PHP中常用的设计模式及其在实际项目中的应用。内容涵盖设计模式的基本概念、分类和具体使用场景,重点介绍了单例模式、工厂模式和观察者模式等常见模式。通过具体的代码示例,展示了如何在PHP项目中有效利用设计模式来提升代码的可维护性和扩展性。文章还讨论了设计模式的选择原则和注意事项,帮助开发者在不同情境下做出最佳决策。