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

发布时间:2023年12月22日

目录

访问者模式(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)
}
文章来源:https://blog.csdn.net/Gloming__zxy/article/details/135133961
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。