写点什么

第二周 - 框架设计 - 学习总结

用户头像
刘希文
关注
发布于: 2020 年 09 月 23 日

课程思维导图

重点回顾

面向对象

什么是面向对象语言?

面向对象语言是支持类和对象的语法,并且有自己的语法规则,可以方便实现封装、继承、多态、抽象四个面向对象特性的语言。


什么是面向对象编程?

面向对象编程是一种编程范式,以类和对象作为基础的单元,并遵从面向对象的四大特性封装、继承、多态、抽象的编程方式。


面向对象有哪些特性?

抽象、封装、继承、多态。


设计模式

常用的设计模式总共有 23 种,分为三大类:创建型、结构型、行为型

创建型包括:单例模式、工厂模式、建造者模式、原型模式。

结构型包括:代理模式、桥接模式、装饰器模式、适配器模式、门面模式、组合模式、享元模式。

行为型包括:观察者模式、模版模式、策略模式、职责链模式、状态模式、迭代器模式、访问者模式、备忘录模式、命令模式、解释器模式、中介模式。

常用的设计模式分析

单例模式

什么是单例模式?

单例模式是指某个类只能在系统中有一个实例存在。

单例模式解决什么问题?

如果某个类需要频繁创建并销毁,或者该类加载资源比较多并且固定就可以使用单例模式。

单例模式有哪些例子?

  1. Spring 创建的 Bean 有些是默认单例模式的,比如 Controller。可以通过参数改变创建的 Bean 是单例还是多例。

  2. 加载项目配置文件的类可以设置为单例。

工厂模式

什么是工厂模式?

将创建对象的行为交给工厂类去做,客户端或调用者无需关心自己调用的是哪个对象。

工厂模式解决什么问题?

一个接口或者抽象类有多个实现,调用者会根据类型选择不同的实现类。如果不用工厂模式,就会在代码里出现 if...else 和 switch...case 的条件分支代码,如果新增或删除实现类就需要修改当前代码,违反了开/闭原则。

工厂模式有哪些例子?

这个例子是我工作真实的代码例子,为了保证私密性,有些细节需要隐藏。

具体场景是:营业执照有很多模版,不同模版显示的内容也不相同,程序需要根据客户传来的类型生成不同的营业执照。

先创建营业执照的抽象类:

public abstract class BizLicense {
private String type;
public BizLicense() { } public BizLicense(String type) { this.type = type; }
public BizLicense paresLicense(){ parseLicenseSub(); return this; }
/** * 解析执照 */ public abstract void parseLicenseSub();
}
复制代码


创建营业执照的实现类:

