这个确实没有调通,也要记录一下

visitor.go

package visitor

import (
	"fmt"
	"io"
	"os"
)

type MessageA struct {
	Msg    string
	Output io.Writer
}

func (m *MessageA) Accept(v Visitor) {
	//nothing
	v.VisitA(m)
}

func (m *MessageA) Print() {
	//nothing
	if m.Output == nil {
		m.Output = os.Stdout
	}
	fmt.Printf("A: %s\n", m.Msg)
	fmt.Fprintf(m.Output, "A: %s", m.Msg)
}

type MessageB struct {
	Msg    string
	Output io.Writer
}

func (m *MessageB) Accept(v Visitor) {
	//nothing
	v.VisitB(m)
}

func (m *MessageB) Print() {
	//nothing
	if m.Output == nil {
		m.Output = os.Stdout
	}
	fmt.Printf("B: %s\n", m.Msg)
	fmt.Fprintf(m.Output, "B: %s", m.Msg)
}

type Visitor interface {
	VisitA(*MessageA)
	VisitB(*MessageB)
}

type Visitable interface {
	Accept(Visitor)
}

type MessageVisitor struct{}

func (mf *MessageVisitor) VisitA(m *MessageA) {
	//nothing
	m.Msg = fmt.Sprintf("%s %s", m.Msg, "(Visited A)")
}

func (mf *MessageVisitor) VisitB(m *MessageB) {
	//nothing
	m.Msg = fmt.Sprintf("%s %s", m.Msg, "(Visited B)")
}

  

visitor_test.go

package visitor

import (
	"fmt"
	"testing"
)

type TestHelper struct {
	Received string
}

func (t TestHelper) Write(p []byte) (int, error) {
	t.Received = string(p)
	return len(p), nil
}

func Test_Overall(t *testing.T) {
	testHelper := &TestHelper{}
	visitor := &MessageVisitor{}

	t.Run("MessageA test", func(t *testing.T) {
		msg := MessageA{
			Msg:    "Hello World",
			Output: testHelper,
		}

		msg.Accept(visitor)
		msg.Print()

		fmt.Print(testHelper)

		expected := "A: Hello World (Visited A)"
		if testHelper.Received != expected {
			t.Errorf("Expected result was incorrect. %s != %s", testHelper.Received, expected)
		}
	})

	t.Run("MessageB test", func(t *testing.T) {
		msg := MessageB{
			Msg:    "Hello World",
			Output: testHelper,
		}

		msg.Accept(visitor)
		msg.Print()

		expected := "B: Hello World (Visited B)"
		if testHelper.Received != expected {
			t.Errorf("Expected result was incorrect. %s != %s", testHelper.Received, expected)
		}
	})
}

  

