八种常见的设计模式

1. 单例模式(Singleton)

核心:保证一个类仅创建一个实例,全局可访问

场景:配置管理、数据库连接池、日志工具

单例模式核心是进程内全局唯一实例,生命周期和服务一致,核心解决「资源复用(如连接池 / 配置)」问题,要保证线程 / 协程安全(Go 用 sync.Once,Java 用双重校验锁),场景是数据库连接池、全局配置、日志工具。

Go 复制代码
package main

import "sync"

// 单例结构体
type Singleton struct {
	Name string
}

var (
	instance *Singleton
	once     sync.Once // 保证线程安全
)

// 获取单例实例
func GetInstance() *Singleton {
	once.Do(func() { // 仅执行一次
		instance = &Singleton{Name: "唯一实例"}
	})
	return instance
}

// 测试
func main() {
	s1 := GetInstance()
	s2 := GetInstance()
	println(s1 == s2) // 输出:true(同一实例)
}

2. 工厂模式(Factory)

核心:封装对象创建逻辑,按类型返回不同实现

场景:支付方式、文件解析器、消息渠道

Go 复制代码
package main

import "fmt"

// 支付接口
type Pay interface {
	Pay(amount float64) string
}

// 微信支付实现
type WechatPay struct{}
func (w *WechatPay) Pay(amount float64) string {
	return fmt.Sprintf("微信支付%.2f元", amount)
}

// 支付宝支付实现
type AliPay struct{}
func (a *AliPay) Pay(amount float64) string {
	return fmt.Sprintf("支付宝支付%.2f元", amount)
}

// 工厂方法
func CreatePay(payType string) (Pay, error) {
	switch payType {
	case "wechat":
		return &WechatPay{}, nil
	case "alipay":
		return &AliPay{}, nil
	default:
		return nil, fmt.Errorf("不支持的支付类型")
	}
}

// 测试
func main() {
	pay, _ := CreatePay("wechat")
	println(pay.Pay(100)) // 输出:微信支付100.00元
}

3. 策略模式(Strategy)

核心:封装一组可互换的算法,动态切换

场景:排序算法、促销规则、支付方式

Go 复制代码
package main

import "fmt"

// 策略接口
type Strategy interface {
	Calculate(amount float64) float64
}

// 满减策略
type FullReduce struct{}
func (f *FullReduce) Calculate(amount float64) float64 {
	if amount >= 200 {
		return amount - 50
	}
	return amount
}

// 折扣策略
type Discount struct{}
func (d *Discount) Calculate(amount float64) float64 {
	return amount * 0.8
}

// 上下文(使用策略)
type Context struct {
	strategy Strategy
}
func (c *Context) SetStrategy(s Strategy) {
	c.strategy = s
}
func (c *Context) Exec(amount float64) float64 {
	return c.strategy.Calculate(amount)
}

// 测试
func main() {
	ctx := &Context{}
	ctx.SetStrategy(&FullReduce{})
	println(ctx.Exec(200)) // 输出:150

	ctx.SetStrategy(&Discount{})
	println(ctx.Exec(200)) // 输出:160
}

4. 适配器模式(Adapter)

核心:兼容不匹配的接口,复用已有代码

场景:老接口适配新系统、第三方 SDK 接口统一

Go 复制代码
package main

import "fmt"

// 新系统期望的接口
type NewInterface interface {
	NewMethod() string
}

// 老接口(不兼容)
type OldStruct struct{}
func (o *OldStruct) OldMethod() string {
	return "老接口逻辑"
}

// 适配器:适配老接口到新接口
type Adapter struct {
	old *OldStruct
}
func (a *Adapter) NewMethod() string {
	// 调用老接口并转换结果
	return "适配后:" + a.old.OldMethod()
}

// 测试
func main() {
	old := &OldStruct{}
	adapter := &Adapter{old: old}
	println(adapter.NewMethod()) // 输出:适配后:老接口逻辑
}

5. 观察者模式(Observer)

核心:一对多依赖,状态变化自动通知观察者

场景:消息通知、订单状态变更、事件监听

Go 复制代码
package main

import "fmt"

// 观察者接口
type Observer interface {
	Update(msg string)
}

// 短信观察者
type SmsObserver struct{}
func (s *SmsObserver) Update(msg string) {
	fmt.Println("短信通知:", msg)
}

// 物流观察者
type LogObserver struct{}
func (l *LogObserver) Update(msg string) {
	fmt.Println("物流通知:", msg)
}

// 主题(被观察对象)
type Subject struct {
	observers []Observer
}
func (s *Subject) Add(o Observer) {
	s.observers = append(s.observers, o)
}
func (s *Subject) Notify(msg string) {
	for _, o := range s.observers {
		o.Update(msg)
	}
}

// 测试
func main() {
	sub := &Subject{}
	sub.Add(&SmsObserver{})
	sub.Add(&LogObserver{})
	sub.Notify("订单支付成功") // 输出两个通知
}

