代理模式,单元测试用例真的写得详细,

受教~

proxy.go

package proxy

import (
	//"errors"
	"fmt"
)

type UserFinder interface {
	FindUser(id int32) (User, error)
}

type User struct {
	ID int32
}

type UserList []User

func (t *UserList) FindUser(id int32) (User, error) {
	for i := 0; i < len(*t); i++ {
		if (*t)[i].ID == id {
			return (*t)[i], nil
		}
	}
	return User{}, fmt.Errorf("User %d could not be found\n", id)
}

type UserListProxy struct {
	SomeDatabase           UserList
	StackCache             UserList
	StackCapacity          int
	DidLastSearchUsedCache bool
}

func (u *UserListProxy) FindUser(id int32) (User, error) {
	user, err := u.StackCache.FindUser(id)
	if err == nil {
		fmt.Println("Returning user from cache")
		u.DidLastSearchUsedCache = true

		return user, nil
	} else {
		user, err = u.SomeDatabase.FindUser(id)
		if err != nil {
			return User{}, err
		}
		fmt.Println("Returning  from database")
		u.addUserToStack(user)
		u.DidLastSearchUsedCache = false
		return user, nil
	}
}

func (t *UserList) addUser(newUser User) {
	*t = append(*t, newUser)
}

func (u *UserListProxy) addUserToStack(user User) {
	if len(u.StackCache) >= u.StackCapacity {
		u.StackCache = append(u.StackCache[1:], user)
	} else {
		u.StackCache.addUser(user)
	}
}

  

proxy_test.go

package proxy

import (
	"fmt"
	"math/rand"
	"testing"
)

func Test_UserListProxy(t *testing.T) {
	someDatabase := UserList{}

	rand.Seed(2342342)
	for i := 0; i < 1000; i++ {
		n := rand.Int31()
		fmt.Println(n)
		someDatabase = append(someDatabase, User{ID: n})
	}

	proxy := UserListProxy{
		SomeDatabase:  someDatabase,
		StackCapacity: 2,
		StackCache:    UserList{},
	}

	knowsIDs := [3]int32{
		someDatabase[3].ID,
		someDatabase[4].ID,
		someDatabase[5].ID}

	t.Run("FindUser - Empty cache", func(t *testing.T) {
		user, err := proxy.FindUser(knowsIDs[0])
		if err != nil {
			t.Fatal(err)
		}
		if user.ID != knowsIDs[0] {
			t.Error("Returned user name doesn't match with expected")
		}
		if len(proxy.StackCache) != 1 {
			t.Error("After one successful search in an empty cache, the size of it must be one")
		}
		if proxy.DidLastSearchUsedCache {
			t.Error("No user can be returned from an empty cache")
		}
	})

	t.Run("FindUser - One user, ask for the same user", func(t *testing.T) {
		user, err := proxy.FindUser(knowsIDs[0])
		if err != nil {
			t.Fatal(err)
		}
		if user.ID != knowsIDs[0] {
			t.Error("Returned user name doesn't match with expected")
		}
		if len(proxy.StackCache) != 1 {
			t.Error("Cache must not grow if we asked for an object that stored on it")
		}
		if !proxy.DidLastSearchUsedCache {
			t.Error("The user should have been returned from the cache")
		}
	})

	user1, err := proxy.FindUser(knowsIDs[0])
	if err != nil {
		t.Fatal(err)
	}

	user2, _ := proxy.FindUser(knowsIDs[1])
	if proxy.DidLastSearchUsedCache {
		t.Error("The user wasn't stored on the proxy cache yet")
	}
	user3, _ := proxy.FindUser(knowsIDs[2])
	if proxy.DidLastSearchUsedCache {
		t.Error("The user wasn't stored on the proxy cache yet")
	}

	for i := 0; i < len(proxy.StackCache); i++ {
		if proxy.StackCache[i].ID == user1.ID {
			t.Error("User that should be gone was found")
		}
	}

	if len(proxy.StackCache) != 2 {
		t.Error("After inserting 3 users the cache should no grow" +
			" more than to two")
	}

	for _, v := range proxy.StackCache {
		if v != user2 && v != user3 {
			t.Error("A non expected user was found on the cache")
		}
	}
}

  

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

  1. java设计模式之Proxy(代理模式)

    java设计模式之Proxy(代理模式) 2008-03-25 20:30 227人阅读 评论(0) 收藏 举报 设计模式javaauthorizationpermissionsstringclass ...

  2. 设计模式之Proxy(代理)

    设计模式之Proxy(代理) 板桥里人banq http://www.jdon.com 2002/04/21/ 理解并使用设计模式,能够培养我们良好的面向对象编程习惯,同时在实际应用中,可以如鱼得水, ...

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

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

  4. Go语言设计模式汇总

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

  5. C语言设计模式

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

  6. 设计模式--代理(Proxy)模式

    在公司,经常性听到采购部的人说采购某样东材料,采购不了,需要通过代理商才可以.以前Insus.NET也做有一个练习<找人办事,代理设计模式(Proxy)>http://www.cnblog ...

  7. php设计模式之Proxy(代理模式)和Facade(外观)设计模式

    Proxy(代理模式)和Facade(外观)设计模式它们均为更复杂的功能提供抽象化的概念,但这两种实现抽象化的过程大不相同 Proxy案例中,所有的方法和成员变量都来自于目标对象,必要时,该代理能够对 ...

  8. [学习笔记]设计模式之Proxy

    为方便读者,本文已添加至索引: 设计模式 学习笔记索引 写在前面 “魔镜啊魔镜,谁是这个世界上最美丽的人?” 每到晚上,女王都会问魔镜相同的问题(见Decorator模式).这是她还曾身为女巫时留下的 ...

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

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

