设计模式是前人总结的代码架构方式,主要是针对面向对象的代码。
JS 代码在 es6 中加入了 class 的支持,TS 又实现了 interface 和 abstract class 的语法,现在写面向对象的代码容易了很多,所以使用设计模式也就方便了很多。
不知道大家是否在代码里用过设计模式呢?
如果不知道怎么用的话,不妨来看下 Nest.js 是怎么用的吧:
案例 1
Nest.js 除了支持跑一个单独的 http 服务之外,还支持微服务,微服务一般就不是直接处理 http 了,可能是和 Redis 通信、和 Kafaka 等各种中间件通信等等。
各种不同中间件的客户端连接方式不同,而 Nest.js 希望把它们统一管理起来。
怎么统一管理呢?
它定义了这样一个策略接口:

有 listen 和 close 两个方法,分别是处理连接建立和断开的。
它内置了 7 个实现类,分别实现了 Grpc、Redis、Kafka、MQTT、Nats、RebbitMQ、TCP 的连接建立和断开的方式:

还继承了一个 Server 类,这个类里定义公用的一些属性和方法。
比如 ServerRedis 是这样实现 listen 和 close 的:

而 ServerKafka 是这样的:

传输方式有多种策略可以选择,通过定义统一的接口来管理它们,这就是策略模式。
然后它又创建了一个工厂类来根据参数创建不同的策略类:

这样代码使用的时候是这样的:


通过 transport 指定不同的传输方式,然后传入 options 即可。
Transport 是一个这样的枚举值:

这就是策略模式 + 工厂模式的应用。策略模式定义统一的结构来管理各种策略,工厂模式根据参数创建某个具体的实例。
有的同学可能会问了,这样写好处在哪里呢?
好处在于可以灵活的扩展传输策略。
官网有如何创建自定义传输策略的代码,也是继承 Server 实现 CustomTransportStrategy:

之后你想使用自己创建的策略类的话就可以这样:

源码里做了对自定义 strategy 的处理:

如果有自定义 strategy 就用自定义的,否则就用工厂来根据参数创建。
这样就实现了灵活的扩展策略类的需求。
这种灵活性是通过策略模式来实现的,这就是设计模式的好处。
案例 2
Nest.js 其实本身并不处理 http 协议,处理 http 是依赖更底层的 Express 实现的,但是它又不想和 Express 强耦合。
怎么办呢?
于是它定义了个 HttpServer 的接口,里面定义了 http 服务器应该有的所有方法:

然后又提供了个抽象类 AbstractHttpAdapter,对 HttpServer 的一些方法做了默认实现。

之后 ExpressAdapter 继承了 AbstractHttpAdapter,基于 Express 的 api 提供了这些方法的实现:

这样比起直接用 Express 的 api 有什么好处呢?
好处就是可以灵活的切换 http 实现了呀!
比如它还提供了另一个实现,基于 Fastify:

这样之后想切换别的 http 的实现就很容易了,并没有和 Express 强耦合。
这又是一个真实的设计模式的应用。
总结
设计模式是针对面向对象的代码的一些代码架构方式,JS 有了 class 的语法,ts 又加入了 interface 和 abstract class,写面向对象的代码容易多了,也就更容易使用设计模式了。
我们看了下 Nest.js 中设计模式的两个案例:
-
基于策略 + 工厂模式,实现了灵活的扩展传输策略。
-
基于适配器模式,实现了和 Express 的解耦,可以轻松的切换到另一个 http 处理库。
通过这两个例子可以看出来设计模式是能让代码的可扩展性更强、耦合度更低的。
现在 TS 代码应用设计模式容易了很多,遇到合适场景不妨就尝试用一些设计模式吧,能让你的代码变得更易扩展、更低耦合,写出更优雅的代码。
原文始发于微信公众号(神光的编程秘籍):项目里没用过设计模式?看看 Nest.js 怎么用的
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/108703.html