DesignPatternProxy代理模式
为其他对象提供一种代理以控制对这个对象的访问。代理模式用于延迟处理操作或者在进行实际操作前后进行其它处理。
官方简洁代码
package proxy
type Subject interface {
Do() string
}
type RealSubject struct{}
func (RealSubject) Do() string {
return "real"
}
type Proxy struct {
real RealSubject
}
func (p Proxy) Do() string {
var res string
// 在调用真实对象之前的工作,检查缓存,判断权限,实例化真实对象等。。
res += "pre:"
// 调用真实对象
res += p.real.Do()
// 调用之后的操作,如缓存结果,对结果进行处理等。。
res += ":after"
return res
}
# 测试代码
package proxy
import "testing"
func TestProxy(t *testing.T) {
FromAgentBuy()
var sub Subject
sub = &Proxy{}
res := sub.Do()
if res != "pre:real:after" {
t.Fail()
}
}
自己根据业务场景模拟
- 买房子需要地皮,证件,和装修
- 如果这些活自己做,太忙了
- 直接找个托管公司帮你完成就好了
- 最后这些证件直接交付给你就好了
代码文件结构
iface是抽象层,real是实现层
抽象层代码
IAgent.go
package iface
type IAgent interface {
GetCard(house IHouse, person IPerson)
GetFinish(house IHouse, person IPerson)
BuyHouse(house IHouse, person IPerson)
Work(house IHouse)
}
ICard.go
package iface
type ICardSpace interface {
CardDo(house IHouse)
}
IFinish.go
package iface
// 装修模块
type IFinish interface {
FinishDo(house IHouse, person IPerson)
}
IHouse.go
package iface
type IHouse interface {
// 房子地皮产出
FloorDo(person IPerson)
}
IPerson.go
package iface
type IPerson interface {
// 办理所有手续
Work(house IHouse)
GetPerson() interface{}
}
实现层代码
agent.go
package real
import (
"g-a/09_proxy/house/iface"
)
type Agent struct {
Name string
Person *Person
}
func NewAgent(s string, person *Person) *Agent {
return &Agent{
Name: s,
Person: person,
}
}
func (a *Agent) GetCard(house iface.IHouse, person iface.IPerson) {
card := NewCard("agent_card")
card.CardDo(house, person)
}
func (a *Agent) GetFinish(house iface.IHouse, person iface.IPerson) {
finish := NewFinish("agent_f")
finish.FinishDo(house, person)
}
func (a *Agent) BuyHouse(house iface.IHouse, person iface.IPerson) {
newHouse := NewHouse("gent_house")
newHouse.FloorDo(person)
}
func (a *Agent) Work(house iface.IHouse) {
a.Person.Work(house)
a.BuyHouse(house, a.Person)
a.GetCard(house, a.Person)
a.GetFinish(house, a.Person)
}
card.go
package real
import "g-a/09_proxy/house/iface"
type Card struct {
Name string
}
func NewCard(n string) *Card {
return &Card{Name: n}
}
func (c *Card) CardDo(house iface.IHouse, person iface.IPerson) {
pass_word := c.Name + "-pass"
p := person.GetPerson().(*Person)
p.HouseNowPro[pass_word] = true
}
finish.go
package real
import "g-a/09_proxy/house/iface"
type Finish struct {
Name string
}
func NewFinish(n string) *Finish {
return &Finish{Name: n}
}
func (f *Finish) FinishDo(house iface.IHouse, person iface.IPerson) {
f_pass := f.Name + "装修标准标识"
p := person.GetPerson().(*Person)
p.HouseNowPro[f_pass] = true
}
house.go
package real
import "g-a/09_proxy/house/iface"
type House struct {
Name string
}
func NewHouse(n string) *House {
return &House{Name: n}
}
func (h *House) FloorDo(person iface.IPerson) {
h_pass := "房子地皮标识"
p := person.GetPerson().(*Person)
p.HouseNowPro[h_pass] = true
}
person.go
package real
import (
"fmt"
"g-a/09_proxy/house/iface"
)
type Person struct {
Name string
HouseNowPro map[string]bool
}
func NewPerson(n string) *Person {
return &Person{
Name: n,
HouseNowPro: make(map[string]bool),
}
}
func (p *Person) GetPerson() interface{} {
return p
}
func (p *Person) Work(house iface.IHouse) {
fmt.Println(p.Name, "出身份证去买房,房子名字是:")
}
调试输出
t.go
package house
import (
"fmt"
real2 "g-a/09_proxy/house/real"
)
func TTT() {
house := real2.NewHouse("汤臣一品")
jane := real2.NewPerson("JANE")
agent := real2.NewAgent("黑市", jane)
agent.Work(house)
for k, _ := range jane.HouseNowPro {
fmt.Println(k)
}
}
t_test.go
package house
import "testing"
func TestTTT(t *testing.T) {
TTT()
}
最终输出
JANE 出身份证去买房,房子名字是:
房子地皮标识
agent_card-pass
agent_f装修标准标识
·额外收获
先看抽象层IPerson代码和实现层Persomn代码
设计的初衷是我才看完zinx框架设计,接口设计模式都渗透了一些,自己也玩玩
在设计IPerson
接口时候,在实现层用的是后,因为实现承层传参是
person iface.IPerson
,发现取不到真正的person结构体,只能是在写个get方法,最后IPerson
是这样的
package iface
type IPerson interface {
// 办理所有手续
Work(house IHouse)
GetPerson() interface{}
}
发现了吧,我写的是interface{}
,那就在实现层这样写
func (p *Person) GetPerson() interface{} {
return p
}
最后用的时候,直接断言。so smart!