随机推荐

  1. 分布式图数据库 Nebula RC2 发布:增强了 CSV Importer 功能

    Nebula Graph 是开源的分布式图数据库,可应用于知识图谱.社交推荐.风控.IoT 等场景. 本次 RC2 主要新增 GO FROM ... REVERSELY 和 GROUP BY 等语句, ...

  2. SpringMVC框架之第四篇

    5.SpringMVC异常处理 5.1.异常分类 1.可预知异常: Java编译时可检测异常,例如:IOException.SQLException等. 自定义异常(继承Exception父类的自定义 ...

  3. 剑指offer笔记面试题6----从未到头打印链表

    题目:输入一个链表的头结点,从尾到头反过来打印出每个结点的值.链表节点定义如下: struct ListNode{ int m_nKey; ListNode* m_pNext; } 测试用例: 功能测 ...

  4. 44.QT-安装MySQL、测试连接MySQL

    在上章学习了42.QT-操作SQLite数据库后,发现MySQL和SQLite的语句都大致相同,所以本章只测试MySQL是否能使用 MySQL安装参考链接:https://blog.csdn.net/ ...

  5. 设计冲刺Design Sprint - 阅读记录

    改进团队流程: 审查了头脑风暴 - brain storming的成果,真正付诸实践并且获得成功的想法并不是来自大喊大叫的头脑风暴.而是来自静下心来的一次思考. 1. 搭建舞台 在开始设计冲刺之前,你 ...

  6. diango中有三种response

    from django.shortcuts import render, redirect, HttpResponse HttpResponse() render() redirect()

  7. linux_ext4恢复超级块.txt

    恢复ext4文件系统superblock 2014-04-01 17:00:17 分类: Linux 恢复ext4文件系统superblock1. Create ext4 文件系统.[root@loc ...

  8. 导入Jar报错An internal error occurred during: "Building workspace". zip END header not found

    百度了好久都没有找到答案,后来新建了一个文件夹,再build path就正常了,不知道为什么

  9. PHPStorm 初遇 Xdebug (xdebug代码调试及性能分析)

    centos 7 下PHP7安装xdebug # 下载xdebug wget https://xdebug.org/files/xdebug-2.7.2.tgz # 解压 tar -xf xdebug ...

  10. 关于Oracle数据库的rownum应用

    它是Oracle系统顺序分配为从查询返回的行的编号,返回的第一行分配的是1,第二行是2,以此类推,这个伪字段可以用于限制查询返回的总行数,而且rownum不能以任何表的名称作为前缀. 如以下语句将无法 ...