golang设计模式之访问者模式

作者: adm 分类: go 发布时间: 2022-08-07

访问者模式可以给一系列对象透明的添加功能,并且把相关代码封装到一个类中。

对象只要预留访问者接口Accept则后期为对象添加功能的时候就不需要改动对象。

大概的流程就是:

从结构容器中取出元素
创建一个访问者
将访问者载入传入的元素(即让访问者访问元素)
获取输出
例如,一个对象的方法,在测试环境要打印出: 这是测试环境,在生产环境中要打印出: 这是生产环境

一般最开始会这样写:

type EnvExample struct {
 }

 func (e EnvExample) Print() {
     if GetEnv() == "testing" {
         fmt.Println("这是测试环境")
     }

     if GetEnv() == "production" {
         fmt.Println("这是生产环境")
     }
 }

这样这个Print() 方法的逻辑就耦合在当前结构体中了,扩展性差,现在假如我们要添加一个打印 这是本地环境 的逻辑呢?

我们就需要更改Print() 方法了,注意! 这是一个非常简单的例子,可以随意更改Print() 方法,没什么关系,但是在实际开发过程中

一个函数的实现是十分复杂的,有可能更改了这个方法,会导致整个系统崩溃,所以解耦是一个十分迫切的需要.

对象容器也只是一个容器而已,我就不实现了,用Map,List都能实现

1. 定义访问者接口

// 定义访问者接口
 type IVisitor interface {
     Visit() // 访问者的访问方法
 }

2. 实现该接口

 type ProductionVisitor struct {
 }

 func (v ProductionVisitor) Visit() {
     fmt.Println("这是生产环境")
 }

 type TestingVisitor struct {
 }

 func (t TestingVisitor) Visit() {
     fmt.Println("这是测试环境")
 }

3. 创建元素接口

// 定义元素接口
 type IElement interface {
     Accept(visitor IVisitor)
 }

4. 实现元素接口

type Element struct {
 }

 func (el Element) Accept(visitor IVisitor) {
     visitor.Visit()
 }

5. 修改 Print() 方法

type EnvExample struct {
     Element
 }

 func (e EnvExample) Print(visitor IVisitor) {
     e.Element.Accept(visitor)
 }

6. 开始调用

// 创建一个元素
 e := new(Element)
 e.Accept(new(ProductionVisitor)) // output: 这是生产环境
 e.Accept(new(TestingVisitor))    // output: 这是测试环境

 m := new(EnvExample)
 m.Print(new(ProductionVisitor))
 m.Print(new(TestingVisitor))

如果觉得我的文章对您有用,请随意赞赏。您的支持将鼓励我继续创作!