架构师训练营第 0 期第二周作业

用户头像
无名氏
关注
发布于: 2020 年 06 月 16 日
架构师训练营第0期第二周作业



作业一:

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



依赖反转原则的英文翻译是 Dependency Inversion Principle,缩写为 DIP。中文翻译有时候也叫依赖倒置原则。



高层模块(high-level modules)不要依赖低层模块(low-level)。高层模块和低层模块应该通过抽象(abstractions)来互相依赖。除此之外,抽象(abstractions)不要依赖具体实现细节(details),具体实现细节(details)依赖抽象(abstractions)。所谓高层模块和低层模块的划分,简单来说就是,在调用链上,调用者属于高层,被调用者属于低层。在平时的业务代码开发中,高层模块依赖底层模块是没有任何问题的。实际上,这条原则主要还是用来指导框架层面的设计。



依赖倒置原则也被称为好莱坞原则:Don’t call me,I will call you. 即不要来调用我,我会调用你。Tomcat、Spring 都是基于这一原则设计出来的,应用程序不需要调用 Tomcat 或者 Spring 这样的框架,而是框架调用应用程序。而实现这一特性的前提就是应用程序必须实现框架的接口规范,比如实现 Servlet 接口。



引用:极客时间王争老师专栏《设计模式之美》,章节“19 | 理论五:控制反转、依赖反转、依赖注入,这三者有何区别和联系?”

引用:极客时间李智慧老师专栏《后端技术面试38讲》,章节“12 | 软件设计的依赖倒置原则:如何不依赖代码却可以复用它的功能?”

作业二:

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



在实际的软件开发中,一些项目可能会涉及几十、上百、甚至几百个类,类对象的创建和依赖注入会变得非常复杂。如果这部分工作都是靠程序员自己写代码来完成,容易出错且开发成本也比较高。而对象创建和依赖注入的工作,本身跟具体的业务无关,我们完全可以抽象成框架来自动完成。这个框架就是“依赖注入框架”。我们只需要通过依赖注入框架提供的扩展点,简单配置一下所有需要创建的类对象、类与类之间的依赖关系,就可以实现由框架来自动创建对象、管理对象的生命周期、依赖注入等原本需要程序员来做的事情。实际上,现成的依赖注入框架有很多,比如 Google Guice、Java Spring、Pico Container、Butterfly Container 等。Spring 框架的控制反转主要是通过依赖注入来实现的。



引用:极客时间王争老师专栏《设计模式之美》,章节“19 | 理论五:控制反转、依赖反转、依赖注入,这三者有何区别和联系?”

作业三:

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



  • 作业三提示:cache 实现类中有四个方法,其中 put get delete 方法是需要暴露给应用程序的,rebuild 方法是需要暴露给系统进行远程调用的。如果将 rebuild 暴露给应用程序,应用程序可能会错误调用 rebuild 方法,导致 cache 服务失效。按照接口隔离原则:不应该强迫客户程序依赖它们不需要的方法。也就是说,应该使 cache 类实现两个接口,一个接口包含 get put delete 暴露给应用程序,一个接口包含 rebuild 暴露给系统远程调用。从而实现接口隔离,使应用程序看不到 rebuild 方法。



Go语言代码设计

  • DefaultCache:实现Get/Put/Delete,暴露给应用程序。

  • AdvancedCache:实现Rebuild,暴露给系统远程调用(类图1),如果需要Get/Put/Delete,组合(继承)DefaultCache即可(类图2)。

type Object interface{}
type Config struct {
// ...
}
// 缓存接口
type Cacher interface {
Get(key Object) Object
Put(key Object, val Object)
Delete(key Object)
}
// 更新接口
type Rebuilder interface {
Rebuild(conf Config)
}
// 普通缓存,实现缓存接口
type DefaultCache struct {
// ...
}
func (c *DefaultCache) Get(key Object) Object {
var value Object
// ...
return value
}
func (c *DefaultCache) Put(key Object, val Object) {
// ...
}
func (c *DefaultCache) Delete(key Object) {
// ...
}
// 高级缓存,实现更新接口
type AdvancedCache struct {
// ...
}
func (c *AdvancedCache) Rebuild(conf Config) {
// ...
}





类图2



用户头像

无名氏

关注

还未添加个人签名 2017.09.11 加入

还未添加个人简介

评论

发布
暂无评论
架构师训练营第0期第二周作业