设计模式-访问者模式

设计模式-访问者模式

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Ah5yZ4Vx-1660700350128)(https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcTmCBS331ik6HqS8umZQ-F0ODN27-KdEUzAkQ&usqp=CAU)]

参考


在访问者模式中,我们使用了一个访问者类,它改变了元素类的执行算法。通过这种方式,元素的执行算法可以随着访问者改变而改变。这种类型的设计模式属于行为模式。根据模式,元素对象已接收访问者,这样访问者对象就可以处理元素对象上的操作。

使用场景

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

Demo分析

例如我们需要完成一个文件解析器,需要实现对不同类型的文件有内容提取压缩等操作。我们可以使用if-else判断语句完成,但是当添加的功能比较多时,代码堆积的就会比较厉害,看起来会很不优雅。

Go实现

package main

import "fmt"

type ReadFile interface {
	Read(filePath string)
	Accept(visitor Visitor)
}

type ReadPdfFile struct{}

func (r *ReadPdfFile) Read(filePath string) {
	fmt.Printf("读取pdf文件:%s\n", filePath)
}

/**
* 接收访问者
 */
func (r *ReadPdfFile) Accept(visitor Visitor) {
	visitor.VistorPdfFile(r)
}

type ReadTxtFile struct{}

func (r *ReadTxtFile) Read(filePath string) {
	fmt.Printf("读取txt文件:%s\n", filePath)
}

func (r *ReadTxtFile) Accept(visitor Visitor) {
	visitor.VistorTxtFile(r)
}

type Visitor interface {
	VistorPdfFile(r *ReadPdfFile)
	VistorTxtFile(r *ReadTxtFile)
}

/**
 * 读取文件类
 */
type ExactFile struct{}

func (e *ExactFile) VistorPdfFile(r *ReadPdfFile) {
	fmt.Println("读取pdf文件")
}

func (e *ExactFile) VistorTxtFile(r *ReadTxtFile) {
	fmt.Println("读取txt文件")
}

/**
* 压缩文件类
 */
type CompressionFile struct{}

func (c *CompressionFile) VistorPdfFile(r *ReadPdfFile) {
	fmt.Println("压缩pdf文件")
}

func (c *CompressionFile) VistorTxtFile(r *ReadTxtFile) {
	fmt.Println("压缩txt文件")
}

func test() {
	fileList := []ReadFile{
		&ReadPdfFile{},
		&ReadTxtFile{},
		&ReadTxtFile{},
	}
	extract := ExactFile{}
	for _, f := range fileList {
		f.Accept(&extract)
	}
	fmt.Println("------------------------------------")
	compress := CompressionFile{}
	for _, f := range fileList {
		f.Accept(&compress)
	}
}

func main() {
	test()
}

输出

读取pdf文件
读取txt文件
读取txt文件
------------------------------------
压缩pdf文件
压缩txt文件
压缩txt文件

Python实现

class ReadFile:
  """
    ## 各种文件的抽象类型
  """
  def Read(self):
    pass
  def Accept(self):
    pass

class ReadPdfFile(ReadFile):
  def Read(self):
    print("Read PDF File")
  def Accept(self, visitor):
    visitor.VisitPdfFile(self)

class ReadTxtFile(ReadFile):
  def Read(self):
    print("Read TXT File")
  def Accept(self, visitor):
    visitor.VisitTxtFile(self)

class Visitor:
  """
    ## 访问者抽象类
  """
  def VistorPdfFile(self, r):
    pass
  def VistorTxtFile(self, r):
    pass

class ExactFile(Visitor):
  """
    ## 读取文件的类
  """
  def VisitPdfFile(self, file):
    print("读取pdf文件")
  def VisitTxtFile(self, file):
    print("读取txt文件")

class CompressionFile(Visitor):
  """
    ## 压缩文件的类
  """
  def VisitPdfFile(self, file):
    print("压缩pdf文件")
  def VisitTxtFile(self, file):
    print("压缩txt文件")

def test():
  fileList = [
    ReadPdfFile(),
    ReadTxtFile(),
    ReadPdfFile(),
  ]
  extract = ExactFile()
  compress = CompressionFile()
  for file in fileList:
    file.Accept(extract)
  for file in fileList:
    file.Accept(compress)

if __name__ == '__main__':
  test()

输出

读取pdf文件
读取txt文件
读取pdf文件
压缩pdf文件
压缩txt文件
压缩pdf文件

小结

面对上述的多种文件类型的多种操作方式的场景。我们采用访问者的模式,根据不同的功能设置不同的访问者(不是经常会出现来者何意嘛,这里不同的功能代表来意带入场景应该就可以方便记住访问者的身份了)。这样的好处就是我们将这样一个文件使用的场景分成了两个大的模块:功能的具体实现模块,面向使用的模块。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值