go语言设计模式之visitor的更多相关文章

  1. Go语言设计模式之函数式选项模式

    Go语言设计模式之函数式选项模式 本文主要介绍了Go语言中函数式选项模式及该设计模式在实际编程中的应用. 为什么需要函数式选项模式? 最近看go-micro/options.go源码的时候,发现了一段 ...

  2. Go语言设计模式汇总

    目录 设计模式背景和起源 设计模式是什么 Go语言模式分类 个人观点 Go语言从面世就受到了业界的普遍关注,随着区块链的火热Go语言的地位也急速蹿升,为了让读者对设计模式在Go语言中有一个初步的了解和 ...

  3. C语言设计模式

    一 .C语言和设计模式(继承.封装.多态) C++有三个最重要的特点,即继承.封装.多态.我发现其实C语言也是可以面向对象的,也是可以应用设计模式的,关键就在于如何实现面向对象语言的三个重要属性. ( ...

  4. 设计模式之visitor模式,人人能懂的有趣实例

    设计模式,现在在网上随便搜都一大堆,为什么我还要写"设计模式"的章节呢? 两个原因: 1.本人觉得这是一个有趣的设计模式使用实例,所以记下来: 2.看着设计模式很牛逼,却不知道怎么 ...

  5. C语言设计模式-封装-继承-多态

    快过年了,手头的工作慢慢也就少了,所以,研究技术的时间就多了很多时间,前些天在CSDN一博客看到有大牛在讨论C的设计模式,正好看到了,我也有兴趣转发,修改,研究一下. 记得读大学的时候,老师就告诉我们 ...

  6. Go语言设计模式实践:迭代器(Iterator)

    关于本系列 决定开个新坑. 这个系列首先是关于Go语言实践的.在项目中实际使用Go语言也有段时间了,一个体会就是不论是官方文档.图书还是网络资料,关于Go语言惯用法(idiom)的介绍都比较少,基本只 ...

  7. Go语言设计模式实践:组合(Composite)

    关于本系列 这个系列首先是关于Go语言实践的.在项目中实际使用Go语言也有段时间了,一个体会就是不论是官方文档.图书还是网络资料,关于Go语言惯用法(idiom)的介绍都比较少,基本只能靠看标准库源代 ...

  8. 设计模式:visitor模式

    核心:将数据结构和数据的处理分开 注意:注意函数的参数传递和调用关系 例子: class Element; class Visitor { public: virtual void Visit(Ele ...

  9. 设计模式之Visitor(访问者)(转)

    Visitor定义 作用于某个对象群中各个对象的操作. 它可以使你在不改变这些对象本身的情况下,定义作用于这些对象的新操作. 在Java中,Visitor模式实际上是分离了collection结构中的 ...

随机推荐

  1. 【每天一题】LeetCode 0026. 删除排序数组中的重复项

    开源地址:https://github.com/jiauzhang/algorithms 题目描述 /* * https://leetcode-cn.com/problems/remove-dupli ...

  2. 线程提供的方法:static void sleep(long ms),会进入阻塞状态,休眠

    package seday08.thread; import java.util.Scanner; /*** @author xingsir * 线程提供的方法:static void sleep(l ...

  3. IP地址的格式和分类

    IP地址 IP地址时IP协议提供的一种地址格式,它为互联网上的网络设备分配一个用来通信的逻辑地址,目前分为IP v4和IP v6两种,v4的意思是version4,v6是同样的意思. IP v4 IP ...

  4. OSG嵌入QT的简明总结

    目录 1.解决方案 2.存在问题 1) 警告提示 2) 多线程问题 3) 其他 1.解决方案 不得不说关于OSG的资料实在太零散了,搜索了很多关于OSG在QT下的解决方案,都是各有各的说法,有的说的不 ...

  5. SpringCloud之Eureka:集群搭建

    上篇文章<SpringCloud之Eureka:服务发布与调用例子>实现了一个简单例子,这次对其进行改造,运行两个服务器实例.两个服务提供者实例,服务调用者请求服务,使其可以进行集群部署. ...

  6. TCP/IP网络协议初识

    目录 一.什么是协议? 二.什么是TCP/IP协议? 三.TCP/IP为什么这么多协议? 四.TCP/IP协议为什么分层? 五.TCP/IP协议如何入门? 六.TCP/IP 的分层: 七.各协议层打包 ...

  7. 一条简单的更新语句,MySQL是如何加锁的?

    看如下一条sql语句: # table T (id )) delete : MySQL在执行的过程中,是如何加锁呢? 在看下面这条语句: : 那这条语句呢?其实这其中包含太多知识点了.要回答这两个问题 ...

  8. 易优CMS:channel的基础用法

    [基础用法] 名称:channel 功能:易优常用标记,可以循环嵌套标签.通常用于网站导航以获取站点栏目信息,方便网站会员分类浏览整站信息 语法: {eyou:channel type='top' r ...

  9. mysql8安装后如何修改root密码

    mysql5.7.9之后,就没有了password函数,所以,使用传统的password()函数修改root密码的话,就会提示sql错误 UPDATE user SET authentication_ ...

  10. dict继承关系

    from collections.abc import Mapping, MutableMapping#dict属于mapping类型, MutalbelMapping继承Mapping a = {} ...