【设计模式】第25节:行为型模式之“访问者模式”

一、简介

访问者模式允许一个或者多个操作应用到一组对象上,设计意图是解耦操作和对象本身,保持类职责单一、满足开闭原则以及应对代码的复杂性。

二、优点

  • 分离操作和数据结构
  • 增加新操作更容易
  • 集中化操作

三、适用场景

  • 数据结构稳定,操作易变
  • 一个对象的操作之间无关联

四、UML类图

【设计模式】第25节:行为型模式之“访问者模式”_第1张图片

五、案例

有圆形和矩形两种对象,有画图和调整大小两种数据访问者对形状进行处理。

package main

import "fmt"

type Shape interface {
	Accept(visitor Visitor)
	GetType() string
}

type Circle struct {
}

func NewCircle() *Circle {
	return &Circle{}
}

func (c *Circle) Accept(visitor Visitor) {
	visitor.Visit(c)
}

func (c *Circle) GetType() string {
	return "Circle"
}

type Rectangle struct {
}

func NewRectangle() *Rectangle {
	return &Rectangle{}
}

func (r *Rectangle) Accept(visitor Visitor) {
	visitor.Visit(r)
}

func (r *Rectangle) GetType() string {
	return "Rectangle"
}

type Visitor interface {
	Visit(shape Shape)
}

type DrawVisitor struct {
}

func NewDrawVisitor() *DrawVisitor {
	return &DrawVisitor{}
}

func (dv *DrawVisitor) Visit(shape Shape) {
	if shape.GetType() == "Circle" {
		fmt.Println("Drawing a circle")
	} else if shape.GetType() == "Rectangle" {
		fmt.Println("Drawing a rectangle")
	} else {
		fmt.Println("Unknown shape")
	}
}

type ResizeVisitor struct {
}

func NewResizeVisitor() *ResizeVisitor {
	return &ResizeVisitor{}
}

func (rv *ResizeVisitor) Visit(shape Shape) {
	if shape.GetType() == "Circle" {
		fmt.Println("Resizing a circle")
	} else if shape.GetType() == "Rectangle" {
		fmt.Println("Resizing a rectangle")
	} else {
		fmt.Println("Unknown shape")
	}
}

func main() {
	circle := NewCircle()
	rectangle := NewRectangle()
	drawVisitor := NewDrawVisitor()
	resizeVisitor := NewResizeVisitor()

	circle.Accept(drawVisitor)
	circle.Accept(resizeVisitor)
	rectangle.Accept(drawVisitor)
	rectangle.Accept(resizeVisitor)
}

你可能感兴趣的:(设计模式,访问者模式)