使用一个场景化的需求来连贯 22 种设计模式来记忆,
假设需求是搭建一个电商服务器(后端),我们从用户浏览商品、下单、支付到售后等流程(如果流程不全面再加上去),贯穿所有设计模式
设计模式的中文名分别说明,起好设计模式会用到的英文类名和对应的函数名来解释。
需求:搭建电商平台后端,涉及用户浏览、下单、支付、售后等完整流程
创建型模式
-
工厂方法(Factory Method)
类名:
UserAccountFactory
函数名:createUserAccount()
场景:在用户注册时,根据用户身份(如Customer
、Seller
、Admin
)创建相应的账户类型。
原因:用户注册时,不同身份(如Customer
、Seller
、Admin
)需要不同的功能和权限。工厂方法模式可以根据身份创建特定的账户对象,确保灵活性和扩展性。工厂方法-go1
-
抽象工厂(Abstract Factory)
类名:
ServiceFactory
函数名:createAuthService()
、createPaymentService()
场景:针对不同平台(如国内和国际),提供特定的服务套件,如支付和身份验证模块的实现。
原因:电商平台需兼容国内外不同支付和认证系统。抽象工厂模式提供一套适应不同平台的服务对象创建方案,使代码可以灵活切换环境而不影响整体结构。抽象工厂-go2
-
生成器(Builder)
类名:
OrderBuilder
函数名:addProduct()
、setDeliveryAddress()
、setPaymentMethod()
场景:在用户下单时,逐步构建订单对象,将商品、配送地址和支付方式组合到订单中。
原因:下单过程需要逐步构建订单,如添加商品、设置配送地址和支付方式。生成器模式能够按步骤创建复杂的对象,确保订单构建的顺序和结构。生成器-go3
-
原型(Prototype)
类名:
ProductPrototype
函数名:clone()
场景:针对用户购物车中的商品,复制某个已有商品对象,通过克隆快速生成相同商品实例。
原因:为满足用户快速添加多个相同商品至购物车的需求,原型模式可以通过克隆已有商品对象,避免每次重新创建,节省时间和系统资源。原型-go4
-
单例(Singleton)
类名:
CartService
函数名:getInstance()
场景:每个用户在整个浏览会话中共享唯一的购物车实例,用于管理当前添加的商品。
原因:每个用户在会话中应使用唯一的购物车实例。单例模式确保每个用户的购物车只有一个实例,避免数据不一致并节省系统资源。单例-go5
结构型模式
-
适配器(Adapter)
类名:
PaymentGatewayAdapter
函数名:processPayment()
场景:将不同支付网关(如PayPal
、Stripe
)接口适配到统一支付处理接口。
原因:不同支付网关接口(如PayPal
、Stripe
)可能有各自的 API。适配器模式将这些接口适配为统一的支付处理接口,方便调用和扩展。适配器-go6
-
桥接(Bridge)
类名:
ProductInfo
和DisplayPlatform
函数名:showDetails()
场景:为商品展示在不同平台(如 Web 端、移动端)提供不同的展示结构,桥接商品信息和展示平台。
原因:商品信息展示在 Web 和移动端的布局和格式不同。桥接模式将商品信息和展示平台分离,便于灵活调整展示方式。桥接-go7
-
组合(Composite)
类名:
Category
函数名:addSubCategory()
、displayProducts()
场景:实现商品分类树状结构,方便电商平台展示不同级别的商品分类及子分类。
原因:商品分类和子分类形成树状结构,组合模式使得树形结构中父类和子类具有一致性,便于递归显示和操作不同层级的分类。组合-go8
-
装饰(Decorator)
类名:
ProductDecorator
函数名:getDescription()
场景:在商品详情页,为商品动态添加如促销、折扣等信息装饰,实现多样化的商品描述。
原因:在商品详情页,需要动态添加促销、折扣等装饰信息。装饰模式允许在不改变基础商品对象的情况下,灵活地添加额外信息。装饰-go9
-
外观(Facade)
类名:
OrderFacade
函数名:processOrder()
场景:用户下单时,通过外观模式一次性调用支付、库存、配送等模块,简化后端订单处理流程。
原因:下单流程涉及多个系统模块(如支付、库存、物流等)的调用,外观模式通过统一接口封装复杂的内部调用逻辑,简化客户端操作。外观-go10
-
享元(Flyweight)
类名:
ProductImageFlyweight
函数名:getImage()
场景:使用享元模式共享重复商品的图片资源,避免内存浪费。
原因:同一商品的图片资源会在页面多次使用,享元模式可以共享相同图片对象,节省内存,提升系统性能。享元-go11
-
代理(Proxy)
类名:
OrderProxy
函数名:processOrder()
场景:代理控制用户的订单操作权限,比如顾客只能查看订单状态,管理员可以取消订单。
原因:在订单系统中,不同用户权限对订单有不同的操作需求。代理模式可以在用户和订单系统之间控制访问权限,保障数据安全。代理-go12
行为模式
-
责任链(Chain of Responsibility)
类名:
OrderHandlerChain
函数名:handle()
场景:订单处理流程中,依次经过库存检查、支付确认、配送等多个步骤进行处理。
原因:订单处理需要多个步骤依次完成,如库存检查、支付确认等。责任链模式能够灵活调整和扩展处理步骤。责任链-go13
-
命令(Command)
类名:
CartCommand
函数名:execute()
、undo()
场景:用户的购物车操作(如添加商品、移除商品)使用命令模式记录,以便可以撤销或重做操作。
原因:用户对购物车的操作(如添加、移除商品)可以用命令模式记录,便于实现撤销、重做等功能,提升用户体验。命令-go14
-
迭代器(Iterator)
类名:
ProductIterator
函数名:next()
、hasNext()
场景:在浏览商品列表或分页查看时,通过迭代器模式简化商品迭代的处理。
原因:用户浏览商品列表时,迭代器模式为分页提供统一的迭代接口,简化遍历操作,提高代码的灵活性和扩展性。迭代器-go15
-
中介者(Mediator)
类名:
CheckoutMediator
函数名:notify()
场景:在订单结算过程中,不同模块(如支付、库存、物流)通过中介者模式协同工作,避免模块间直接耦合。
原因:在订单结算过程中,支付、库存、物流等模块间相互通信复杂。中介者模式通过协调模块间交互,减少耦合,便于维护和扩展。中介者-go16
-
备忘录(Memento)
类名:
OrderStateMemento
函数名:save()
、restore()
场景:在用户修改订单前保存当前状态,以便在用户回退或恢复至之前状态时使用。
原因:用户在修改订单前保存状态,用备忘录模式可以保存和恢复订单状态,确保用户在回退时获得正确数据。备忘录-go17
-
观察者(Observer)
类名:
OrderStatusObserver
函数名:update()
场景:当订单状态变化(如发货、送达)时,通知用户和物流系统状态更新。
原因:当订单状态变化(如发货、送达)时,观察者模式可以将状态更新通知用户和物流系统,保证信息实时同步。观察者-go18
-
状态(State)
类名:
OrderState
函数名:nextState()
场景:订单的不同状态(如已下单、已发货、已收货、完成)通过状态模式管理转移逻辑。
原因:订单在不同状态间转换时,使用状态模式可以封装状态转移逻辑,简化状态管理,确保状态变化符合业务规则。状态-go19
-
策略(Strategy)
类名:
DiscountStrategy
函数名:applyDiscount()
场景:在商品折扣计算中,针对不同优惠策略(如满减、折扣、赠品)使用策略模式动态选择。
原因:商品折扣可以有多种策略(如满减、折扣、赠品),策略模式通过封装算法实现动态选择不同的优惠策略。策略-go20
-
模板方法(Template Method)
类名:
OrderProcessingTemplate
函数名:process()
场景:定义订单处理的模板方法,不同类型订单(如虚拟商品、实物商品)可以复用通用流程,并在特定步骤自定义。
原因:订单处理步骤可以复用一部分逻辑,不同订单类型的特定流程可以在模板方法中自定义,确保通用流程的可维护性。模板方法-go21
-
访问者(Visitor)
类名:
ReportVisitor
函数名:visitOrder()
、visitCustomer()
场景:为生成数据报表,访问订单、客户信息等结构化数据,执行不同统计分析逻辑。
原因:报表生成需要对订单和客户信息进行不同的数据统计分析,访问者模式能为不同结构化数据提供特定访问逻辑,便于扩展统计类型。访问者-go22
工厂方法-go
下面是使用 Go 实现的一个工厂方法模式示例代码,通过
UserAccountFactory
创建不同的用户账户类型(如Customer
、Seller
、Admin
)。package main import "fmt" // UserAccount 定义用户账户接口 type UserAccount interface { GetRole() string } // Customer 定义顾客账户 type Customer struct{} func (c *Customer) GetRole() string { return "Customer" } // Seller 定义卖家账户 type Seller struct{} func (s *Seller) GetRole() string { return "Seller" } // Admin 定义管理员账户 type Admin struct{} func (a *Admin) GetRole() string { return "Admin" } // UserAccountFactory 创建用户账户的工厂方法 func UserAccountFactory(accountType string) UserAccount { switch accountType { case "Customer": return &Customer{} case "Seller": return &Seller{} case "Admin": return &Admin{} default: return nil } } func main() { // 使用工厂方法创建不同用户账户 customer := UserAccountFactory("Customer") seller := UserAccountFactory("Seller") admin := UserAccountFactory("Admin") fmt.Println("Created account type:", customer.GetRole()) fmt.Println("Created account type:", seller.GetRole()) fmt.Println("Created account type:", admin.GetRole()) }
代码解释
-
UserAccount
接口定义了一个通用方法GetRole
,表示不同类型账户的角色。 -
Customer
、Seller
和Admin
是不同的账户类型,实现了UserAccount
接口。 -
UserAccountFactory
是工厂方法,根据传入的accountType
返回对应账户类型的实例。 - 在
main
函数中,通过调用UserAccountFactory
创建不同的账户类型,并输出它们的角色类型。
输出结果
↩Created account type: Customer Created account type: Seller Created account type: Admin
-
抽象工厂-go
下面是使用 Go 实现的一个抽象工厂模式示例代码。
ServiceFactory
用于创建不同平台(如DomesticServiceFactory
和InternationalServiceFactory
)的支付和身份验证服务。package main import "fmt" // AuthService 定义身份验证服务接口 type AuthService interface { Authenticate() string } // PaymentService 定义支付服务接口 type PaymentService interface { ProcessPayment() string } // DomesticAuthService 国内身份验证服务实现 type DomesticAuthService struct{} func (d *DomesticAuthService) Authenticate() string { return "国内身份验证成功" } // InternationalAuthService 国际身份验证服务实现 type InternationalAuthService struct{} func (i *InternationalAuthService) Authenticate() string { return "国际身份验证成功" } // DomesticPaymentService 国内支付服务实现 type DomesticPaymentService struct{} func (d *DomesticPaymentService) ProcessPayment() string { return "国内支付成功" } // InternationalPaymentService 国际支付服务实现 type InternationalPaymentService struct{} func (i *InternationalPaymentService) ProcessPayment() string { return "国际支付成功" } // ServiceFactory 抽象工厂接口 type ServiceFactory interface { CreateAuthService() AuthService CreatePaymentService() PaymentService } // DomesticServiceFactory 国内服务工厂 type DomesticServiceFactory struct{} func (d *DomesticServiceFactory) CreateAuthService() AuthService { return &DomesticAuthService{} } func (d *DomesticServiceFactory) CreatePaymentService() PaymentService { return &DomesticPaymentService{} } // InternationalServiceFactory 国际服务工厂 type InternationalServiceFactory struct{} func (i *InternationalServiceFactory) CreateAuthService() AuthService { return &InternationalAuthService{} } func (i *InternationalServiceFactory) CreatePaymentService() PaymentService { return &InternationalPaymentService{} } func main() { // 创建国内服务工厂 var domesticFactory ServiceFactory = &DomesticServiceFactory{} authService := domesticFactory.CreateAuthService() paymentService := domesticFactory.CreatePaymentService() fmt.Println(authService.Authenticate()) fmt.Println(paymentService.ProcessPayment()) // 创建国际服务工厂 var internationalFactory ServiceFactory = &InternationalServiceFactory{} authService = internationalFactory.CreateAuthService() paymentService = internationalFactory.CreatePaymentService() fmt.Println(authService.Authenticate()) fmt.Println(paymentService.ProcessPayment()) }
代码解释
- 接口定义:
AuthService
和PaymentService
分别定义身份验证和支付的接口。 - 实现具体服务:
DomesticAuthService
和InternationalAuthService
实现身份验证服务,DomesticPaymentService
和InternationalPaymentService
实现支付服务。 - 抽象工厂:
ServiceFactory
接口定义创建身份验证和支付服务的抽象方法。 - 具体工厂实现:
DomesticServiceFactory
和InternationalServiceFactory
分别实现了国内和国际服务工厂。 - 主函数调用:在
main
函数中,通过工厂实例化了不同平台的身份验证和支付服务。
输出结果
↩国内身份验证成功 国内支付成功 国际身份验证成功 国际支付成功
- 接口定义:
生成器-go
下面是使用 Go 实现的一个生成器模式示例代码,通过
OrderBuilder
来逐步构建订单对象(Order
),包括添加商品、设置配送地址和支付方式。package main import "fmt" // Order 订单对象 type Order struct { Products []string DeliveryAddress string PaymentMethod string } // OrderBuilder 定义订单生成器 type OrderBuilder struct { order *Order } // NewOrderBuilder 创建一个新的订单生成器 func NewOrderBuilder() *OrderBuilder { return &OrderBuilder{&Order{}} } // AddProduct 添加商品到订单 func (b *OrderBuilder) AddProduct(product string) *OrderBuilder { b.order.Products = append(b.order.Products, product) return b } // SetDeliveryAddress 设置订单配送地址 func (b *OrderBuilder) SetDeliveryAddress(address string) *OrderBuilder { b.order.DeliveryAddress = address return b } // SetPaymentMethod 设置订单支付方式 func (b *OrderBuilder) SetPaymentMethod(method string) *OrderBuilder { b.order.PaymentMethod = method return b } // Build 构建最终的订单 func (b *OrderBuilder) Build() *Order { return b.order } func main() { // 使用生成器模式逐步构建订单 order := NewOrderBuilder(). AddProduct("Laptop"). AddProduct("Phone"). SetDeliveryAddress("123 Main St, Springfield"). SetPaymentMethod("Credit Card"). Build() fmt.Printf("Order Details:\nProducts: %v\nDelivery Address: %s\nPayment Method: %s\n", order.Products, order.DeliveryAddress, order.PaymentMethod) }
代码解释
- Order:表示订单对象,包含商品列表、配送地址和支付方式。
- OrderBuilder:生成器类,用于逐步构建
Order
对象,通过链式方法AddProduct
、SetDeliveryAddress
和SetPaymentMethod
设置订单信息。 - NewOrderBuilder:创建并初始化一个新的
OrderBuilder
实例。 - Build:返回最终构建的
Order
对象。 - 主函数调用:在
main
函数中,调用OrderBuilder
逐步添加商品、设置地址和支付方式,最后生成订单。
输出结果
↩Order Details: Products: [Laptop Phone] Delivery Address: 123 Main St, Springfield Payment Method: Credit Card
原型-go
以下是使用 Go 实现的原型模式示例代码,通过
ProductPrototype
接口来克隆商品对象,方便在购物车中快速复制已有的商品。package main import "fmt" // ProductPrototype 定义克隆方法的接口 type ProductPrototype interface { Clone() ProductPrototype GetInfo() string } // Product 商品结构体 type Product struct { Name string Price float64 } // Clone 实现 ProductPrototype 接口中的 Clone 方法 func (p *Product) Clone() ProductPrototype { // 创建一个新的 Product 实例,复制当前对象的值 return &Product{ Name: p.Name, Price: p.Price, } } // GetInfo 获取商品信息 func (p *Product) GetInfo() string { return fmt.Sprintf("Product Name: %s, Price: %.2f", p.Name, p.Price) } func main() { // 创建一个商品原型 originalProduct := &Product{ Name: "Laptop", Price: 1500.00, } // 克隆商品 clonedProduct := originalProduct.Clone() // 输出克隆结果 fmt.Println("Original Product:", originalProduct.GetInfo()) fmt.Println("Cloned Product:", clonedProduct.GetInfo()) }
代码解释
- ProductPrototype 接口:定义了
Clone
方法,用于克隆商品对象。 - Product 结构体:实现了
ProductPrototype
接口中的Clone
方法,提供商品信息Name
和Price
。 - Clone 方法:通过创建新实例并复制当前对象的值,实现商品对象的克隆。
- 主函数调用:在
main
函数中,创建了一个商品原型并通过Clone
方法克隆商品实例。
输出结果
↩Original Product: Product Name: Laptop, Price: 1500.00 Cloned Product: Product Name: Laptop, Price: 1500.00
- ProductPrototype 接口:定义了
单例-go
以下是使用 Go 实现的单例模式示例代码,通过
CartService
确保每个用户会话中共享唯一的购物车实例。package main import ( "fmt" "sync" ) // CartService 购物车服务类,作为单例 type CartService struct { items []string } // 用于保存 CartService 单例实例 var cartInstance *CartService var once sync.Once // GetInstance 返回唯一的购物车实例 func GetInstance() *CartService { once.Do(func() { cartInstance = &CartService{} }) return cartInstance } // AddItem 添加商品到购物车 func (c *CartService) AddItem(item string) { c.items = append(c.items, item) } // GetItems 获取购物车中的商品 func (c *CartService) GetItems() []string { return c.items } func main() { // 获取购物车实例并添加商品 cart1 := GetInstance() cart1.AddItem("Laptop") cart1.AddItem("Phone") // 获取同一个购物车实例并查看商品 cart2 := GetInstance() fmt.Println("Cart items:", cart2.GetItems()) // cart1 和 cart2 是同一个实例 fmt.Printf("cart1 and cart2 are the same instance: %v\n", cart1 == cart2) }
代码解释
- CartService:定义购物车服务类,包含商品列表
items
和添加商品的AddItem
方法。 - 单例实现:通过
sync.Once
和GetInstance
方法,确保CartService
实例只创建一次,保证线程安全。 - 主函数调用:在
main
函数中,分别通过GetInstance
获取购物车实例cart1
和cart2
,并验证它们是否为同一实例。
输出结果
↩Cart items: [Laptop Phone] cart1 and cart2 are the same instance: true
- CartService:定义购物车服务类,包含商品列表
适配器-go
以下是适配器模式在 Go 中的一个简易实现示例,通过
PaymentGatewayAdapter
将不同支付网关适配到统一的processPayment
接口,方便在电商平台上统一调用。package main import "fmt" // PaymentProcessor 统一支付处理接口 type PaymentProcessor interface { ProcessPayment(amount float64) string } // PayPal 支付网关 type PayPal struct{} func (p *PayPal) MakePayment(amount float64) string { return fmt.Sprintf("Processed PayPal payment of $%.2f", amount) } // Stripe 支付网关 type Stripe struct{} func (s *Stripe) Charge(amount float64) string { return fmt.Sprintf("Processed Stripe payment of $%.2f", amount) } // PayPalAdapter 适配器,将 PayPal 适配到 PaymentProcessor 接口 type PayPalAdapter struct { paypal *PayPal } func (p *PayPalAdapter) ProcessPayment(amount float64) string { return p.paypal.MakePayment(amount) } // StripeAdapter 适配器,将 Stripe 适配到 PaymentProcessor 接口 type StripeAdapter struct { stripe *Stripe } func (s *StripeAdapter) ProcessPayment(amount float64) string { return s.stripe.Charge(amount) } func main() { // 使用 PayPal 适配器 paypalAdapter := &PayPalAdapter{paypal: &PayPal{}} fmt.Println(paypalAdapter.ProcessPayment(99.99)) // 使用 Stripe 适配器 stripeAdapter := &StripeAdapter{stripe: &Stripe{}} fmt.Println(stripeAdapter.ProcessPayment(199.99)) }
代码解释
- PaymentProcessor 接口:定义了统一的
ProcessPayment
方法。 - PayPal 和 Stripe:表示具体支付网关,每个网关有自己特定的支付方法(如
MakePayment
和Charge
)。 - PayPalAdapter 和 StripeAdapter:适配器类,分别将
PayPal
和Stripe
的接口适配到统一的ProcessPayment
接口。 - 主函数调用:在
main
函数中,通过PayPalAdapter
和StripeAdapter
适配器调用ProcessPayment
,实现了统一的支付处理方式。
输出结果
↩Processed PayPal payment of $99.99 Processed Stripe payment of $199.99
- PaymentProcessor 接口:定义了统一的
桥接-go
下面是桥接模式在 Go 中的一个简易实现,通过
ProductInfo
和DisplayPlatform
将商品信息和展示平台分离,为不同平台提供特定的展示方式。package main import "fmt" // DisplayPlatform 展示平台接口,提供展示方法 type DisplayPlatform interface { ShowDetails(name string, price float64) } // WebDisplay Web端展示平台 type WebDisplay struct{} func (w *WebDisplay) ShowDetails(name string, price float64) { fmt.Printf("Web Display -> Product: %s, Price: $%.2f\n", name, price) } // MobileDisplay 移动端展示平台 type MobileDisplay struct{} func (m *MobileDisplay) ShowDetails(name string, price float64) { fmt.Printf("Mobile Display -> Product: %s, Price: $%.2f\n", name, price) } // ProductInfo 商品信息类,使用展示平台接口 type ProductInfo struct { name string price float64 platform DisplayPlatform } // NewProductInfo 构造函数 func NewProductInfo(name string, price float64, platform DisplayPlatform) *ProductInfo { return &ProductInfo{ name: name, price: price, platform: platform, } } // ShowDetails 显示商品详细信息 func (p *ProductInfo) ShowDetails() { p.platform.ShowDetails(p.name, p.price) } func main() { // 创建商品并在 Web 端展示 webProduct := NewProductInfo("Laptop", 1200.00, &WebDisplay{}) webProduct.ShowDetails() // 创建商品并在移动端展示 mobileProduct := NewProductInfo("Laptop", 1200.00, &MobileDisplay{}) mobileProduct.ShowDetails() }
代码解释
- DisplayPlatform 接口:定义了
ShowDetails
方法,用于不同平台的展示方式。 - WebDisplay 和 MobileDisplay:具体实现了
DisplayPlatform
,分别表示 Web 和移动端的展示逻辑。 - ProductInfo:持有商品信息及展示平台的实例,通过桥接模式将展示平台与商品信息分离。
- ShowDetails:调用展示平台的
ShowDetails
方法,实现商品信息在不同平台的展示。
输出结果
↩Web Display -> Product: Laptop, Price: $1200.00 Mobile Display -> Product: Laptop, Price: $1200.00
- DisplayPlatform 接口:定义了
组合-go
下面是一个在 Go 中实现组合模式的简易代码示例,用于表示商品分类和子分类的树状结构,允许递归添加和显示分类。
package main import ( "fmt" ) // Category 表示一个商品分类接口,包含显示商品信息的方法 type Category interface { displayProducts(indent int) addSubCategory(subCategory Category) } // BaseCategory 基础分类结构,实现通用的分类显示逻辑 type BaseCategory struct { name string subCategories []Category } // addSubCategory 添加子分类 func (c *BaseCategory) addSubCategory(subCategory Category) { c.subCategories = append(c.subCategories, subCategory) } // displayProducts 显示分类及其子分类的商品信息 func (c *BaseCategory) displayProducts(indent int) { // 输出当前分类 fmt.Printf("%s- %s\n", indentSpaces(indent), c.name) // 递归输出子分类 for _, subCategory := range c.subCategories { subCategory.displayProducts(indent + 2) } } // indentSpaces 用于格式化输出的缩进 func indentSpaces(count int) string { return fmt.Sprintf("%*s", count, "") } // NewCategory 创建一个新的分类 func NewCategory(name string) *BaseCategory { return &BaseCategory{ name: name, subCategories: []Category{}, } } // MainCategory 顶级分类结构,继承自 BaseCategory type MainCategory struct { BaseCategory } // SubCategory 子分类结构,继承自 BaseCategory type SubCategory struct { BaseCategory } func main() { // 创建顶级分类和子分类 root := &MainCategory{*NewCategory("电子产品")} mobiles := &SubCategory{*NewCategory("手机")} laptops := &SubCategory{*NewCategory("笔记本电脑")} // 创建手机品牌子分类 apple := &SubCategory{*NewCategory("苹果")} samsung := &SubCategory{*NewCategory("三星")} // 创建笔记本电脑品牌子分类 dell := &SubCategory{*NewCategory("戴尔")} lenovo := &SubCategory{*NewCategory("联想")} // 构建分类树 root.addSubCategory(mobiles) root.addSubCategory(laptops) mobiles.addSubCategory(apple) mobiles.addSubCategory(samsung) laptops.addSubCategory(dell) laptops.addSubCategory(lenovo) // 显示所有分类 root.displayProducts(0) }
输出结果
运行该代码,将会输出以下商品分类结构:
- 电子产品 - 手机 - 苹果 - 三星 - 笔记本电脑 - 戴尔 - 联想
说明
-
Category
接口定义了基本的分类行为。 -
BaseCategory
实现了基础的分类显示和子分类管理。 -
MainCategory
和SubCategory
继承BaseCategory
,实现具体的分类实例。 -
displayProducts
方法递归调用,便于展示和管理嵌套的分类结构。 ↩
-
装饰-go
下面是一个在 Go 中实现装饰模式的简易代码示例,用于在商品详情页动态添加促销和折扣信息,以实现多样化的商品描述。
package main import ( "fmt" ) // Product 接口定义了商品的基本行为 type Product interface { getDescription() string } // BaseProduct 具体商品结构,实现基础的商品描述 type BaseProduct struct { name string price float64 description string } // getDescription 返回基础商品的描述 func (p *BaseProduct) getDescription() string { return fmt.Sprintf("%s: %.2f", p.name, p.price) } // NewBaseProduct 创建一个新的基础商品 func NewBaseProduct(name string, price float64, description string) *BaseProduct { return &BaseProduct{name: name, price: price, description: description} } // ProductDecorator 装饰器结构,持有一个 Product 对象 type ProductDecorator struct { product Product } // NewProductDecorator 创建一个新的装饰器 func NewProductDecorator(p Product) *ProductDecorator { return &ProductDecorator{product: p} } // PromotionalDecorator 促销装饰器 type PromotionalDecorator struct { ProductDecorator promotion string } // getDescription 返回带促销信息的商品描述 func (d *PromotionalDecorator) getDescription() string { return fmt.Sprintf("%s - 促销: %s", d.product.getDescription(), d.promotion) } // DiscountDecorator 折扣装饰器 type DiscountDecorator struct { ProductDecorator discount float64 } // getDescription 返回带折扣信息的商品描述 func (d *DiscountDecorator) getDescription() string { return fmt.Sprintf("%s - 折扣: %.2f%%", d.product.getDescription(), d.discount) } func main() { // 创建基础商品 product := NewBaseProduct("智能手机", 599.99, "最新款智能手机") // 添加促销装饰 promotionalProduct := &PromotionalDecorator{ ProductDecorator: ProductDecorator{product: product}, promotion: "限时特价", } // 添加折扣装饰 discountedProduct := &DiscountDecorator{ ProductDecorator: ProductDecorator{product: promotionalProduct}, discount: 15, } // 输出商品描述 fmt.Println(discountedProduct.getDescription()) }
输出结果
运行该代码,将会输出以下商品描述:
智能手机: 599.99 - 促销: 限时特价 - 折扣: 15.00%
说明
-
Product
接口定义了商品的基本行为。 -
BaseProduct
结构实现了基础商品的描述。 -
ProductDecorator
是装饰器的基础结构,持有一个Product
对象。 -
PromotionalDecorator
和DiscountDecorator
分别用于动态添加促销和折扣信息。 - 通过嵌套装饰器,可以灵活地组合不同的装饰功能而不修改基础商品对象。 ↩
-
外观-go
以下是一个在 Go 中实现外观模式的简易代码示例,用于简化用户下单时涉及的支付、库存和配送等模块的调用。
package main import ( "fmt" ) // PaymentService 支付服务 type PaymentService struct{} func (p *PaymentService) processPayment(amount float64) { fmt.Printf("支付处理: %.2f 元\n", amount) } // InventoryService 库存服务 type InventoryService struct{} func (i *InventoryService) checkInventory(productID int) bool { // 假设所有产品都有库存 fmt.Printf("检查库存: 产品ID %d - 库存充足\n", productID) return true } // ShippingService 配送服务 type ShippingService struct{} func (s *ShippingService) shipOrder(orderID int) { fmt.Printf("配送订单: 订单ID %d\n", orderID) } // OrderFacade 外观模式,简化下单流程 type OrderFacade struct { paymentService *PaymentService inventoryService *InventoryService shippingService *ShippingService } func NewOrderFacade() *OrderFacade { return &OrderFacade{ paymentService: &PaymentService{}, inventoryService: &InventoryService{}, shippingService: &ShippingService{}, } } // processOrder 处理下单流程 func (o *OrderFacade) processOrder(productID int, amount float64) { if o.inventoryService.checkInventory(productID) { o.paymentService.processPayment(amount) o.shippingService.shipOrder(productID) // 这里使用产品ID作为订单ID示例 fmt.Println("订单处理成功!") } else { fmt.Println("库存不足,无法处理订单.") } } func main() { orderFacade := NewOrderFacade() orderFacade.processOrder(101, 299.99) // 假设产品ID为101,支付299.99元 }
输出结果
运行该代码,将会输出以下内容:
检查库存: 产品ID 101 - 库存充足 支付处理: 299.99 元 配送订单: 订单ID 101 订单处理成功!
说明
-
PaymentService
、InventoryService
和ShippingService
分别代表支付、库存和配送的服务模块。 -
OrderFacade
是外观类,它将多个服务组合在一起,通过统一的processOrder
方法来简化客户端操作。 - 客户端只需要调用
OrderFacade
的processOrder
方法,而不需要了解内部服务的具体实现,从而简化了下单流程的复杂性。 ↩
-
享元-go
以下是一个在 Go 中实现享元模式的简易代码示例,用于共享商品图片资源,以避免内存浪费。
package main import ( "fmt" ) // ProductImage 享元类 type ProductImage struct { imagePath string } // NewProductImage 创建新的商品图片 func NewProductImage(imagePath string) *ProductImage { return &ProductImage{imagePath: imagePath} } // Display 显示商品图片 func (p *ProductImage) Display() { fmt.Printf("显示商品图片: %s\n", p.imagePath) } // ImageFactory 享元工厂 type ImageFactory struct { imageMap map[string]*ProductImage } // NewImageFactory 创建新的图片工厂 func NewImageFactory() *ImageFactory { return &ImageFactory{imageMap: make(map[string]*ProductImage)} } // GetImage 获取共享的商品图片 func (f *ImageFactory) GetImage(imagePath string) *ProductImage { // 如果图片已经存在,则返回共享的实例 if img, exists := f.imageMap[imagePath]; exists { return img } // 否则创建新的图片对象并存储 img := NewProductImage(imagePath) f.imageMap[imagePath] = img return img } // Client 客户端 type Client struct { factory *ImageFactory } // NewClient 创建新的客户端 func NewClient(factory *ImageFactory) *Client { return &Client{factory: factory} } // AddProductImage 添加商品图片 func (c *Client) AddProductImage(imagePath string) { image := c.factory.GetImage(imagePath) image.Display() } func main() { factory := NewImageFactory() client := NewClient(factory) // 使用相同的图片路径 client.AddProductImage("images/product1.jpg") client.AddProductImage("images/product2.jpg") client.AddProductImage("images/product1.jpg") // 共享同一图片 client.AddProductImage("images/product3.jpg") client.AddProductImage("images/product2.jpg") // 共享同一图片 }
输出结果
运行该代码,将会输出以下内容:
显示商品图片: images/product1.jpg 显示商品图片: images/product2.jpg 显示商品图片: images/product1.jpg 显示商品图片: images/product3.jpg 显示商品图片: images/product2.jpg
说明
-
ProductImage
类代表商品图片对象,其中包含imagePath
属性。 -
ImageFactory
是享元工厂,负责管理和共享ProductImage
实例。如果请求的图片路径已经存在,则返回已有的实例;否则,创建新的实例并存储。 -
Client
类代表客户端,它通过ImageFactory
来获取和显示商品图片。 - 运行时,通过添加相同的图片路径,可以看到同一图片对象被多次使用,这实现了享元模式的核心思想:通过共享相同的对象来节省内存。 ↩
-
代理-go
以下是一个在 Go 中实现代理模式的简易代码示例,用于控制用户的订单操作权限,如顾客只能查看订单状态,管理员可以取消订单。
package main import ( "fmt" ) // Order 订单类 type Order struct { ID int Status string } // OrderService 订单服务接口 type OrderService interface { ViewOrder(orderID int) string CancelOrder(orderID int) string } // RealOrderService 真实订单服务 type RealOrderService struct { orders map[int]*Order } // NewRealOrderService 创建新的真实订单服务 func NewRealOrderService() *RealOrderService { return &RealOrderService{ orders: map[int]*Order{ 1: {ID: 1, Status: "待发货"}, 2: {ID: 2, Status: "已发货"}, }, } } // ViewOrder 查看订单状态 func (s *RealOrderService) ViewOrder(orderID int) string { if order, exists := s.orders[orderID]; exists { return fmt.Sprintf("订单ID: %d,状态: %s", order.ID, order.Status) } return "订单不存在" } // CancelOrder 取消订单 func (s *RealOrderService) CancelOrder(orderID int) string { if order, exists := s.orders[orderID]; exists { order.Status = "已取消" return fmt.Sprintf("订单ID: %d,已取消", order.ID) } return "订单不存在" } // OrderProxy 代理类 type OrderProxy struct { realService *RealOrderService isAdmin bool } // NewOrderProxy 创建新的订单代理 func NewOrderProxy(realService *RealOrderService, isAdmin bool) *OrderProxy { return &OrderProxy{realService: realService, isAdmin: isAdmin} } // ViewOrder 查看订单状态 func (p *OrderProxy) ViewOrder(orderID int) string { return p.realService.ViewOrder(orderID) } // CancelOrder 取消订单 func (p *OrderProxy) CancelOrder(orderID int) string { if p.isAdmin { return p.realService.CancelOrder(orderID) } return "权限不足,无法取消订单" } // Client 客户端 type Client struct { orderService OrderService } // NewClient 创建新的客户端 func NewClient(orderService OrderService) *Client { return &Client{orderService: orderService} } // Main 函数 func main() { // 创建真实订单服务 realService := NewRealOrderService() // 创建代理,顾客用户 customerProxy := NewOrderProxy(realService, false) client1 := NewClient(customerProxy) fmt.Println(client1.orderService.ViewOrder(1)) // 顾客查看订单 fmt.Println(client1.orderService.CancelOrder(1)) // 顾客尝试取消订单 // 创建代理,管理员用户 adminProxy := NewOrderProxy(realService, true) client2 := NewClient(adminProxy) fmt.Println(client2.orderService.ViewOrder(2)) // 管理员查看订单 fmt.Println(client2.orderService.CancelOrder(2)) // 管理员取消订单 }
输出结果
运行该代码,将会输出以下内容:
订单ID: 1,状态: 待发货 权限不足,无法取消订单 订单ID: 2,状态: 已发货 订单ID: 2,已取消
说明
-
Order
类表示一个订单,包含订单 ID 和状态。 -
OrderService
接口定义了查看和取消订单的方法。 -
RealOrderService
实现了OrderService
接口,提供实际的订单处理逻辑。 -
OrderProxy
代理类用于控制对订单服务的访问。根据用户权限(普通用户或管理员),决定是否允许取消订单。 -
Client
类代表客户端,它使用代理来访问订单服务。 - 在主函数中,通过不同的代理实例展示了普通用户和管理员用户对订单的不同操作权限。 ↩
-
责任链-go
以下是一个在 Go 中实现责任链模式的简易代码示例,用于订单处理流程,依次经过库存检查、支付确认和配送等多个步骤。
package main import ( "fmt" ) // Order 订单类 type Order struct { ID int Amount float64 Stocked bool Paid bool } // OrderHandler 订单处理器接口 type OrderHandler interface { SetNext(handler OrderHandler) OrderHandler Handle(order *Order) bool } // BaseHandler 基础处理器 type BaseHandler struct { next OrderHandler } // SetNext 设置下一个处理器 func (h *BaseHandler) SetNext(handler OrderHandler) OrderHandler { h.next = handler return handler } // Handle 处理方法,留给子类实现 func (h *BaseHandler) Handle(order *Order) bool { if h.next != nil { return h.next.Handle(order) } return true } // StockCheckHandler 库存检查处理器 type StockCheckHandler struct { BaseHandler } // Handle 库存检查处理逻辑 func (h *StockCheckHandler) Handle(order *Order) bool { if order.Stocked { fmt.Printf("订单 %d 库存检查通过。\n", order.ID) return h.BaseHandler.Handle(order) } fmt.Printf("订单 %d 库存不足,处理失败。\n", order.ID) return false } // PaymentHandler 支付确认处理器 type PaymentHandler struct { BaseHandler } // Handle 支付确认逻辑 func (h *PaymentHandler) Handle(order *Order) bool { if order.Paid { fmt.Printf("订单 %d 支付确认通过。\n", order.ID) return h.BaseHandler.Handle(order) } fmt.Printf("订单 %d 支付未完成,处理失败。\n", order.ID) return false } // DeliveryHandler 配送处理器 type DeliveryHandler struct { BaseHandler } // Handle 配送逻辑 func (h *DeliveryHandler) Handle(order *Order) bool { fmt.Printf("订单 %d 配送中...\n", order.ID) return h.BaseHandler.Handle(order) } // Main 函数 func main() { // 创建订单 order := &Order{ ID: 1, Amount: 100.0, Stocked: true, Paid: true, } // 创建责任链 stockCheck := &StockCheckHandler{} payment := &PaymentHandler{} delivery := &DeliveryHandler{} // 设置责任链 stockCheck.SetNext(payment).SetNext(delivery) // 开始处理订单 fmt.Println("处理订单...") stockCheck.Handle(order) }
输出结果
运行该代码,将会输出以下内容:
处理订单... 订单 1 库存检查通过。 订单 1 支付确认通过。 订单 1 配送中...
说明
-
Order
类表示一个订单,包含订单 ID、金额、库存状态和支付状态。 -
OrderHandler
接口定义了责任链中的处理器方法,包括设置下一个处理器和处理订单的逻辑。 -
BaseHandler
是一个基础处理器,负责管理责任链中的下一个处理器。 -
StockCheckHandler
、PaymentHandler
和DeliveryHandler
分别实现了库存检查、支付确认和配送的处理逻辑。 - 在主函数中,创建一个订单和责任链,依次调用处理器进行订单处理。通过责任链模式,可以灵活地调整和扩展处理步骤。
4o mini ↩
-
命令-go
以下是一个在 Go 中实现命令模式的简易代码示例,使用
CartCommand
类来管理用户的购物车操作,包括添加商品和移除商品的操作,并支持撤销和重做功能。package main import ( "fmt" ) // Command 接口定义了命令的基本方法 type Command interface { Execute() Undo() } // Product 商品类 type Product struct { Name string Price float64 } // Cart 购物车类 type Cart struct { Items []Product } // AddProductCommand 添加商品命令 type AddProductCommand struct { Cart *Cart Product Product } // Execute 执行添加商品命令 func (c *AddProductCommand) Execute() { c.Cart.Items = append(c.Cart.Items, c.Product) fmt.Printf("添加商品: %s\n", c.Product.Name) } // Undo 撤销添加商品命令 func (c *AddProductCommand) Undo() { c.Cart.Items = c.Cart.Items[:len(c.Cart.Items)-1] fmt.Printf("撤销添加商品: %s\n", c.Product.Name) } // RemoveProductCommand 移除商品命令 type RemoveProductCommand struct { Cart *Cart Product Product } // Execute 执行移除商品命令 func (c *RemoveProductCommand) Execute() { for i, item := range c.Cart.Items { if item.Name == c.Product.Name { c.Cart.Items = append(c.Cart.Items[:i], c.Cart.Items[i+1:]...) fmt.Printf("移除商品: %s\n", c.Product.Name) break } } } // Undo 撤销移除商品命令 func (c *RemoveProductCommand) Undo() { c.Cart.Items = append(c.Cart.Items, c.Product) fmt.Printf("撤销移除商品: %s\n", c.Product.Name) } // Invoker 命令调用者 type Invoker struct { commands []Command } // ExecuteCommand 执行命令 func (i *Invoker) ExecuteCommand(command Command) { command.Execute() i.commands = append(i.commands, command) } // UndoCommand 撤销最后一个命令 func (i *Invoker) UndoCommand() { if len(i.commands) > 0 { lastCommand := i.commands[len(i.commands)-1] lastCommand.Undo() i.commands = i.commands[:len(i.commands)-1] } } // Main 函数 func main() { cart := &Cart{} invoker := &Invoker{} // 创建并执行添加商品命令 addProduct1 := &AddProductCommand{Cart: cart, Product: Product{Name: "商品A", Price: 100.0}} invoker.ExecuteCommand(addProduct1) addProduct2 := &AddProductCommand{Cart: cart, Product: Product{Name: "商品B", Price: 200.0}} invoker.ExecuteCommand(addProduct2) // 创建并执行移除商品命令 removeProduct := &RemoveProductCommand{Cart: cart, Product: Product{Name: "商品A", Price: 100.0}} invoker.ExecuteCommand(removeProduct) // 撤销最后一个命令(移除商品A) invoker.UndoCommand() // 输出购物车当前状态 fmt.Println("购物车商品列表:") for _, item := range cart.Items { fmt.Printf("商品: %s, 价格: %.2f\n", item.Name, item.Price) } }
输出结果
运行该代码,将会输出以下内容:
添加商品: 商品A 添加商品: 商品B 移除商品: 商品A 撤销移除商品: 商品A 购物车商品列表: 商品: 商品A, 价格: 100.00 商品: 商品B, 价格: 200.00
说明
-
Command
接口定义了命令的基本方法Execute()
和Undo()
。 -
Product
类表示一个商品,包含商品名称和价格。 -
Cart
类表示购物车,包含商品列表。 -
AddProductCommand
和RemoveProductCommand
分别实现了添加和移除商品的命令。 -
Invoker
类用于执行命令并维护已执行命令的列表,以支持撤销操作。 - 在主函数中,创建一个购物车和命令调用者,执行添加和移除商品的命令,并进行撤销操作,最终输出购物车的当前状态。 ↩
-
迭代器-go
以下是一个在 Go 中实现迭代器模式的简易代码示例,使用
ProductIterator
类来迭代商品列表,以支持浏览商品的操作。package main import "fmt" // Product 商品类 type Product struct { Name string Price float64 } // ProductCollection 商品集合接口 type ProductCollection interface { CreateIterator() Iterator } // Iterator 迭代器接口 type Iterator interface { Next() *Product HasNext() bool } // ProductList 商品列表 type ProductList struct { products []Product } // CreateIterator 创建商品迭代器 func (p *ProductList) CreateIterator() Iterator { return &ProductIterator{ products: p.products, index: 0, } } // ProductIterator 商品迭代器 type ProductIterator struct { products []Product index int } // HasNext 判断是否还有下一个商品 func (pi *ProductIterator) HasNext() bool { return pi.index < len(pi.products) } // Next 获取下一个商品 func (pi *ProductIterator) Next() *Product { if pi.HasNext() { product := &pi.products[pi.index] pi.index++ return product } return nil } // Main 函数 func main() { // 创建商品列表 productList := &ProductList{ products: []Product{ {Name: "商品A", Price: 100.0}, {Name: "商品B", Price: 200.0}, {Name: "商品C", Price: 300.0}, }, } // 创建迭代器 iterator := productList.CreateIterator() // 遍历商品列表 fmt.Println("商品列表:") for iterator.HasNext() { product := iterator.Next() fmt.Printf("商品名称: %s, 价格: %.2f\n", product.Name, product.Price) } }
输出结果
运行该代码,将会输出以下内容:
商品列表: 商品名称: 商品A, 价格: 100.00 商品名称: 商品B, 价格: 200.00 商品名称: 商品C, 价格: 300.00
说明
-
Product
类表示一个商品,包含商品名称和价格。 -
ProductCollection
接口定义了创建迭代器的方法。 -
Iterator
接口定义了Next()
和HasNext()
方法。 -
ProductList
实现了ProductCollection
接口,并包含商品列表。 -
ProductIterator
实现了Iterator
接口,用于迭代ProductList
中的商品。 - 在主函数中,创建一个商品列表和相应的迭代器,遍历商品并输出每个商品的名称和价格。 ↩
-
中介者-go
以下是一个在 Go 中实现中介者模式的简易代码示例,使用
CheckoutMediator
类来协调支付、库存和物流模块的交互,从而避免直接耦合。package main import "fmt" // Mediator 中介者接口 type Mediator interface { Notify(colleague Colleague, event string) } // Colleague 同事接口 type Colleague interface { SetMediator(mediator Mediator) } // Payment 支付模块 type Payment struct { mediator Mediator } func (p *Payment) SetMediator(mediator Mediator) { p.mediator = mediator } func (p *Payment) ProcessPayment() { fmt.Println("处理支付...") p.mediator.Notify(p, "payment_processed") } // Inventory 库存模块 type Inventory struct { mediator Mediator } func (i *Inventory) SetMediator(mediator Mediator) { i.mediator = mediator } func (i *Inventory) UpdateInventory() { fmt.Println("更新库存...") i.mediator.Notify(i, "inventory_updated") } // Logistics 物流模块 type Logistics struct { mediator Mediator } func (l *Logistics) SetMediator(mediator Mediator) { l.mediator = mediator } func (l *Logistics) ShipOrder() { fmt.Println("发货中...") } // CheckoutMediator 结算中介者 type CheckoutMediator struct { payment *Payment inventory *Inventory logistics *Logistics } // Notify 通知各模块 func (cm *CheckoutMediator) Notify(colleague Colleague, event string) { switch event { case "payment_processed": cm.inventory.UpdateInventory() cm.logistics.ShipOrder() case "inventory_updated": fmt.Println("库存已更新,准备发货。") } } // Main 函数 func main() { // 创建中介者和模块 mediator := &CheckoutMediator{} payment := &Payment{} inventory := &Inventory{} logistics := &Logistics{} // 设置中介者 payment.SetMediator(mediator) inventory.SetMediator(mediator) logistics.SetMediator(mediator) // 将模块添加到中介者 mediator.payment = payment mediator.inventory = inventory mediator.logistics = logistics // 模拟订单结算流程 payment.ProcessPayment() }
输出结果
运行该代码,将会输出以下内容:
处理支付... 更新库存... 发货中... 库存已更新,准备发货。
说明
-
Mediator
接口定义了通知方法,用于协调各模块的交互。 -
Colleague
接口定义了设置中介者的方法。 -
Payment
、Inventory
和Logistics
分别表示支付、库存和物流模块,实现了Colleague
接口,并通过中介者与其他模块交互。 -
CheckoutMediator
实现了Mediator
接口,负责协调各模块的行为。 - 在主函数中,创建中介者和模块实例,设置中介者,并模拟订单结算过程,通过支付模块触发流程,其他模块随之执行。 ↩
-
备忘录-go
以下是一个在 Go 中实现备忘录模式的简易代码示例,使用
OrderStateMemento
类来保存和恢复订单的状态,以便在用户修改订单时进行回退或恢复操作。package main import "fmt" // Memento 备忘录类 type Memento struct { state string } // Order 订单类 type Order struct { state string } // Save 保存当前状态到备忘录 func (o *Order) Save() *Memento { fmt.Println("保存当前订单状态:", o.state) return &Memento{state: o.state} } // Restore 从备忘录恢复状态 func (o *Order) Restore(m *Memento) { o.state = m.state fmt.Println("恢复订单状态:", o.state) } // SetState 设置订单状态 func (o *Order) SetState(state string) { o.state = state fmt.Println("订单状态更新为:", o.state) } // Main 函数 func main() { // 创建订单实例 order := &Order{} // 修改订单状态并保存 order.SetState("已创建") memento1 := order.Save() order.SetState("已支付") memento2 := order.Save() order.SetState("已发货") // 恢复至之前状态 order.Restore(memento2) // 恢复至“已支付”状态 order.Restore(memento1) // 恢复至“已创建”状态 }
输出结果
运行该代码,将会输出以下内容:
订单状态更新为: 已创建 保存当前订单状态: 已创建 订单状态更新为: 已支付 保存当前订单状态: 已支付 订单状态更新为: 已发货 恢复订单状态: 已支付 恢复订单状态: 已创建
说明
-
Memento
类用于保存订单的状态。 -
Order
类表示订单,包含当前状态,并提供保存和恢复状态的方法。 -
Save()
方法将当前状态保存到备忘录中,返回Memento
对象。 -
Restore()
方法从Memento
对象中恢复状态。 -
SetState()
方法用于更新订单状态。 - 在主函数中,创建订单实例,修改状态并保存,之后恢复至之前的状态,展示了备忘录模式的应用。 ↩
-
观察者-go
以下是一个在 Go 中实现观察者模式的简易代码示例,使用
OrderStatusObserver
类来观察订单状态的变化,并在状态更新时通知用户和物流系统。package main import ( "fmt" ) // Observer 观察者接口 type Observer interface { update(orderID string, status string) } // Subject 主题接口 type Subject interface { registerObserver(o Observer) removeObserver(o Observer) notifyObservers() } // Order 订单类 type Order struct { observers []Observer orderID string status string } // NewOrder 创建新订单 func NewOrder(orderID string) *Order { return &Order{ orderID: orderID, } } // registerObserver 注册观察者 func (o *Order) registerObserver(observer Observer) { o.observers = append(o.observers, observer) } // removeObserver 移除观察者 func (o *Order) removeObserver(observer Observer) { for i, obs := range o.observers { if obs == observer { o.observers = append(o.observers[:i], o.observers[i+1:]...) break } } } // notifyObservers 通知所有观察者 func (o *Order) notifyObservers() { for _, observer := range o.observers { observer.update(o.orderID, o.status) } } // UpdateStatus 更新订单状态并通知观察者 func (o *Order) UpdateStatus(status string) { o.status = status fmt.Printf("订单 %s 状态更新为: %s\n", o.orderID, status) o.notifyObservers() } // User 用户观察者 type User struct { name string } // update 用户更新通知 func (u *User) update(orderID string, status string) { fmt.Printf("用户 %s 收到通知: 订单 %s 状态更新为: %s\n", u.name, orderID, status) } // Logistics 物流观察者 type Logistics struct{} // update 物流系统更新通知 func (l *Logistics) update(orderID string, status string) { fmt.Printf("物流系统收到通知: 订单 %s 状态更新为: %s\n", orderID, status) } // Main 函数 func main() { // 创建订单实例 order := NewOrder("12345") // 创建用户和物流实例 user1 := &User{name: "Alice"} user2 := &User{name: "Bob"} logistics := &Logistics{} // 注册观察者 order.registerObserver(user1) order.registerObserver(user2) order.registerObserver(logistics) // 更新订单状态 order.UpdateStatus("已发货") order.UpdateStatus("已送达") }
输出结果
运行该代码,将会输出以下内容:
订单 12345 状态更新为: 已发货 用户 Alice 收到通知: 订单 12345 状态更新为: 已发货 用户 Bob 收到通知: 订单 12345 状态更新为: 已发货 物流系统收到通知: 订单 12345 状态更新为: 已发货 订单 12345 状态更新为: 已送达 用户 Alice 收到通知: 订单 12345 状态更新为: 已送达 用户 Bob 收到通知: 订单 12345 状态更新为: 已送达 物流系统收到通知: 订单 12345 状态更新为: 已送达
说明
-
Observer
接口定义了观察者应实现的update()
方法,用于接收状态更新通知。 -
Subject
接口定义了主题的方法,包括注册、移除和通知观察者。 -
Order
类实现了Subject
接口,维护观察者列表,并在状态更新时通知所有观察者。 -
User
和Logistics
类实现了Observer
接口,分别表示用户和物流系统。 - 在主函数中,创建订单实例、用户和物流观察者,注册观察者,并在更新订单状态时通知所有观察者,展示了观察者模式的应用。 ↩
-
状态-go
以下是一个在 Go 中实现状态模式的简易代码示例,使用
OrderState
类来管理订单的不同状态(如已下单、已发货、已收货、完成)。package main import ( "fmt" ) // OrderState 订单状态接口 type OrderState interface { nextState(order *Order) getStatus() string } // Order 订单结构 type Order struct { state OrderState } // NewOrder 创建新订单,初始状态为已下单 func NewOrder() *Order { order := &Order{} order.setState(&OrderedState{}) // 初始状态 return order } // setState 设置订单状态 func (o *Order) setState(state OrderState) { o.state = state fmt.Printf("订单状态更新为: %s\n", o.state.getStatus()) } // nextState 触发状态转移 func (o *Order) nextState() { o.state.nextState(o) } // OrderedState 已下单状态 type OrderedState struct{} // nextState 处理状态转移逻辑 func (s *OrderedState) nextState(order *Order) { order.setState(&ShippedState{}) // 转换为已发货状态 } // getStatus 获取当前状态 func (s *OrderedState) getStatus() string { return "已下单" } // ShippedState 已发货状态 type ShippedState struct{} // nextState 处理状态转移逻辑 func (s *ShippedState) nextState(order *Order) { order.setState(&DeliveredState{}) // 转换为已收货状态 } // getStatus 获取当前状态 func (s *ShippedState) getStatus() string { return "已发货" } // DeliveredState 已收货状态 type DeliveredState struct{} // nextState 处理状态转移逻辑 func (s *DeliveredState) nextState(order *Order) { order.setState(&CompletedState{}) // 转换为完成状态 } // getStatus 获取当前状态 func (s *DeliveredState) getStatus() string { return "已收货" } // CompletedState 完成状态 type CompletedState struct{} // nextState 处理状态转移逻辑 func (s *CompletedState) nextState(order *Order) { fmt.Println("订单已完成,无法转移到其他状态。") } // getStatus 获取当前状态 func (s *CompletedState) getStatus() string { return "已完成" } // Main 函数 func main() { order := NewOrder() // 创建新订单 // 触发状态转移 order.nextState() // 已下单 -> 已发货 order.nextState() // 已发货 -> 已收货 order.nextState() // 已收货 -> 已完成 order.nextState() // 已完成 -> 不再转移 }
输出结果
运行该代码,将会输出以下内容:
订单状态更新为: 已下单 订单状态更新为: 已发货 订单状态更新为: 已收货 订单状态更新为: 已完成 订单已完成,无法转移到其他状态。
说明
-
OrderState
接口定义了状态的行为,包括nextState()
方法用于处理状态转移,以及getStatus()
方法用于获取当前状态的描述。 -
Order
类代表一个订单,维护当前状态,并提供方法以触发状态转移。 - 每个具体状态(如
OrderedState
、ShippedState
、DeliveredState
和CompletedState
)实现了OrderState
接口,封装了状态转移的逻辑。 - 在主函数中,创建新订单并依次触发状态转移,展示了状态模式的应用,确保状态变化符合业务规则。 ↩
-
策略-go
以下是一个在 Go 中实现策略模式的简易代码示例,使用
DiscountStrategy
类来动态选择不同的折扣策略(如满减、折扣、赠品)进行商品折扣计算。package main import ( "fmt" ) // DiscountStrategy 折扣策略接口 type DiscountStrategy interface { applyDiscount(price float64) float64 } // FullReductionStrategy 满减策略 type FullReductionStrategy struct { threshold float64 // 满足条件的金额 reduction float64 // 减去的金额 } // applyDiscount 实现满减策略 func (s *FullReductionStrategy) applyDiscount(price float64) float64 { if price >= s.threshold { return price - s.reduction } return price } // PercentageDiscountStrategy 折扣策略 type PercentageDiscountStrategy struct { percentage float64 // 折扣百分比 } // applyDiscount 实现折扣策略 func (s *PercentageDiscountStrategy) applyDiscount(price float64) float64 { return price * (1 - s.percentage/100) } // GiftStrategy 赠品策略 type GiftStrategy struct { giftValue float64 // 赠品的价值 } // applyDiscount 实现赠品策略 func (s *GiftStrategy) applyDiscount(price float64) float64 { return price // 赠品策略不影响商品价格 } // ShoppingCart 购物车结构 type ShoppingCart struct { price float64 // 商品价格 strategy DiscountStrategy // 当前使用的折扣策略 } // NewShoppingCart 创建购物车 func NewShoppingCart(price float64, strategy DiscountStrategy) *ShoppingCart { return &ShoppingCart{price: price, strategy: strategy} } // SetStrategy 设置新的折扣策略 func (c *ShoppingCart) SetStrategy(strategy DiscountStrategy) { c.strategy = strategy } // CalculateFinalPrice 计算最终价格 func (c *ShoppingCart) CalculateFinalPrice() float64 { return c.strategy.applyDiscount(c.price) } // Main 函数 func main() { // 创建一个购物车,初始价格为100 cart := NewShoppingCart(100, &FullReductionStrategy{threshold: 80, reduction: 20}) fmt.Printf("最终价格(满减策略): %.2f\n", cart.CalculateFinalPrice()) // 应用满减策略 // 更改策略为百分比折扣 cart.SetStrategy(&PercentageDiscountStrategy{percentage: 10}) fmt.Printf("最终价格(折扣策略): %.2f\n", cart.CalculateFinalPrice()) // 应用折扣策略 // 更改策略为赠品 cart.SetStrategy(&GiftStrategy{giftValue: 5}) fmt.Printf("最终价格(赠品策略): %.2f\n", cart.CalculateFinalPrice()) // 赠品策略 }
输出结果
运行该代码,将会输出以下内容:
最终价格(满减策略): 80.00 最终价格(折扣策略): 90.00 最终价格(赠品策略): 100.00
说明
-
DiscountStrategy
接口定义了折扣策略的行为,包括applyDiscount()
方法用于计算折扣后的价格。 -
FullReductionStrategy
、PercentageDiscountStrategy
和GiftStrategy
是具体的折扣策略,实现了DiscountStrategy
接口。 -
ShoppingCart
结构代表购物车,包含商品价格和当前使用的折扣策略,提供方法以设置策略和计算最终价格。 - 在主函数中,创建购物车并依次使用不同的折扣策略进行价格计算,展示了策略模式的应用,使得可以灵活选择和更改折扣策略。 ↩
-
模板方法-go
以下是一个在 Go 中实现模板方法模式的简易代码示例,使用
OrderProcessingTemplate
类来定义订单处理的模板方法,不同类型的订单(如虚拟商品、实物商品)可以复用通用流程并在特定步骤进行自定义。package main import ( "fmt" ) // OrderProcessingTemplate 订单处理模板 type OrderProcessingTemplate struct{} // Process 定义订单处理的模板方法 func (t *OrderProcessingTemplate) Process() { t.validateOrder() t.prepareOrder() t.processPayment() t.shipOrder() } // ValidateOrder 验证订单 func (t *OrderProcessingTemplate) validateOrder() { fmt.Println("验证订单...") } // PrepareOrder 准备订单,留给子类实现 func (t *OrderProcessingTemplate) prepareOrder() { fmt.Println("准备订单...") } // ProcessPayment 处理支付 func (t *OrderProcessingTemplate) processPayment() { fmt.Println("处理支付...") } // ShipOrder 发货,留给子类实现 func (t *OrderProcessingTemplate) shipOrder() { fmt.Println("发货...") } // VirtualProductOrder 虚拟商品订单 type VirtualProductOrder struct { OrderProcessingTemplate } // PrepareOrder 实现虚拟商品订单的准备逻辑 func (v *VirtualProductOrder) prepareOrder() { fmt.Println("准备虚拟商品...") } // ShipOrder 实现虚拟商品订单的发货逻辑 func (v *VirtualProductOrder) shipOrder() { fmt.Println("虚拟商品通过电子邮件发送...") } // PhysicalProductOrder 实物商品订单 type PhysicalProductOrder struct { OrderProcessingTemplate } // PrepareOrder 实现实物商品订单的准备逻辑 func (p *PhysicalProductOrder) prepareOrder() { fmt.Println("准备实物商品...") } // ShipOrder 实现实物商品订单的发货逻辑 func (p *PhysicalProductOrder) shipOrder() { fmt.Println("实物商品通过快递发货...") } // Main 函数 func main() { // 处理虚拟商品订单 virtualOrder := &VirtualProductOrder{} fmt.Println("处理虚拟商品订单:") virtualOrder.Process() fmt.Println() // 处理实物商品订单 physicalOrder := &PhysicalProductOrder{} fmt.Println("处理实物商品订单:") physicalOrder.Process() }
输出结果
运行该代码,将会输出以下内容:
处理虚拟商品订单: 验证订单... 准备虚拟商品... 处理支付... 虚拟商品通过电子邮件发送... 处理实物商品订单: 验证订单... 准备实物商品... 处理支付... 实物商品通过快递发货...
说明
-
OrderProcessingTemplate
定义了一个模板方法Process
,其中包含订单处理的通用流程,涉及验证订单、准备订单、处理支付和发货等步骤。 -
prepareOrder()
和shipOrder()
方法在模板中被定义为留给子类实现的抽象方法,以便在不同类型的订单中进行自定义。 -
VirtualProductOrder
和PhysicalProductOrder
是具体的订单类型,分别实现了订单的准备和发货逻辑。 - 在主函数中,创建虚拟商品订单和实物商品订单的实例,并调用
Process
方法进行订单处理,展示了模板方法的使用,使得可以复用通用的处理逻辑并在特定步骤自定义。 ↩
-
访问者-go
以下是一个在 Go 中实现访问者模式的简易代码示例,使用
ReportVisitor
类来访问订单和客户信息,执行不同的统计分析逻辑。package main import "fmt" // Visitable 接口 type Visitable interface { Accept(visitor Visitor) } // Visitor 接口 type Visitor interface { visitOrder(order *Order) visitCustomer(customer *Customer) } // Order 订单结构体 type Order struct { ID int Amount float64 } // Accept 方法接受访问者 func (o *Order) Accept(visitor Visitor) { visitor.visitOrder(o) } // Customer 客户结构体 type Customer struct { ID int Name string } // Accept 方法接受访问者 func (c *Customer) Accept(visitor Visitor) { visitor.visitCustomer(c) } // ReportVisitor 实现 Visitor 接口 type ReportVisitor struct { TotalAmount float64 CustomerCount int } // visitOrder 访问订单 func (v *ReportVisitor) visitOrder(order *Order) { v.TotalAmount += order.Amount fmt.Printf("访问订单 ID: %d, 金额: %.2f\n", order.ID, order.Amount) } // visitCustomer 访问客户 func (v *ReportVisitor) visitCustomer(customer *Customer) { v.CustomerCount++ fmt.Printf("访问客户 ID: %d, 名称: %s\n", customer.ID, customer.Name) } // Main 函数 func main() { // 创建订单和客户 orders := []*Order{ {ID: 1, Amount: 100.50}, {ID: 2, Amount: 200.75}, } customers := []*Customer{ {ID: 1, Name: "Alice"}, {ID: 2, Name: "Bob"}, } // 创建报告访问者 reportVisitor := &ReportVisitor{} // 访问订单 for _, order := range orders { order.Accept(reportVisitor) } // 访问客户 for _, customer := range customers { customer.Accept(reportVisitor) } // 输出统计结果 fmt.Printf("总订单金额: %.2f\n", reportVisitor.TotalAmount) fmt.Printf("客户数量: %d\n", reportVisitor.CustomerCount) }
输出结果
运行该代码将会输出以下内容:
访问订单 ID: 1, 金额: 100.50 访问订单 ID: 2, 金额: 200.75 访问客户 ID: 1, 名称: Alice 访问客户 ID: 2, 名称: Bob 总订单金额: 301.25 客户数量: 2
说明
-
Visitable
接口定义了接受访问者的方法Accept
,用于让访问者访问对象。 -
Visitor
接口包含两个方法:visitOrder
和visitCustomer
,分别用于访问订单和客户。 -
Order
和Customer
结构体实现了Visitable
接口,并在Accept
方法中调用访问者的对应方法。 -
ReportVisitor
实现了Visitor
接口,包含了统计总金额和客户数量的逻辑。 - 在主函数中,创建了一些订单和客户的实例,并通过
ReportVisitor
对其进行访问,最终输出统计结果。 - 这种设计模式的好处在于能够通过扩展访问者的方式,轻松地为不同类型的数据添加新的操作,而无需修改数据结构本身。 ↩
-
欢迎来到这里!
我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。
注册 关于