【场景实战】【设计模式】【go】以电商系统为例讲述设计模式在项目中的应用
·
本文以电商系统为例讲述设计模式在项目中的应用
在面试时经常会被问到项目中设计模式的使用情况,以及自己在开发时也会纠结如何在项目正确使用设计模式,今天就以大家都熟知的电商系统为例,简述一下系统中如何使用常见设计模式的场景。并用Go语言实现相应的示例代码。
1. 工厂模式 - 创建不同支付方式
package main
import "fmt"
// PaymentMethod 支付接口
type PaymentMethod interface {
Pay(amount float64) string
}
// 具体支付方式
type Alipay struct{}
func (a *Alipay) Pay(amount float64) string {
return fmt.Sprintf("支付宝支付: %.2f 元", amount)
}
type WechatPay struct{}
func (w *WechatPay) Pay(amount float64) string {
return fmt.Sprintf("微信支付: %.2f 元", amount)
}
type CreditCard struct{}
func (c *CreditCard) Pay(amount float64) string {
return fmt.Sprintf("信用卡支付: %.2f 元", amount)
}
// PaymentMethodType 支付类型
type PaymentMethodType int
const (
AlipayType PaymentMethodType = iota
WechatPayType
CreditCardType
)
// PaymentFactory 支付工厂
func PaymentFactory(methodType PaymentMethodType) PaymentMethod {
switch methodType {
case AlipayType:
return &Alipay{}
case WechatPayType:
return &WechatPay{}
case CreditCardType:
return &CreditCard{}
default:
return nil
}
}
func main() {
// 使用工厂创建支付方式
payment := PaymentFactory(AlipayType)
fmt.Println(payment.Pay(100.50))
payment = PaymentFactory(WechatPayType)
fmt.Println(payment.Pay(200.00))
}
2. 单例模式 - 配置管理器
package main
import (
"fmt"
"sync"
)
// Config 配置结构
type Config struct {
DatabaseURL string
Port string
APIKey string
}
var (
instance *Config
once sync.Once
)
// GetConfig 获取配置单例
func GetConfig() *Config {
once.Do(func() {
instance = &Config{
DatabaseURL: "localhost:3306/ecommerce",
Port: "8080",
APIKey: "abc123xyz",
}
})
return instance
}
func main() {
config1 := GetConfig()
config2 := GetConfig()
fmt.Println("配置相同:", config1 == config2)
fmt.Printf("数据库地址: %s\n", config1.DatabaseURL)
}
3. 观察者模式 - 订单状态通知
package main
import "fmt"
// Observer 观察者接口
type Observer interface {
Update(orderID string, status string)
}
// Subject 主题接口
type Subject interface {
Register(observer Observer)
Remove(observer Observer)
NotifyAll()
}
// Order 订单主题
type Order struct {
observers []Observer
ID string
Status string
}
func (o *Order) Register(observer Observer) {
o.observers = append(o.observers, observer)
}
func (o *Order) Remove(observer Observer) {
for i, obs := range o.observers {
if obs == observer {
o.observers = append(o.observers[:i], o.observers[i+1:]...)
break
}
}
}
func (o *Order) NotifyAll() {
for _, observer := range o.observers {
observer.Update(o.ID, o.Status)
}
}
func (o *Order) UpdateStatus(status string) {
o.Status = status
o.NotifyAll()
}
// 具体观察者
type CustomerNotifier struct{}
func (c *CustomerNotifier) Update(orderID string, status string) {
fmt.Printf("客户通知: 订单 %s 状态更新为 %s\n", orderID, status)
}
type LogisticsNotifier struct{}
func (l *LogisticsNotifier) Update(orderID string, status string) {
fmt.Printf("物流通知: 订单 %s 状态更新为 %s\n", orderID, status)
}
func main() {
order := &Order{ID: "ORD12345"}
// 注册观察者
order.Register(&CustomerNotifier{})
order.Register(&LogisticsNotifier{})
// 更新状态并通知
order.UpdateStatus("已付款")
order.UpdateStatus("已发货")
}
4. 策略模式 - 折扣计算
package main
import "fmt"
// DiscountStrategy 折扣策略接口
type DiscountStrategy interface {
Calculate(price float64) float64
}
// 具体策略
type NoDiscount struct{}
func (n *NoDiscount) Calculate(price float64) float64 {
return price
}
type PercentageDiscount struct {
percentage float64
}
func (p *PercentageDiscount) Calculate(price float64) float64 {
return price * (1 - p.percentage/100)
}
type FixedDiscount struct {
amount float64
}
func (f *FixedDiscount) Calculate(price float64) float64 {
result := price - f.amount
if result < 0 {
return 0
}
return result
}
// DiscountContext 折扣上下文
type DiscountContext struct {
strategy DiscountStrategy
}
func (d *DiscountContext) SetStrategy(strategy DiscountStrategy) {
d.strategy = strategy
}
func (d *DiscountContext) ApplyDiscount(price float64) float64 {
return d.strategy.Calculate(price)
}
func main() {
context := &DiscountContext{}
// 无折扣
context.SetStrategy(&NoDiscount{})
fmt.Printf("无折扣: %.2f\n", context.ApplyDiscount(100))
// 8折
context.SetStrategy(&PercentageDiscount{percentage: 20})
fmt.Printf("8折: %.2f\n", context.ApplyDiscount(100))
// 满减
context.SetStrategy(&FixedDiscount{amount: 30})
fmt.Printf("满减30: %.2f\n", context.ApplyDiscount(100))
}
5. 装饰器模式 - 商品添加功能
package main
import "fmt"
// Product 商品接口
type Product interface {
GetDescription() string
GetPrice() float64
}
// BasicProduct 基础商品
type BasicProduct struct {
name string
price float64
}
func (b *BasicProduct) GetDescription() string {
return b.name
}
func (b *BasicProduct) GetPrice() float64 {
return b.price
}
// ProductDecorator 商品装饰器
type ProductDecorator struct {
product Product
}
func (p *ProductDecorator) GetDescription() string {
return p.product.GetDescription()
}
func (p *ProductDecorator) GetPrice() float64 {
return p.product.GetPrice()
}
// 具体装饰器
type GiftWrapDecorator struct {
ProductDecorator
}
func (g *GiftWrapDecorator) GetDescription() string {
return g.product.GetDescription() + " + 礼品包装"
}
func (g *GiftWrapDecorator) GetPrice() float64 {
return g.product.GetPrice() + 5.0
}
type ExpressDeliveryDecorator struct {
ProductDecorator
}
func (e *ExpressDeliveryDecorator) GetDescription() string {
return e.product.GetDescription() + " + 快递配送"
}
func (e *ExpressDeliveryDecorator) GetPrice() float64 {
return e.product.GetPrice() + 15.0
}
func main() {
// 基础商品
product := &BasicProduct{name: "手机", price: 2999.0}
fmt.Printf("%s, 价格: %.2f\n", product.GetDescription(), product.GetPrice())
// 添加礼品包装
giftWrapped := &GiftWrapDecorator{ProductDecorator{product}}
fmt.Printf("%s, 价格: %.2f\n", giftWrapped.GetDescription(), giftWrapped.GetPrice())
// 添加快递配送
expressDelivered := &ExpressDeliveryDecorator{ProductDecorator{giftWrapped}}
fmt.Printf("%s, 价格: %.2f\n", expressDelivered.GetDescription(), expressDelivered.GetPrice())
}
6. 仓储模式 - 数据访问层
package main
import "fmt"
// User 用户模型
type User struct {
ID int
Name string
Email string
}
// UserRepository 用户仓储接口
type UserRepository interface {
FindByID(id int) (*User, error)
Save(user *User) error
Delete(id int) error
}
// InMemoryUserRepository 内存用户仓储
type InMemoryUserRepository struct {
users map[int]*User
}
func NewInMemoryUserRepository() *InMemoryUserRepository {
return &InMemoryUserRepository{
users: make(map[int]*User),
}
}
func (r *InMemoryUserRepository) FindByID(id int) (*User, error) {
user, exists := r.users[id]
if !exists {
return nil, fmt.Errorf("用户不存在")
}
return user, nil
}
func (r *InMemoryUserRepository) Save(user *User) error {
r.users[user.ID] = user
return nil
}
func (r *InMemoryUserRepository) Delete(id int) error {
delete(r.users, id)
return nil
}
func main() {
repo := NewInMemoryUserRepository()
// 保存用户
user := &User{ID: 1, Name: "张三", Email: "zhangsan@example.com"}
repo.Save(user)
// 查找用户
foundUser, _ := repo.FindByID(1)
fmt.Printf("找到用户: %s, 邮箱: %s\n", foundUser.Name, foundUser.Email)
}
7. 责任链模式 - 订单处理流程
package main
import "fmt"
// Order 订单
type Order struct {
ID string
Items []string
TotalAmount float64
IsVerified bool
IsPaid bool
IsShipped bool
}
// OrderHandler 订单处理接口
type OrderHandler interface {
SetNext(handler OrderHandler)
Handle(order *Order) error
}
// 具体处理者
type VerificationHandler struct {
next OrderHandler
}
func (v *VerificationHandler) SetNext(handler OrderHandler) {
v.next = handler
}
func (v *VerificationHandler) Handle(order *Order) error {
fmt.Println("验证订单中...")
order.IsVerified = true
fmt.Println("订单验证完成")
if v.next != nil {
return v.next.Handle(order)
}
return nil
}
type PaymentHandler struct {
next OrderHandler
}
func (p *PaymentHandler) SetNext(handler OrderHandler) {
p.next = handler
}
func (p *PaymentHandler) Handle(order *Order) error {
fmt.Println("处理支付中...")
order.IsPaid = true
fmt.Println("支付处理完成")
if p.next != nil {
return p.next.Handle(order)
}
return nil
}
type ShippingHandler struct {
next OrderHandler
}
func (s *ShippingHandler) SetNext(handler OrderHandler) {
s.next = handler
}
func (s *ShippingHandler) Handle(order *Order) error {
fmt.Println("处理发货中...")
order.IsShipped = true
fmt.Println("发货处理完成")
if s.next != nil {
return s.next.Handle(order)
}
return nil
}
func main() {
// 创建处理链
verification := &VerificationHandler{}
payment := &PaymentHandler{}
shipping := &ShippingHandler{}
verification.SetNext(payment)
payment.SetNext(shipping)
// 创建订单
order := &Order{
ID: "ORD67890",
Items: []string{"商品A", "商品B"},
TotalAmount: 150.50,
}
// 处理订单
verification.Handle(order)
fmt.Printf("订单状态: 验证=%t, 支付=%t, 发货=%t\n",
order.IsVerified, order.IsPaid, order.IsShipped)
}
这些示例展示了电商项目中常用的设计模式实现。每种模式都解决了特定的设计问题:
- 工厂模式:创建对象的逻辑封装,便于扩展新的支付方式
- 单例模式:确保配置信息全局唯一
- 观察者模式:实现订单状态变化的通知机制
- 策略模式:灵活切换不同的折扣计算算法
- 装饰器模式:动态添加商品额外功能
- 仓储模式:抽象数据访问层,便于切换数据源
- 责任链模式:处理订单流程中的多个步骤
这些模式可以帮助构建灵活、可维护和可扩展的电商系统架构。
希望这些设计模式使用场景举例,可以给大家提供使用和设计灵感。
更多推荐



所有评论(0)