什么是代理模式?
为其他对象提供一种代理以控制对这个对象的访问。
实现
// 游戏玩家接口。由登陆、杀怪、升级三个方法。
type IGamePlayer interface {
// 登录
Login(user, password string)
// 杀怪
KillBoss()
// 升级
Upgrade()
}
// 游戏玩家。正常玩家登陆、打怪、升级。
type GamePlayer struct {
name string
}
func NewGamePlayer(name string) *GamePlayer {
return &GamePlayer{name: name}
}
func (this *GamePlayer) Login(user, password string) {
fmt.Println("登录名为: " + user + " 的超级VIP用户 " + this.name + " 登录成功")
}
func (this *GamePlayer) KillBoss() {
fmt.Println(this.name + " 在打怪")
}
func (this *GamePlayer) Upgrade() {
fmt.Println(this.name + " 升了1级")
}
// 游戏代练。也即代理类,用于代替玩家登陆、打怪、升级。
type GamePlayerProxy struct {
gamePlayer IGamePlayer
}
func NewGamePlayerProxy(gamePlayer IGamePlayer) *GamePlayerProxy {
return &GamePlayerProxy{gamePlayer: gamePlayer}
}
func (this *GamePlayerProxy) Login(user, password string) {
this.gamePlayer.Login(user, password)
}
func (this *GamePlayerProxy) KillBoss() {
this.gamePlayer.KillBoss()
}
func (this *GamePlayerProxy) Upgrade() {
this.gamePlayer.Upgrade()
}
func TestNewGamePlayerProxy(t *testing.T) {
// 定义一个玩家
player := NewGamePlayer("我是大帅哥")
// 定义一个代理
proxy := NewGamePlayerProxy(player)
// 开始打游戏
// 登录
proxy.Login("YXX", "123456")
// 杀怪
proxy.KillBoss()
// 升级
proxy.Upgrade()
}
/*
=== RUN TestNewGamePlayerProxy
登录名为: YXX 的超级VIP用户 我是大帅哥 登录成功
我是大帅哥 在打怪
我是大帅哥 升了1级
--- PASS: TestNewGamePlayerProxy (0.00s)
PASS
*/
优点
- 职责清晰。真实的角色就是实现实际的业务逻辑,不用担心其他非本职责的事务;
- 高扩展性。代理类完全可以在不做任何修改的情况下使用;
- 智能化。比如动态代理。
缺点
-
有些类型的代理模式可能会造成请求的处理速度变慢;
-
实现代理模式需要额外的工作,有些代理模式的实现非常复杂。
使用场景
- 代理;
- 代练
注意
- 与适配器模式的区别:适配器模式主要改变所考虑对象的接口,而代理模式不能改变所代理类的接口;
- 与装饰模式区别:装饰模式是为了增强功能,而代理模式是为了加以控制。
网友评论