您的位置:

装饰器模式golang,装饰器模式例子

本文目录一览:

IO流中的设计模式

1.IO中用到的适配器模式

在IO中,如将字符串数据转变成字节数据保存到文件中,将字节数据转变成流数据等都用到了适配器模式,下面以InputStreamReader和OutputStreamWriter类为例介绍适配器模式。

InputStreamReader和OutputStreamWriter类分别继承了Reader和Writer接口,但要创建它们必须在构造函数中传入一个InputStream和OutputStream的实例,InputStreamReader和OutputStreamWriter的作用也就是将InputStream和OutputStream适配到Reader和Writer。

InputStreamReader实现了Reader接口,并且持有了InputStream的引用,这是通过StreamDecoder类间接持有的,因为byte到char要经过编码。

这里,适配器就是InputStreamReader类,而源角色就是InputStream代表的实例对象,目标接口就是Reader类,OutputStreamWriter类也是类似的方式。

在IO中类似的还有,如StringReader将一个String类适配到Reader接口,ByteArrayInputStream适配器将byte数组适配到InputStream流处理接口。

2.IO中用到的装饰模式

装饰模式就是对一个类进行装饰,增强其方法行为,在装饰模式中,作为原来的这个类使用者还不应该感受到装饰前与装饰后有什么不同,否则就破坏了原有类的结构了,所以装饰器模式要做到对被装饰类的使用者透明,这是对装饰器模式的一个要求。总之装饰器设计模式就是对于原有功能的扩展

在IO中有许多不同的功能组合情况,这些不同的功能组合都是使用装饰器模式实现的,下面以FilterInputStream为例介绍装饰器模式的使用。

InputStream类就是以抽象组件存在的,而FileInputStream就是具体组件,它实现了抽象组件的所有接口,FilterInputStream类就是装饰角色,它实现了InputStream类的所有接口,并持有InputStream的对象实例的引用,BufferedInputStream是具体的装饰器实现者,这个装饰器类的作用就是使得InputStream读取的数据保存在内存中,而提高读取的性能。类似的还有LineNumberInputStream类,它的作用是提高按行读取数据的功能。

总结

这两种设计模式看起来都是起到包装一个类或对象的作用,但是使用它 们的目的却不尽相同。适配器模式主要在于将一个接口转变成另一个接口,它的目的是通过改变接口来达到重复使用的目的;而装饰器模式不是要改变被装饰对象的接口,而是保持原有的接口,但是增强原有对象的功能,或改变原有对象的方法而提高性能。

补充:高性能的IO体系。

首先得明白什么是同步,异步,阻塞,非阻塞.

1,同步和异步是针对应用程序和内核的交互而言的

2,阻塞和非阻塞是针对于进程在访问数据的时候,根据IO操作的就绪状态来采取的不同方式

总结一句简短的话,同步和异步是目的,阻塞和非阻塞是实现方式。

名词解释

同步 指的是用户进程触发IO操作并等待或者轮询的去查看IO操作是否就绪 自己上街买衣服,自己亲自干这件事,别的事干不了。

软件开发中的装饰器模式是什么呢?

装饰器模式就是动态地给一个对象添加一些额外的职责。就增加功能来说,装饰器模式相比生成子类更为灵活。

1.装饰器模式允许向一个现有的对象添加新的功能,同时又不改变其结构。这种类型的设计模式属于结构性模式,它是作为现有的类的一个包装。

2.这种模式创建了一个装饰类,用来包装原有的类,并在保持类方法签名完整性的前提下,提供了额外的功能。

3.我们通过下面的实例来演示装饰器模式的用法。其中,我们将把一个形状装饰上不同的颜色,同时又不改变形状类。

什么是装饰器模式

装饰器模式是允许向一个现有的对象添加新的功能,同时又不改变其结构。这种类型的设计模式属于结构型模式,它是作为现有的类的一个包装。通俗的来讲,就是一个对象嵌入到另一个对象中去,实际上相当于这个对象被另一个对象包装起来,形成一条包装链。

主要是解决为了扩展一个类经常使用继承方式实现,由于继承为类引入静态特征,并且随着扩展功能的增多,子类会很膨胀。优点是,装饰类和被装饰类可以独立发展,不会相互耦合,装饰模式是继承的一个替代模式,装饰模式可以动态扩展一个实现类的功能。

应用场景:(a)在不影响其他对象的情况下,以动态、透明的方式给单个对象添加职责。 (b) 需要动态地给一个对象增加功能,这些功能也可以动态地被撤销。 当不能采用继承的方式对系统进行扩充或者采用继承不利于系统扩展和维护时。

在装饰器模式中的角色有:

