关于代理模式
某些情况下,一个客户不能或者不想直接访问另一个对象,这时需要找一个中介帮忙完成某项任务,这个中介就是代理对象。例如,我们要买火车票可以不去火车站买,可以通过12306网站或者火车票代售点买。
代理模式定义:
由于某些原因需要给对象提供一个代理以控制对该对象的访问。这时,提供一个代理对象,并由代理对象控制对原对象的引用。
我们比较常见的有调用权限检查、分布式负载均衡等。
代理模式的UML类图及代码示例
结构及类图:
代理模式的主要角色如下:
- 抽象主题(Subject)类:通过接口或抽象类声明真实主题和代理对象实现的业务方法。
- 真实主题(Real Subject)类:实现了抽象主题中的具体业务,是代理对象所代表的真实对象,是最重要引用的对象。
- 代理(Proxy)类:提供了与真实主题相同的接口,其内部含有对真实主题的引用,它可以访问、控制或扩展真实主题的功能。
当然,这些都是课本上的定义。
代码实现
单看书上的概念还是抽象了一些,这里我们给出一个场景:
招聘网站中普通用户仅支持上传简历、投递简历以及查看招聘启事,而通过企业认证的企业用户还可以发布招聘启事以及查看他人简历,这里我们用代理模式来解决招聘网站权限控制:
Go实现:
// UserOperation 定义用户操作的接口
type UserOperation interface {
UploadResume() error
SubmitResume() error
ViewJobPostings() error
}
定义普通用户结构体并实现接口
// RegularUser 普通用户结构体
type RegularUser struct {
}
// UploadResume 普通用户上传简历的实现
func (ru RegularUser) UploadResume() error {
// 这里可以添加实际的上传简历逻辑,比如与服务器交互等
// 这里简单返回nil表示操作成功
return nil
}
// SubmitResume 普通用户投递简历的实现
func (ru RegularUser) SubmitResume() error {
// 同样可以添加实际的投递逻辑,这里先简单返回nil
return nil
}
// ViewJobPostings 普通用户查看招聘启事的实现
func (ru RegularUser) ViewJobPostings() error {
// 添加查看招聘启事的实际逻辑,暂返回nil
return nil
}
定义企业用户结构体,它除了实现上述接口的方法外,还有自己特有的发布招聘启事和查看他人简历的方法
// EnterpriseUser 企业用户结构体
type EnterpriseUser struct {
}
// UploadResume 企业用户上传简历的实现,这里假设企业用户也可能有上传简历的需求(比如企业介绍文档等)
func (eu EnterpriseUser) UploadResume() error {
return nil
}
// SubmitResume 企业用户投递简历的实现,这里假设企业用户不需要投递简历操作,返回一个特定的错误表示不支持该操作
func (eu EnterpriseUser) SubmitResume() error {
return fmt.Errorf("企业用户不支持投递简历操作")
}
// ViewJobPostings 企业用户查看招聘启事的实现
func (eu EnterpriseUser) ViewJobPostings() error {
return nil
}
// PostJobOpening 企业用户发布招聘启事的实现
func (eu EnterpriseUser) PostJobOpening() error {
// 添加实际的发布招聘启事逻辑,暂返回nil
return nil
}
// ViewOtherResumes 企业用户查看他人简历的实现
func (eu EnterpriseUser) ViewOtherResumes() error {
// 添加实际的查看他人简历逻辑,暂返回nil
return nil
}
定义代理结构体,它将根据用户类型(普通用户或企业用户)来代理相应的操作
// UserProxy 代理结构体
type UserProxy struct {
user UserOperation
}
// NewUserProxy 创建代理对象的函数,根据用户类型创建对应的代理
func NewUserProxy(userType string) *UserProxy {
var user UserOperation
if userType == "regular" {
user = RegularUser{}
} else if userType == "enterprise" {
user = EnterpriseUser{}
} else {
panic("不支持的用户类型")
}
return &UserProxy{user: user}
}
// UploadResume 代理上传简历操作
func (up *UserProxy) UploadResume() error {
return up.user.UploadResume()
}
// SubmitResume 代理投递简历操作
func (up *UserProxy) SubmitResume() error {
return up.user.SubmitResume()
}
// ViewJobPostings 代理查看招聘启事操作
func (up *UserProxy) ViewJobPostings() error {
return up.user.ViewJobPostings()
}
// PostJobOpening 代理发布招聘启事操作,只有企业用户可执行
func (up *UserProxy) PostJobOpening() error {
if _, ok := up.user.(EnterpriseUser); ok {
return up.user.PostJobOpening()
}
return fmt.Errorf("普通用户不支持发布招聘启事操作")
}
// ViewOtherResumes 代理查看他人简历操作,只有企业用户可执行
func (up *UserProxy) ViewOtherResumes() error {
if _, ok := up.user.(EnterpriseUser); ok {
return up.user.ViewOtherResumes()
}
return fmt.Errorf("普通用户不支持查看他人简历操作")
}
测试类
func main() {
// 创建普通用户代理并执行相关操作
regularUserProxy := NewUserProxy("regular")
regularUserProxy.UploadResume()
regularUserProxy.SubmitResume()
regularUserProxy.ViewJobPostings()
regularUserProxy.PostJobOpening() // 应该返回普通用户不支持发布招聘启事操作的错误
regularUserProxy.ViewOtherResumes() // 应该返回普通用户不支持查看他人简历操作的错误
// 创建企业用户代理并执行相关操作
enterpriseUserProxy := NewUserProxy("enterprise")
enterpriseUserProxy.UploadResume()
enterpriseUserProxy.SubmitResume()
enterpriseUserProxy.ViewJobPostings()
enterpriseUserProxy.PostJobOpening()
enterpriseUserProxy.ViewOtherResumes()
}
代理模式优缺点
看完代码实现,我们来分析一下优缺点:
优点:
- 代理模式在客户端与目标之间起到一个中介作用和保护目标对象的作用
- 代理对象可以扩展目标对象的功能
- 代理模式能够将客户端与目标对象分离,在一定程度上降低了系统的耦合度
缺点: - 在客户端和目标对象之间增加一个代理对象,会造成请求处理速度变慢
- 增加了系统的复杂度
更新中…
标签:简历,代理,招聘启事,Proxy,func,error,return,设计模式 From: https://blog.csdn.net/qq_73564181/article/details/142643921