Netty入门学习(八):Netty创建NioEventLoopGroup实例过程中使用到的设计模式
背景
了解Netty中NioEventLoopGroup和JDK中的Executor的继承关系。NioEventLoopGroup
目的:创建一个NioEventLoopGroup对象。
- 使用了工厂方法设计模式。
- 使用了代理设计模式。
- 使用了命令设计模式。
- 使用了装饰设计模式。
类图
- 创建NioEventLoopGroup实例的核心类图
-
关系说明
NioEventLoopGroup继承了MultithreadEventExecutorGroup类的。而MultithreadEventExecutorGroup类持有来自JDK源码的ThreadFactory类的引用。
DefaultThreadFactory实现了ThreadFactory接口。而DefaultRunnableDecorator是DefaultThreadFactory类的内部类。
理解
-
从new NioEventLoopGroup()方法,一路链接下去,就可以在类MultithreadEventExecutorGroup 中找到如下代码。
从这段代码,就可以关联到上面类图。 -
newDefaultThreadFactory()
这里的DefaultThreadFactory实例来自Netty源码中,并且这个类也实现了JDK源码的ThreadFactory. -
new ThreadPerTaskExecutor()
这里的属性threadFactory的具体实例就是来自Netty的DefaultThreadFactory,从名字中可以看出使用了工厂方法设计模式。ThreadPerTaskExecutor类持有了JDK源码中的ThreadFactory类的引用,可以看出这里其实使用了代理设计模式。
其中 execute(Runnable command)方法,是具体创建实例的方法。从这个方法依赖的参数名称可以看出使用了命令设计模式。
-
DefaultRunnableDecorator
这里使用了装饰设计模式。
问与答
问:如何理解这里的设计模式?
答:做什么?谁来做中间人?谁来分配任务?怎么干?如果自己干不了,可以增加 “人手” 吗?
- 目的是创建NioEventLoopGroup实例。工厂方法设计模式就是创建一个类的具体实例。结论:所有构建类(事物分类)的设计模式都是创建类(具体的Java类)的实例。
- 代理人去做中间人。代理人是从来不具体实施任务的,它只是一个桥梁,连接着需求的发布方和需求的接收方,起一个平台或者中间人的作用。代理设计模式。
- 任务统筹安排者。当从代理人那里得知任务来了的时候,也不会立即去干,而需要一个类统筹分配所有的任务。它只负责分配具体的任务给到具体的人,从来不关系具体的实施步骤,只关心谁来做和做什么,它最终关心的只是一个结果。
- 具体实施者。就是设计一个类,让它完成这任务,它需要一个步骤又一个步骤地完成整个任务。
- 增加“人手”。在具体实施者完成任务过程中,他一般会遇见问题,这些问题他也搞不定,这个时候可以增加 “人手”,而这个人手可以带来新的功能。装饰设计模式。
我的理解
使用如上的设计模式,可以很好地满足单一职责原则,每个类只做自己的事情。
如果自己做不了的事情,就代理给别人做,我们不关心代理人怎么去完成这件事情,我们只要一个结果就行。
代理人只需要接洽具体任务实施方就可以了,他也只关心一个结果。
任务统筹者,它负责任务安排,不是他自己一个步骤又一个步骤地做。他把任务以命令的方式(命令设计模式:让专业的人,一个步骤一个步骤地去做任务)安排下去,让专业(专门负责的人,类的单一职责原则)的人去做。这样做的好处:把发出指令的人和具体完成指令的人完全解耦。
具体实施者,在做事情的时候,发现已经超出了自己的能力,那么它可以请求增加外援的(装饰设计模式:增强对象的功能,经典例子就是JDK IO类实现过程)协助来完成具体的任务。
充分体现了解耦的思想,利用设计原则把事物完全隔离开来。
小结
- 设计模式在使用的时候:一定要把设计模式的名称添加到类名称上,比如上面的ThreadFactory, command, DefaulRunnableDecorator等。
- 完成任何一个小逻辑,其实可以运用到很多设计模式。因为完成一个逻辑,需要创建实例,需要有任务的接收者,需要统筹分配任务的人,需要具体的实施者,需要专家来解决技术难题。而具体的实施在实现具体的逻辑过程中,一样可以使用到这些设计模式,他也可以用上模板方法设计模式,好让后来的新添加的类别事物,只需要沿着一个模板就可以复制出一个新的逻辑,甚至可以在模板方法中预留出勾子,这样可以应对某些具体任务的独特性。
- 模式的使用听起来,很厉害。但是,它一定有一个应用场景的。只有在一个适合的场景中使用设计模式,才有意义,而不是随便乱使用。
- 模式的使用,看起来很美好,其实理解起来会复杂。它需要引入一个继承或者实现或者组合的类结构体系。就是这单纯的体系结构,就不容易理解。它需要开发者理解一个个设计模式的背后用意,模式带来的好处和意义以及缺陷。它需要开发者学习更多的知识。