posted at 2024.4.16 16:42 by Administrator
Delegate(代理)模式是一种结构型设计模式。 Delegate(代理)用于控制着对于原对象的访问,并允许在将请求提交给原对象的前进行一些处理,从而增强原对象的逻辑处理。
下面让我们一起体验一个例子。
假设有一个代表电视节目的TVProgram类型,需要实现一个代表上映行为的接口(interface)Release,该接口只有一个方法On(tv)。
我们实例化一个TVProgram的实例,在实例上面调用On(tv)方法就能让电视节目上映。
不过地球的大部分国家都是不允许随意上映任何电视节目的,如果此程序要加一个“查询电视节目是否上映”的功能该怎么办?给TVProgram结构体加一个已上映的电视节目清单是显然不合理的。同理,该清单也不应该加在On(tv) 方法里。
这个时候通常的做法是,加上一个表示已上映的电视节目清单变量Check。然后再包装一个Delegate代理类和NewDelegate代理对象。
type Delegate struct{ //代理类 tvprogram *TVProgram} func NewDelegate() *Delegate{ //创建代理对象 return &Delegate{tvprogram:&TVProgram{}}
这样的话我们就可以通过用代理类实现 On(tv) 行为时,给它加上查询电视节目是否上映的功能。
上述做法就是Delegate(代理)模式。
Go语言代码如下:
//TVProgramprojectmain.go
packagemain
import(
"fmt"
"strings"
)
type TVProgram struct{ //服务类
}
type Release interface{ //服务接口
On(tvstring)
}
func(t* TVProgram) On(tv string){//服务类的方法
fmt.Println(tv+"isbeingOn")
}
varcheckstring="西游记非常地带硅谷第六季
黑色乌托邦风月变倚天屠龙记RomeSeason"
type Delegate struct{//代理类
tvprogram *TVProgram
}
func NewDelegate() *Delegate{ //创建代理对象
return &Delegate{tvprogram:&TVProgram{}}
}
func (t*Delegate) On(tv string){ //接替服务类方法
if strings.Contains(check,tv){
t.tvprogram.On(tv)
}else{
fmt.Println(tv+"isn’tbeingOn!")
}
}
//客户端
func main(){
tv:=NewDelegate()
tv.On("非常地带") //输出
var flag string=""
fmt.Printf("请输入查询的电视节目:\n")
fmt.Scanln(&flag)
tv1:=NewDelegate()
tv1.On(flag) //根据输入,输出
}
程序效果:
正如执行后的结果所示,我们不必为服务TVProgram类型添加任何属性和方法,我们只要用代理模式,在客户端调用新的Delegate(代理)On(tv) 方法,就能达到我们想要的查询电视节目是否上映的效果。
看完例子后,相信大家都理解了写代码时怎么使用代理模式,
更清晰的描述代理模式如下:
代理模式的UML类图如下所示:
参与Delegate(代理)模式的一共有四种角色:客户端、服务接口、服务类和代理类。
职责分别是:
服务接口(Service Interface),声明了服务类要实现的接口。服务类的业务处理逻辑就是实现在这里定义的接口方法中,代理类也必须遵循该接口才能伪装成服务对象。
服务(Service)类,提供实际业务逻辑的原对象。
Delegate(代理)类,包含一个服务对象作为成员变量。代理完成其任务(例如延迟初始化、记录日志、访问控制和缓存等)后会将请求传递给服务对象。通常情况下,代理会对其服务对象的整个生命周期进行管理。
客户端(Client),通过统一接口与服务对象或代理对象进行交互,所以可在一切需要服务对象的代码中使用服务对象的代理,客户端完全不会感知到。
在Delegate(代理)模式中,通过让代理类实现跟服务类相同的接口,从而把代理类伪装成了服务类,客户端请求代理时,代理再把请求委派给其持有的真实服务类,在委派的过程中我们就可以添加增强逻辑。
如果我们再给代理类加个代理,代理的代理再加代理,那么其实就变成了另外一种设计模式--装饰器模式。
Delegate(代理)模式的优缺点:
一是与其他模式相比,代理模式更安全,并且易于实施。二是代理模式可以避免巨型对象和内存密集型对象的重复,提高性能。三是远程代理可以增强交互的安全性。缺点是由于引入了另一层抽象,因此,如果一部分客户端直接访问真实的服务对象,而另一部分访问代理对象,则可能导致不同步等问题。
a9304f64-d8de-45c4-a0f9-24f5c66f3598|0|.0|96d5b379-7e1d-4dac-a6ba-1e50db561b04
Tags: 程序, 代码, 方法, 接口, 类, 模
IT技术