找回密码
 会员注册
查看: 14|回复: 0

一文读懂10种最经典的设计模式

[复制链接]

2万

主题

0

回帖

6万

积分

超级版主

积分
65013
发表于 2024-10-9 20:06:27 | 显示全部楼层 |阅读模式
一文读懂10种最经典的设计模式 王顺驰 腾讯云开发者 腾讯云开发者 腾讯云计算(北京)有限责任公司 腾讯云官方社区公众号,汇聚技术开发者群体,分享技术干货,打造技术影响力交流社区。 886篇内容 2024年08月30日 08:45 北京 目录1 单例模式(Singleton Pattern)2 工厂模式(Factory Pattern)3 观察者模式(Observer Pattern)4 装饰者模式(Decorator Pattern)5 策略模式(Strategy Pattern)6 适配器模式(Adapter Pattern)7代理模式(Proxy Pattern)8命令模式(Command Pattern)9组合模式(Composite Pattern)10迭代器模式(Iterator Pattern)软件设计模式是一套被反复使用、多数人知晓的、经过分类编目的、代码设计经验的总结。它的意义在于这些模式是众多程序员经过相当长的一段时间的试验和错误复盘所总结的宝贵经验,可以帮助我们提高代码的可重用性、可读性和可靠性。本文由腾讯云天御业务安全工程师王顺驰撰写,总结了 10种经典的软件设计模式的特点、优缺点和应用场景,并给出了相应代码示例。关注腾讯云开发者,一手技术干货提前解锁01单例模式(Singleton Pattern)单例模式是一种创建型设计模式,它限制了实例化类的对象个数,确保在任何情况下,一个类只有一个实例,并且提供一个全局访问点。这种模式在需要全局状态控制或共享资源访问时非常有用。特点:只有一个实例对象。必须自行创建实例对象。必须提供一个访问该实例的全局访问点。优点:确保在应用中,资源或状态的全局唯一性。减少系统资源消耗,提高系统效率。缺点:反模块化,因为单例对象需要被多个客户端引用,这违反了高内聚低耦合的设计原则。难以测试,因为单例对象的生命周期与应用相同,这使得在单元测试中进行隔离测试变得困难。应用场景:配置管理器:在应用程序中,配置信息通常只需要一个实例来管理,这样可以保证配置信息的一致性。连接池:数据库连接池需要限制数据库连接的数量,以避免过多的连接消耗资源。日志记录器:日志系统通常只需要一个实例来记录应用程序的日志信息,以避免日志信息的冗余和混乱。硬件管理器:对于某些硬件设备,如打印机或扫描仪,可能只需要一个管理器来控制对它们的访问。应用状态管理:在某些应用中,需要全局的状态管理,如用户会话管理或权限验证状态。// 定义一个结构体Singleton,用于存储单例的实例数据type singleton struct { value string // 这里可以存储单例对象的任何数据}// 定义一个全局变量instance,用于存储单例的实例var instance *singleton// getInstance函数用于获取单例的实例// 如果instance为nil,则创建一个新的singleton实例// 否则,返回已存在的实例func getInstance() *singleton { if instance == nil { instance = &singleton{value: "unique instance"} // 这里初始化singleton实例 } return instance // 返回单例的实例}func main() { // 获取单例的实例 singletonInstance := getInstance() fmt.Println(singletonInstance.value) // 输出: unique instance // 再次获取单例的实例,将返回相同的实例 anotherInstance := getInstance() if singletonInstance == anotherInstance { fmt.Println("Both instances are the same") // 输出: Both instances are the same }}在并发环境下如果没有适当的同步机制,多个 goroutine 可能会同时检测到instance为nil并尝试创建新的实例,从而导致创建多个实例。为了解决这个问题,可以使用sync.Once,它确保在并发环境中只执行一次初始化操作。// 定义一个结构体Singleton,用于存储单例的实例数据type singleton struct { value string // 这里可以存储单例对象的任何数据}// 定义一个Once对象,用于确保初始化操作只执行一次var once sync.Once// 定义一个全局变量instance,用于存储单例的实例var instance *singleton// 初始化函数,由Once.Do调用func initSingleton() { instance = &singleton{value: "unique instance"} // 这里初始化singleton实例}// getInstance函数用于获取单例的实例func getInstance() *singleton { // 执行initSingleton,确保instance只被初始化一次 once.Do(initSingleton) return instance // 返回单例的实例}func main() { // 获取单例的实例 singletonInstance := getInstance() fmt.Println(singletonInstance.value) // 输出: unique instance // 再次获取单例的实例,将返回相同的实例 anotherInstance := getInstance() if singletonInstance == anotherInstance { fmt.Println("Both instances are the same") // 输出: Both instances are the same } // 测试并发环境下的单例模式 var wg sync.WaitGroup for i := 0; i = len(c.Children) { return nil // 索引超出范围,返回nil } return c.Children[i]}func main() { // 创建叶节点 leafA := &Leaf{name: "Leaf A"} leafB := &Leaf{name: "Leaf B"} // 创建组合节点 composite := &Composite{name: "Composite Root"} composite.Add(leafA) // 向组合中添加叶节点A composite.Add(leafB) // 向组合中添加叶节点B // 执行组合节点的操作 composite.Operation()}10迭代器模式(Iterator Pattern)迭代器模式是一种行为设计模式,它允许你顺序访问一个聚合对象中的各个元素而不需要暴露其内部的表示。迭代器模式提供了一种通过抽象迭代器来遍历元素的方法,使得你可以在不知道具体集合类型的情况下,对集合进行遍历。特点:抽象化遍历过程:迭代器定义了遍历元素的接口。支持多种遍历方式:不同的迭代器可以实现不同的遍历策略。聚合对象与迭代器解耦:聚合对象不需要知道迭代器的具体实现。优点:抽象化集合的访问,使客户端代码与集合的内部表示无关。可以提供多种遍历方式,如正序或逆序遍历。增加了集合的灵活性,可以在不修改集合类的情况下,引入新的遍历方式。缺点:增加了系统的复杂性,需要为每个聚合类设计迭代器类。需要额外的代码来实现迭代器。应用场景:遍历集合:在需要遍历集合元素的系统中,迭代器模式提供了一种通用的遍历机制。数据结构:在实现复杂的数据结构如树、图等时,迭代器模式可以用来遍历结构中的节点。数据库查询:在数据库查询中,迭代器可以用来逐条访问查询结果。用户界面:在用户界面开发中,迭代器可以用来遍历界面元素。多维数组访问:在需要访问多维数组元素的系统中,迭代器可以提供一种顺序访问的方式。// 定义Iterator接口,它声明了迭代器必须实现的Next和Current方法type Iterator interface { Next() bool // 移动到下一个元素,并返回是否成功移动 Current() interface{} // 返回当前元素}// 定义ConcreteIterator结构体,它实现了Iterator接口type ConcreteIterator struct { items []string // 存储聚合对象的元素列表 index int // 当前迭代到的元素索引}// Next方法实现,用于移动到下一个元素func (c *ConcreteIterator) Next() bool { if c.index 0 & c.index
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 会员注册

本版积分规则

QQ|手机版|心飞设计-版权所有:微度网络信息技术服务中心 ( 鲁ICP备17032091号-12 )|网站地图

GMT+8, 2024-12-29 12:41 , Processed in 0.678912 second(s), 25 queries .

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表