抽象构件(Component)角色:给出一个抽象接口,已规范准备接收附加责任的对象。具体构件(ConcreteComponent)角色:定义一个将要接收附加责任的类。装饰(Decorator)角色:持有一个构件(Component)对象的实例,并定义一个与抽象构件接口一致的接口。具体装饰(ConcreteDecorator)角色:负责给构件对象“贴上”附加的责任。

设计模式|菜鸟教程 - C3 结构型模式

适配器模式:SD读卡器

桥接模式:抽象是抽象,具体是具体,隔离开来

过滤器模式:结果是一个list,用不同的标准类去过滤

组合模式:树

装饰器模式:实现同一套接口,但是增加功能

外观模式:隐藏结构的复杂性,比如提供一个api接口,每个api调用的模块细节隐藏

享元模式:

代理模式:实现同一套接口,但是功能不变,只是加一下控制

创建一个接口类,集成被扩展的类;

是作为两个不兼容的接口之间的桥梁。这种类型的设计模式属于结构型模式,它结合了两个独立接口的功能。

举个真实的例子SD读卡器,读卡器是作为内存卡和笔记本之间的适配器。您将内存卡插入读卡器,再将读卡器插入笔记本,这样就可以通过笔记本来读取内存卡。

我们通过下面的实例来演示适配器模式的使用。其中,音频播放器设备只能播放 mp3 文件,通过使用一个更高级的音频播放器来播放 vlc 和 mp4 文件。

应用实例:

比如绘制四种车,每种车有3种启动方式,将抽象和实现分离,解决多次继承的问题。

不必要的继承导致类爆炸;

在一个抽象类里面聚合其他的抽象类(比多继承好)

使用场景:

过滤器模式(Filter Pattern)或标准模式(Criteria Pattern)是一种设计模式,这种模式允许开发人员使用不同的标准来过滤一组对象,通过逻辑运算以解耦的方式把它们连接起来。

即声明一种检测标准类,如下:

通过实现这个接口来选出不同的对象。

其实就是树的架构,每个节点都相同

应用实例:

动态地给一个对象添加一些额外的职责。就增加功能来说,装饰器模式相比生成子类更为灵活。

类图:

以下情况可以使用装饰器模式:

隐藏系统的复杂性,并向客户端提供了一个客户端可以访问系统的接口。这种类型的设计模式属于结构型模式,它向现有的系统添加一个接口,来隐藏系统的复杂性。

享元模式尝试重用现有的同类对象,如果未找到匹配的对象,则创建新对象。

跟单例模式差不多,可以称之为多例模式:

核心使用一个hashmap存储一个之前用过的对象,如果有了就不用创建新的了

何时使用:

应用实例:

一个类代表另一个类的功能。

主要解决:在直接访问对象时带来的问题,比如说:要访问的对象在远程的机器上。在面向对象系统中,有些对象由于某些原因(比如对象创建开销很大,或者某些操作需要安全控制,或者需要进程外的访问),直接访问会给使用者或者系统结构带来很多麻烦,我们可以在访问此对象时加上一个对此对象的访问层。

例子:

注意事项:

Kubectl源码阅读

本章的任务主线任务如下

其实kubectl的每个子命令流程大体分为三步,

首先以下面的命令作为起始任务,看看kubectl的代码结构

kubernetes的所有组件入口函数几乎都是一致的,使用的命令行解析库是cobra

为什么不直接用标准库的flag呢?因为标准库的flag库与linux下的POSIX命令行参数标准不兼容,比如linux下的命令行 -a -b可以连起来写成-ab, 而golang官方库的flag不支持。

在深入get.NewCmdGet("kubectl", f, ioStreams)之前,首先看看委托者模式

输出如下:

总的来书,具体的实现由Delegate实现,上层就是一层层的往下委托, 而kubectl中的f := cmdutil.NewFactory(matchVersionKubeConfigFlags)就是如此。

以ToRESTConfig方法为例,委托调用链如下

委托模式使得我们可以用聚合来替代继承,它还使我们可以模拟mixin

每个cobra.Command的创建其实差不多

在深入请求的逻辑之前先看看代码中用到的设计模式,其实还有一个装饰器模式,但其实就是在原函数的基础上包装一层,就不说了。

访问者模式的好处在于将熟悉的配置抽象成方法,可以隐藏一些复杂的细节,以及控制内部属性

输出如下

访问者模式的好处在于定义统一的接口让外部与内部交流,解耦数据与数据处理逻辑。

从上文知道,result对象最终在Do方法中创建,所以看下它对应的实现。

那么从外层到内层的调用链如下:

构造对应的result对象

这个result对象的构造过程比较复杂,我也没完全看懂,等我看懂了在来写吧。

那么继续看看数据在哪里出发吧。

未完待续。。。。