设计模式七大原则之依赖倒转原则

设计模式七大原则之依赖倒转原则

什么是依赖倒转原则

  1. 高层模块不应该依赖底层模块,二者都应该依赖其抽象。
  2. 抽象不应该依赖细节,细节应该依赖抽象。

说这样的官话确实比较难以理解,那么来说点人话:

  • 依赖倒转原则主要是要体现出**“面向接口编程”**的中心思想。
  • 细节是多变的,抽象是相对稳定的,以抽象为基础搭建的结构会比以细节为基础的架构稳定很多。抽象指接口、抽象类,细节为具体的实现类。
  • 在实现功能时,要多用接口或抽象类去制定一个规范,比如传参时更多地使用接口或抽象类来规定变量,而非某一个具体的实现类,这样在扩展功能时,不需要修改现有代码,仅需要使新增的类实现该接口,即可完成功能扩展。
  • 低层的模块尽量要有抽象类或接口,当然也可以两者都有,可以提高程序的稳定性。
  • 变量的声明类型尽量是抽象类或接口,这样可以使得变量引用和实际对象之间有一个缓冲,便于程序扩展和优化。

所谓倒转:

  • 接口和抽象类是抽象的,他们依赖一个实现类去表现出其功能,但这样的依赖是对细节的依赖,在软件上是很不稳定的。
  • 倒转即是让具体的依赖抽象的,增强稳定性与可扩展性,同时与具体实现类解耦。

注意点:

举个栗子

书籍是人类进步的阶梯,现在需要实现一个Person类,其包括一个read方法,用于表示人读书的行为。

最简单的实现方式:

public class DependecyInversion {
    public static void main(String[] args) {
        Person person = new Person();
        person.read(new Book());
    }
}

class Book {
    public String getContent() {
        return "书里面写着:知为行之始,行为知之成。";
    }
}

class Person {
    public void read(Book book) {
        System.out.println(book.getContent());
    }
}

这样我们实现的Person的read功能。

但是时代在进步,电子书出现了,人们可以阅读纸质书,用kindle阅读,甚至用手机阅读。现在很明显,上面的代码是不可用的,因为它过度依赖Book类这一细节。

public class DependecyInversion {
    public static void main(String[] args) {
        Person person = new Person();
        person.read(new Book());
        person.read(new Ebook());
    }
}

interface BookInterface {
    String getContent();
}

class Book implements BookInterface {
    @Override
    public String getContent() {
        return "书里面写着:知为行之始,行为知之成。";
    }
}

class Ebook implements BookInterface {
    @Override
    public String getContent() {
        return "电子书里写着:知为行之始,行为知之成。";
    }
}

class Person {
    public void read(BookInterface book) {
        System.out.println(book.getContent());
    }
}

现在,Person中的read方法仅需要获取一个可以被阅读的“书”即可以进行阅读(仅依赖一个接口),无论是纸质书还是电子书,均可以加以扩展,不必对Person类进行其他修改(如方法重载等)。


依赖传递的三种方法:

  1. 接口传递

上面的例子中,就是使用了接口传递的方法传递依赖:

class Person {
    public void read(BookInterface book) { //方法参数中用接口规定一个变量
        System.out.println(book.getContent());
    }
}

public class DependecyInversion {
    public static void main(String[] args) {
        Person person = new Person();
        person.read(new Book()); //调用时传入具体的书籍
        person.read(new Ebook());
    }
}
  1. 构造方法传递
class Person {
    BookInterface book;//将具体书籍作为一个属性存在

    public Person(BookInterface book) {//构造方法
        this.book = book;
    }

    public void read(){
        System.out.println(book.getContent());
    }
}

public class DependecyInversion {
    public static void main(String[] args) {
        Person person = new Person(new Book());//给定其书籍属性
        person.read();//让该对象开始阅读即可
    }
}
  1. setter方式传递
class Person {
    BookInterface book;

    public void read(){
        System.out.println(book.getContent());
    }

    public void setBook(BookInterface book) {
        this.book = book;
    }
}

public class DependecyInversion {
    public static void main(String[] args) {
        Person person = new Person();
        person.setBook(new Book());//要在调用read方法前通过set方法给定一个能被阅读的书,否则很明显会出现NullPointerException
        person.read();
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值