Golang设计模式之-装饰器模式

举报
kaliarch 发表于 2022/01/21 18:49:03 2022/01/21
【摘要】 一 装饰器模式简介装饰模式是一种结构型设计模式, 允许你通过将对象放入包含行为的特殊封装对象中来为原对象绑定新的行为。封装器是装饰模式的别称, 这个称谓明确地表达了该模式的主要思想。 “封装器” 是一个能与其他 “目标” 对象连接的对象。 封装器包含与目标对象相同的一系列方法, 它会将所有接收到的请求委派给目标对象。 但是, 封装器可以在将请求委派给目标前后对其进行处理, 所以可能会改变...

一 装饰器模式简介

装饰模式是一种结构型设计模式, 允许你通过将对象放入包含行为的特殊封装对象中来为原对象绑定新的行为。

封装器是装饰模式的别称, 这个称谓明确地表达了该模式的主要思想。 “封装器” 是一个能与其他 “目标” 对象连接的对象。 封装器包含与目标对象相同的一系列方法, 它会将所有接收到的请求委派给目标对象。 但是, 封装器可以在将请求委派给目标前后对其进行处理, 所以可能会改变最终结果。

二 代码

2.1 开发代码

package decorator

import "fmt"

// 装饰器模式

// 定义Going 的接口,包含 run 方法
type Going interface {
	Run()
}

// 定义 Car 对象, 实现run方法
type Car struct {
	name string
}

func (d *Car) Run() {
	fmt.Println("decorator do function")
}

// 为了给Car 方法增加额外功能,例如fly
// 该装饰接口包含被装饰的接口,并且新增额外方法
type AdvantageCar interface {
	Going
	Fly
}

// 定义新增方法接口
type Fly interface {	
	Flying()
}

// 定义装饰后的对象, 其属性包含被装饰的接口
type ACar struct {
	Going
}

// 新对象实现额外新增功能接口方法
func (a *ACar) Flying() {
	fmt.Println("flaying ")
}

func (a *ACar) Run() {
	// 先实现之前被装饰前的方法
	a.Going.Run()
	// 在实现额外新增功能方法
	a.Flying()
}

2.2 测试

package decorator

import (
	"fmt"
	"testing"
)

func TestCar_Run(t *testing.T) {
	c := Car{name: "BYD"}
	c.Run()
}

func TestACar_Run(t *testing.T) {
	fmt.Println("acar test......")
	ac := ACar{}

	g := &Car{name: "BMW"}
	ac.Going = g

	ac.Run()

}


/*
decorator do function
acar test......
decorator do function
flaying 
PASS
ok      github.com/kaliarch/mycode/design-patterns/structural/decorator 0.015s
*/

三 应用场景

  • 如果你希望在无需修改代码的情况下即可使用对象,且希望在运行时为对象新增额外的行为,可以使用装饰模式, 装饰能将业务逻辑组织为层次结构, 你可为各层创建一个装饰, 在运行时将各种不同逻辑组合成对象。 由于这些对象都遵循通用接口, 客户端代码能以相同的方式使用这些对象。

  • 如果用继承来扩展对象行为的方案难以实现或者根本不可行, 你可以使用该模式, 许多编程语言使用 final最终关键字来限制对某个类的进一步扩展。 复用最终类已有行为的唯一方法是使用装饰模式: 用封装器对其进行封装。

四 特点

  • 优点:
    • 你无需创建新子类即可扩展对象的行为。
    • 你可以在运行时添加或删除对象的功能。
    • 你可以用多个装饰封装对象来组合几种行为。
    • 单一职责原则。 你可以将实现了许多不同行为的一个大类拆分为多个较小的类。
  • 缺点:
    • 在封装器栈中删除特定封装器比较困难。
    • 实现行为不受装饰栈顺序影响的装饰比较困难。
    • 各层的初始化配置代码看上去可能会很糟糕。

参考链接

【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。