1.Golang 设计模式之装饰器模式
Golang 设计模式之装饰器模式
本期和大家交流的找鸡是设计模式中的装饰器模式。
装饰器模式的蛋源基本定义是:在不变更原对象结构的基础上,动态地为对象增加附属能力。码领码它与“继承”有一定的鸡蛋相似之处,但侧重点不同,小程序源可以将装饰器模式视为“继承”的找鸡装机联盟挂机源码大全一种补充手段。
为了更好地理解装饰器模式,蛋源以下是码领码一个实际案例的分析:
通过编程的方式,我们可以还原上述场景问题。鸡蛋一种常见的小程序源实现方式是采用继承。然而,找鸡这种实现方式需要对子类的蛋源ociuldr2源码等级和种类进行枚举,包括一系列一级和二级子类。码领码这种固定的鸡蛋等级架构存在一些问题。
因此,小程序源在这种“加料”场景中,使用继承的设计模式可能并不合适。我们可以改变思路,不再关注对所有组合种类的枚举,而是将注意力放在“加料”的过程中。
在这种实现思路下,就诞生了基于“装饰器模式”的实现架构。例如,pi远控源码一份鸡蛋培根盖浇饭可以由一份白米饭(核心类)加上一份鸡蛋(装饰器1)和一份培根(装饰器2)组成,其中鸡蛋和培根的装饰顺序不限制。这样,无论后续有多少种新的“菜品”加入,我们只需声明其对应的装饰器类即可。
比如,双份鸡蛋盖浇饭 = 一份白米饭(核心类)+ 一份鸡蛋(装饰器1)+一份鸡蛋(装饰器1);鸡蛋火腿青椒盖浇饭 = 一份白米饭(核心类)+ 一份鸡蛋(装饰器1)+一份青椒(装饰器2)+一份火腿(装饰器3);双份牛肉青椒盖浇饭 = 一份白米饭(核心类)+ 一份青椒(装饰器4)+一份牛肉(装饰器5)+一份牛肉(装饰器5)。
至此,问题得到了圆满解决。接下来,我们对装饰器模式和继承模式进行对比总结。审计问题整改源码
下面进入代码实战环节,通过编程实现一个搭配食材的案例,展示装饰器模式的实现细节。
这个案例非常简单,我们需要在主食的基础上添加配菜,最终搭配出美味可口的食物套餐。其中主食包括米饭 rice 和面条 noodle 两条,配菜包括老干妈 LaoGanMa(老干妈拌饭顶呱呱)、火腿肠 HamSausage 和煎蛋 FriedEgg 三类。
事实上,如果需要,代码雨源码简单主食和配菜也可以随时进行扩展。在装饰器模式中,这种扩展行为的成本并不高。
接下来,展示一下总体的 UML 类图。
首先是对应于装饰器模式中核心类的是原始的主食 Food,我们声明了一个 interface,其中包含两个核心方法,Eat 和 Cost,含义分别为食用主食以及计算出主食对应的花费。
接下来是装饰器部分,我们声明了一个 Decorate interface,它们本身是在强依附于核心类(主食)的基础上产生的,只能起到锦上添花的作用,因此在构造器函数中,需要传入对应的主食 Food。
接下来分别声明三个装饰器的具体实现类,对应为老干妈 LaoGanMaDecorator、火腿肠 HamSausageDecorator 和煎蛋 FriedEggDecorator。
每个装饰器类的作用是对食物进行一轮装饰增强,因此需要在构造器函数中传入待装饰的食物,然后通过重写食物的 Eat 和 Cost 方法,实现对应的增强装饰效果。
下面提供另一种闭包实现装饰增强函数的实现示例,其实现也是遵循着装饰器模式的思路,但在形式上会更加简洁直观一些。
其中核心的处理方法 handleFunc 对应的是装饰器模式中的核心类,Decorate 增强方法对应的则是装饰器类,每次在执行 Decorate 的过程中,都会在 handleFunc 前后增加一些额外的附属逻辑。
为了加深理解,以下摘出一个实际项目中应用到装饰器模式的使用案例进行分析。
这里给到的案例是 grpc-go 中对拦截器链 chainUnaryInterceptors 的实现。
在 grpc-go 服务端模块中,每次接收到来自客户端的 grpc 请求,会根据请求的 path 映射到对应的 service 和 handler 进行执行逻辑的处理,但在真正调用 handler 之前,会先经历一轮对拦截器链 chainUnaryInterceptors 的遍历调用。
下面我们来观察一下其中具体的源码细节。
首先,对于拦截器类 UnaryServerInterceptor,本身是一个函数的类型。
下面是生成拦截器链的方法 chainUnaryInterceptors。该方法入参是用户定义好的一系列拦截器 interceptors,内部会按照顺序对拦截器进行组装,最终通过层层装饰增强的方式,将整个执行链路压缩成一个拦截器 UnaryServerInterceptor 的形式进行方法。
在这个过程中,就体现了我们今天讨论的装饰器模式的设计思路。核心业务处理方法 handler 对应的就是装饰器模式中的核心类,每一轮通过拦截器 UnaryServerInterceptor 对 handler 进行增强的过程,对应的就是一次“装饰”的步骤。
下面给出一个具体实现的装饰器的代码示例,可以看到其中在核心方法 handler 前后分别执行了对应的附属逻辑,起到了装饰的效果。
如果各位读友们想了解更多关于 grpc-go 的内容,可以阅读我之前发表的相关话题文章。
本期和大家交流了设计模式中的装饰器模式。装饰器模式能够动态地为对象增加某种特定的附属能力,相比于继承模式显得更加灵活,且符合开闭原则,可以作为继承模式的一种有效补充手段。
2024-11-25 21:05
2024-11-25 20:25
2024-11-25 20:03
2024-11-25 20:01
2024-11-25 19:45
2024-11-25 18:33