GO设计模式——26、访问者模式(行为型)

本文详细介绍了访问者模式,包括其核心角色(抽象访问者、具体访问者、抽象元素和具体元素)、优缺点以及在电商平台中处理商品操作的使用场景。通过代码示例展示了如何实现这一设计模式。
摘要由CSDN通过智能技术生成

目录

访问者模式(Visitor Pattern)

访问者模式的核心角色:

优缺点

使用场景

代码实现


访问者模式(Visitor Pattern)

       访问者模式(Visitor Pattern)将算法从对象结构中分离出来,从而使算法可以独立对象而变化。允许在不修改现有代码的情况下向现有对象结构添加新的行为。该模式建立在两个核心组件上:访问者和元素。访问者是一个能够访问所有元素的对象,而元素则是需要接受访问者的对象。在这种模式下,访问者可以在不改变元素本身的情况下对其进行操作。访问者模式的核心思想是,通过让访问者持有某个具体元素的引用,让元素的接受访问者方法中执行具体访问者的操作。

访问者模式核心角色

  • 抽象访问者(Abstract Visitor):定义了对每个具体元素类的访问操作接口,它的方法签名决定了可以访问哪些元素以及如何访问它们。
  • 具体访问者(Concrete Visitor):实现了抽象访问者定义的访问操作接口,具体决定了对元素的实际访问行为。
  • 抽象元素(Abstract Element):定义了接受访问者的接口,声明了接受访问者的方法。
  • 具体元素(Concrete Element):实现了抽象元素定义的接受访问者的方法,通过调用访问者的具体访问方法来完成具体操作。
  • 对象结构(Object Structure):通常由多个具体元素组成的集合,提供了遍历元素集合的方法,用于让访问者访问元素。

优缺点

(1)优点:

  • 符合单一职责原则。
  • 优秀的扩展性。
  • 灵活性。

(2)缺点:

  • 具体元素对访问者公布细节,违反了迪米特原则。
  • 具体元素变更比较困难。
  • 违反了依赖倒置原则,依赖了具体类,没有依赖抽象。

使用场景

  • 对象结构中对象对应的类很少改变,但经常需要在此对象结构上定义新的操作。
  • 需要对一个对象结构中的对象进行很多不同的并且不相关的操作,而需要避免让这些操作"污染"这些对象的类,也不希望在增加新操作时修改这些类。

代码实现

package main

import "fmt"

// 电商平台,需要对用户的购物车中的商品进行不同的操作,例如计算商品总价、打印商品清单等。
// 商品的类型包括书籍(Book)和电子产品(ElectronicProduct)。

// 抽象访问者接口(Visitor):
type Visitor interface {
    VisitBook(book *Book)
    VisitElectronicProduct(product *ElectronicProduct)
}

// 抽象元素接口(Element)
type Element interface {
    Accept(visitor Visitor)
}

// 具体访问者(Concrete Visitor):
type ShoppingCartVisitor struct {
    TotalPrice float64
}

func (v *ShoppingCartVisitor) VisitBook(book *Book) {
    v.TotalPrice += book.Price
}

func (v *ShoppingCartVisitor) VisitElectronicProduct(product *ElectronicProduct) {
    v.TotalPrice += product.Price
}

// 具体元素(Concrete Element):book
type Book struct {
    Name  string
    Price float64
}

func (b *Book) Accept(visitor Visitor) {
    visitor.VisitBook(b)
}

// 具体元素(Concrete Element):ElectronicProduct
type ElectronicProduct struct {
    Name  string
    Price float64
}

func (p *ElectronicProduct) Accept(visitor Visitor) {
    visitor.VisitElectronicProduct(p)
}

// 对象结构(Object Structure)和具体元素的访问方法
type ShoppingCart struct {
    Items []Element
}

func (cart *ShoppingCart) AddItem(item Element) {
    cart.Items = append(cart.Items, item)
}

func (cart *ShoppingCart) CalculateTotalPrice(visitor Visitor) float64 {
    for _, item := range cart.Items {
       item.Accept(visitor)
    }
    return visitor.(*ShoppingCartVisitor).TotalPrice
}

func main() {
    cart := &ShoppingCart{}

    book := &Book{Name: "Design Patterns", Price: 49.99}
    electronicProduct := &ElectronicProduct{Name: "Smartphone", Price: 599.99}

    cart.AddItem(book)
    cart.AddItem(electronicProduct)

    visitor := &ShoppingCartVisitor{}
    totalPrice := cart.CalculateTotalPrice(visitor)

    fmt.Printf("Total price: $%.2f\n", totalPrice)
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值