6. 装饰器模式(Decorator)

核心:不修改原类,动态增强功能

场景:日志、缓存、权限、限流增强

Go 复制代码
package main

import "fmt"

// 核心接口
type Service interface {
	Do() string
}

// 基础实现
type BaseService struct{}
func (b *BaseService) Do() string {
	return "核心业务逻辑"
}

// 日志装饰器
type LogDecorator struct {
	service Service
}
func (l *LogDecorator) Do() string {
	// 增强逻辑:前置日志
	fmt.Println("日志:开始执行")
	// 调用原逻辑
	res := l.service.Do()
	// 增强逻辑:后置日志
	fmt.Println("日志:执行完成")
	return res
}

// 测试
func main() {
	base := &BaseService{}
	// 包装成带日志的服务
	decorated := &LogDecorator{service: base}
	println(decorated.Do()) // 输出日志+核心逻辑
}

7. 代理模式(Proxy)

核心:代理类替原类执行,可加拦截 / 控制

场景:远程调用、权限控制、延时加载

Go 复制代码
package main

import "fmt"

// 核心接口
type UserService interface {
	GetUser(id int) string
}

// 真实服务
type RealUserService struct{}
func (r *RealUserService) GetUser(id int) string {
	return fmt.Sprintf("用户%d信息", id)
}

// 代理服务(权限控制)
type ProxyUserService struct {
	realService *RealUserService
	role        string
}
func (p *ProxyUserService) GetUser(id int) string {
	// 代理逻辑:权限校验
	if p.role != "admin" {
		return "无权限访问"
	}
	// 调用真实服务
	return p.realService.GetUser(id)
}

// 测试
func main() {
	proxy := &ProxyUserService{
		realService: &RealUserService{},
		role:        "guest", // 非管理员
	}
	println(proxy.GetUser(1)) // 输出:无权限访问

	proxy.role = "admin"
	println(proxy.GetUser(1)) // 输出:用户1信息
}

8. 模板方法模式(Template)

核心 :固定流程骨架,具体步骤子类实现场景:支付流程、文件上传、报表生成

Go 复制代码
package main

import "fmt"

// 抽象模板类
type Template struct{}

// 固定流程(模板方法)
func (t *Template) Process() {
	t.Step1()
	t.Step2()
	t.Step3()
}

// 通用步骤(父类实现)
func (t *Template) Step1() {
	fmt.Println("通用步骤:初始化")
}

// 抽象步骤(子类实现)
func (t *Template) Step2() {}

// 通用步骤
func (t *Template) Step3() {
	fmt.Println("通用步骤:收尾")
}

// 具体实现1
type ConcreteTemplate1 struct{ Template }
func (c *ConcreteTemplate1) Step2() {
	fmt.Println("具体步骤1:执行业务A")
}

// 测试
func main() {
	c1 := &ConcreteTemplate1{}
	c1.Process() // 输出:初始化→业务A→收尾
}

总结

模式 核心记忆点 典型场景
单例模式 唯一实例 配置 / 连接池
工厂模式 按类型创建对象 支付 / 解析器
策略模式 算法可互换 促销 / 排序
适配器模式 接口兼容 老系统适配
观察者模式 状态变更通知 消息 / 订单通知
装饰器模式 动态增强功能 日志 / 缓存
代理模式 代理执行 + 拦截 权限 / 远程调用
模板方法模式 固定流程,自定义步骤 标准化业务流程

工厂模式和策略模式的区别:

工厂模式聚焦「对象创建」,核心是「帮你造对象,你只管用来;

策略模式聚焦「算法执行」,核心是「你给我对象,我帮你切换执行」;

工厂是创建型模式,策略是行为型模式。

注:文章由豆包辅助生成

相关推荐
geovindu3 小时前
python: Bridge Pattern
python·设计模式·桥接模式
Anurmy10 小时前
设计模式之构建器模式
设计模式
鱼骨不是鱼翅12 小时前
个人简历面试复习-----设计模式篇(一)
设计模式
电子科技圈13 小时前
从工具到平台:如何化解跨架构时代的工程开发和管理难题
人工智能·设计模式·架构·编辑器·软件工程·软件构建·设计规范
Anurmy14 小时前
设计模式之装饰模式
设计模式
TimberWill14 小时前
优化if else过多的方案(含设计模式处理方式)
java·设计模式
@insist12314 小时前
软件设计师-结构型与行为型设计模式全解:软考设计模式考点一站式通关
设计模式·软考·软件设计师·软件水平考试
JTCC16 小时前
Java 设计模式西游篇 - 第五回:装饰者模式添法力 悟空披挂新战袍
java·观察者模式·设计模式
逆境不可逃17 小时前
【从零入门23种设计模式13】行为型之责任链模式
算法·leetcode·游戏·设计模式·责任链模式