public class BizTypeALicense extends BizLicense{
public BizTypeALicense() { super(); } public BizTypeALicense(String type) { super(type); }
@Override public void parseLicenseSub() { //A类执照业务逻辑 }}
复制代码

其他类别营业执照类似以上结构,只是业务逻辑不同。


创建简单工厂类:

public class ParseLicenseFactory {        public static BizLicense parse(String type){        if (type.indexOf("A") != -1){            return new BizTypeALicense(entity);        }else if (type.indexOf("B") != -1){            return new BizTypeBLicense(entity);        }else if (type.indexOf("C") != -1){            return new BizTypeCLicense(entity);        }else if (type.indexOf("D") != -1){            return new BizTypeDLicense(entity);        }        return null;    }}
复制代码


调用营业执照工厂创建营业执照:

String type = "A";BizLicense bizLicense = ParseLicenseFactory.parse(type).paresLicense() ;
复制代码


策略模式

什么是策略模式?

让客户端(调用者)依赖一组接口,接口实现的变化不影响客户端的调用,并且实现的细节对客户端不可见。

策略模式解决什么问题?

策略模式解决的问题与工厂模式解决的问题类似。

如何用 Springboot 去实现策略模式?

该例子也是我工作中真实的例子,利用了 Spring 的依赖注入去实现策略模式。

首先定义业务接口:

public interface GetQrResultService {  	LicGetInfResponse get(BizLicense bizLicense);      }
复制代码


定义实现类:

//实现类指定类型,就是客户端需要传入的类型@Component(QrType.LIC_COPY)public class LicCopyGetter implements GetQrResultService {        @Override    public GetQrLicCopyResponse get(BizLicense bizLicense) {			  //实现业务逻辑      	renturn new GetQrLicCopyResponse();    }}
复制代码


定义策略类:

@Componentpublic class GetQrResultResponseFactory {
//Spring会自动注入GetQrResultService的实现类倒集合中。 @Autowired private Map<String, GetQrResultService> context = new ConcurrentHashMap<>();
public GetQrResultService getQrResult(String type) { return this.context.get(type); }}
复制代码


客户端调用:

Response response = getQrResultResponseFactory.getQrResult(qrType).get(bizLicense);
复制代码


观察者模式

什么是观察者模式?

一个对象有变化,依赖它的对象也要变化,类似订阅-发布模式。

观察者模式解决什么问题?

这里举个例子,村长得知猪肉要涨价的消息,他想把这个消息通过“村长大喇叭”通知给全村的人,让大家都养猪。如果大家想要知道最新的消息,就可以通过订阅“村长大喇叭”,等一有新消息,村长把消息通过“村长大喇叭”发布出去,听到大喇叭的村民就能知道最新消息了。

观察者模式有哪些例子?

以极客大学训练营为例,现在要做一个简单订阅系统,给新进训练营的同学发学习通知,有三种通知方式邮件、短信、微信。该系统简单设计的类图如下:


  1. 定义消息发布者 MessageProducer 类,其中有 MessageConsumer 类的集合和 addConsumer()增加订阅这的功能。

  2. 定义消息订阅者接口 MessageConsumer,有三个实现分别是 MailConsumer、ShortMessageConsumer、WeChatConsumer。

  3. 客户端循环遍历 MessageConsumer 集合,调用 MessageConsumer 的 send()方法发布消息出去。


*其他设计模式会继续补充至此。


设计原则

单一职责原则

什么是单一职责原则?

一个类只做一件事,只适应一种变化。

遵从单一职责有什么好处?

一个类只做一件事符合高内聚原则,使得业务模块清晰,可移植也可复用。


里氏替换原则

什么是里氏替换原则?

任何使用父类的地方都可以用子类去替换,保证代码的输入输出一切正常。

哪些设计违反了里氏替换原则?

  1. 子类违背父类要实现的功能。比如父类要实现订单按金额排序,子类重写后按日期排序。

  2. 子类违背父类对输入、输出、异常的约定。比如父类只抛出 AException,而子类多抛出了 BException。

  3. 子类违背父类注释中所罗列的任何特殊说明。比如父类中注释该业务是输出订单金额,但是子类注释该业务输出按时间排序后的订单金额。


开/闭原则

什么是开/闭原则?

对扩展开放,对修改关闭。

遵循开闭原则有什么好处?

软件是在需求不断变更的道路上慢慢完善的,代码就是软件的灵魂,如果不遵循开/闭原则,那么新需求来了会在原有的代码上进行修改或者增加新逻辑,这样的代码时间越长越不容易维护。


接口隔离原则

什么是接口隔离原则?

使客户端/调用者不要引用它不需要的接口。

遵循接口隔离原则有什么好处?

比如分布式系统管理模块类有注册服务器、删除服务器、重制策略等行为,现有两个客户端,一个是服务器节点和管理节点。那么对服务器来说就应该只提供注册服务器接口,不应该提供删除服务器和重制策略,因为这样服务器节点使用这两个接口会对整个分布式系统造成不必要的影响。,


依赖倒置原则

什么是依赖倒置原则?

依赖倒置原则又称好莱坞原则(Dont't call me.I'll call you.)。高层不依赖低层具体实现,高层应该依赖抽象(接口),低层去实现抽象,抽象属于高层。

遵循依赖倒置原则有什么好处?

依赖倒置原则一般在设计框架的时候非常有用,这也是这周课我最大的收获。我一直疑惑为什么我们在 Spring 下只写业务逻辑,就可以实现企业级的应用;为什么我把 war 包扔到 tomcat 下启动服务后就可以对外提供服务呢?

这些困扰都在知道依赖倒置原则后恍然大悟,框架的设计就是可以让业务逻辑代码可以在我的框架下运行,遵从我的规则运行,那如何实现?就需要框架,也就是高层设计定义一个抽象,可以是接口或者抽象类,低层只要去实现这个接口,就可以被高层调用,而高层不需要知道低层具体实现了什么,只要符合我的规则,就可以运行起来。


总结

本节课对我影响很大,让我知道框架设计需要哪些必备的知识和一些思考框架。

  1. 我学会了一个思考框架——一个事物出现,首先搞清楚它是什么,接着要明白它是要解决什么问题?最后知道它是怎么解决的?跟其他同类别的解决方案比较有什么优劣势。

  2. 了解了设计模式的重要性,和使用设计模式后代码的扩展性带来的好处。之前我就使用过几种比较常用的设计模式来写代码,至今还被公司沿用,而且扩展性非常好,不论是新增接口还是修改,都可以分分钟搞定,而且 bug 率很小。

  3. 设计原则之前了解过很多回,但是都没有记住,也不会应用到工作中。这周课老师的讲解简单易懂,让我对五大设计原则有了深深的印象,但是想要应用好还是件从长计议的事情。

  4. 依赖倒置原则对我影响非常大,这个设计思路也是很巧妙,他也给我工作中提供了一个管理框架,我其实是一个技术管理者,我一直在思考一个很有意思的事情,一件事我来做很快能搞定,但是我的组员来做就很吃力,遇到问题也不会经常找我解决,就算找我,我可能也没有太多精力管,所以这就导致组员的效率不高。

知道了依赖倒置原则后,我有个想法,就是把这个原则运用到管理上,其实也是个很不错的主意。我把我多年的经验和思考问题的框架整理出一套规则,一套可实现的框架,让组员们遵循我的框架执行,这样应该会事半功倍吧。

发布于: 2020 年 09 月 23 日阅读数: 52
用户头像

刘希文

关注

还未添加个人签名 2018.05.07 加入

还未添加个人简介

评论

发布
暂无评论
第二周-框架设计-学习总结