写点什么

第二周 - 作业

用户头像
JI
关注
发布于: 2020 年 06 月 18 日

描述什么是依赖倒置原则,为什么有时候依赖倒置原则又被称为好莱坞原则?

传统的方式: 高层次依赖了低层次,由低层次定义好,让高层次进行调用,但是存在的问题就是, 如果我高层次依赖了低层次,当低层次发生变更的时候,会直接影响高层次的调用,此时就需要进行相应的修改。

 

依赖倒置(也叫依赖反转)

通俗的定义: 高层次的模块不应依赖于低层次的模块, (反转)从而使得低层次模块依赖于高层次模块的需求抽象, 也就是说, 低层次需要依赖高层的定义的抽象接口,由高层次定义抽象,推动低层去根据定义的抽象,进行实现细节,不管低层怎么改, 抽象接口依然是那个,低层细节依然是没有改变了依赖抽象接口的关系,对高层没有产生实际上的影响。

 

好莱坞原则 : 遵循的就是IOC原则,不要调用我,让我来调用你 耦合的坏处:如果改变程序的一个模块要求另一个模块同时发生变化,就认为两个模块发生了耦合,所以,高层和底层通过抽象接口分离之后,就能解除耦合

 

举个代码栗子🌰:

(J 使用了 苹果笔记本电脑 做作业)…两个月后又换了(J 使用了 华为笔记本电脑 做作业)

  1. 高层调用底层的方式(未使用依赖倒置)

class J: 调用了computer的方法,使用了一个记笔记的方法

public class J {
public Computer computer = new Computer();
public void makeNotes() {
computer.makeNotes();
}
}
public class Computer {
public void makeNotes() {
...
}
}

当Computer类需要修改了记笔记的方法名,那么就会导致 class J 这个类需要更改,这样导致高层调用底层,两边都变化,会耦合在一起

 

  1. 高层调用底层的方式(使用依赖倒置)

通过把高层的需求抽象成一个接口

 

// 抽象高层需求
//IUseComputer.java
public interface IUseComputer {
public abstract void makeNotes();
}
// 底层实现
// Computer.java
public abstract class Computer implements IUseComputer{
public abstract void makeNotes();
}
//HuaweiComputer.java
public class HuaweiComputer extends Computer{
public void makeNotes() {
System.out.print("HuaweiComputer makeNotes");
}
}
//AppleComputer.java
public class AppleComputer extends Computer{
public void makeNotes() {
System.out.print("AppleComputer makeNotes");
}
}
// 高层实现
//J.java:
public class J {
public void makeNotes (Computer computer) {
computer.makeNotes();
}
}
// 入口
public class Main {
public static void main(String[] args) {
J j = new J();
j.makeNotes(new AppleComputer());
j.makeNotes(new AppleComputer());
}
}

通过定义入口,分别调用不通的class。通过多态方式进行调用,然后低层根据高层接口的抽象接口,实现方法, 实现解耦,到时候底层不管怎么修改,底层依旧根据抽象接口实现逻辑,不管怎么修改,都不会导致原来引用的方法报错。

 

请描述一个你熟悉的框架,是如何实现依赖倒置原则的。

SpringBoot, 延续了spring框架的核心思想IOC。

当web容器启动的时候,spring的全局bean的管理器会去xml配置文件中扫描的包下面获取到所有的类,并根据你使用的注解,进行对应的封装,封装到全局的bean容器中进行管理,一旦容器初始化完毕,beanID以及bean实例化的类对象信息就全部存在了,现在我们需要在某个service里面调用另一个bean的某个方法的时候,我们只需要依赖注入进来另一个bean的Id即可,调用的时候,spring会去初始化完成的bean容器中获取即可,如果存在就把依赖的bean的类的实例化对象返回给你,你就可以调用依赖的bean的相关方法或属性等;

 

请用接口隔离原则优化 Cache 类的设计,画出优化后的类图。





使用了抽象工厂方法,分别隔离两个不同的类,实现单一职责 

public interface IApplication {
void put();
void get();
void delete();
}
public interface IRemoteApplication {
void rebuild();
}
public class Application implements IApplication {
public void put() {};
public void get() {};
public void delete() {};
}
public class RemoteApplication implements IRemoteApplication {
public void rebuild() {}
}
interface ICacheFactory
{
public Application getApplication();
public RemoteApplication getRemoteApplication();
}
public class Cache implements ICacheFactory {
public Application getApplication() {
return new Application();
}
public RemoteApplication getRemoteApplication() {
return new RemoteApplication()
}
}
public class MainEntry {
public static void main(String[] args) {
Cache cache = new Cache();
IApplication app = cache.getApplication();
IRemoteApplication remoteapp = cache.getRemoteApplication();
app.get();
remoteapp.rebuild();
}
}



用户头像

JI

关注

还未添加个人签名 2019.07.19 加入

还未添加个人简介

评论 (1 条评论)

发布
用户头像
很棒!不过有个疑问,第一题的例子代码中,main方法如果是高层模块的,应该是看不到底层的实现类AppleComputer的。
2020 年 06 月 20 日 16:45
回复
没有更多了
第二周-作业