1. 基本概念

代理模式(Proxy Pattern)是一种结构型设计模式,它允许一个对象(代理)控制另一个对象的访问。代理模式通常涉及到创建一个包装对象(代理),以控制对原始对象的访问,从而提供额外的功能或控制访问方式。

2. 适用场景

  • 远程代理: 当对象位于不同的地址空间,需要通过网络或远程方式进行访问时,使用远程代理。
  • 虚拟代理: 当创建对象的代价很高时,可以使用虚拟代理来推迟对象的实际创建,只在真正需要时才创建。
  • 保护代理: 当希望限制对对象的访问时,可以使用保护代理来控制对对象的访问权限。
  • 缓存代理: 当需要缓存对象的信息,避免重复请求时,可以使用缓存代理。
  • 智能引用: 当需要在对象被引用时执行一些附加操作时,可以使用智能引用代理。

3. 优缺点

优点:

  • 控制访问: 代理模式允许控制对对象的访问,可以在访问对象前后执行一些操作。
  • 降低耦合: 通过代理模式,可以将客户端与真正的实现解耦,客户端无需直接访问真实对象。
  • 灵活性: 可以随时修改代理,以提供不同的行为,而无需修改真实对象。

缺点:

  • 增加复杂性: 代理模式引入了额外的间接层,可能增加系统的复杂性。
  • 性能问题: 在某些情况下,由于代理引入了额外的操作,可能会影响系统性能。

4. 示例

考虑一个简单的图像加载的例子,其中包括一个接口 Image 和其实现类 RealImage,以及一个代理类 ProxyImage

package main

import "fmt"

// Subject Interface
type Image interface {
	Display()
}

// RealSubject
type RealImage struct {
	filename string
}

func NewRealImage(filename string) *RealImage {
	return &RealImage{filename: filename}
}

func (ri *RealImage) LoadFromDisk() {
	fmt.Printf("Loading image: %s\n", ri.filename)
}

func (ri *RealImage) Display() {
	ri.LoadFromDisk()
	fmt.Printf("Displaying image: %s\n", ri.filename)
}

// Proxy
type ProxyImage struct {
	realImage *RealImage
	filename  string
}

func NewProxyImage(filename string) *ProxyImage {
	return &ProxyImage{filename: filename}
}

func (pi *ProxyImage) Display() {
	if pi.realImage == nil {
		pi.realImage = NewRealImage(pi.filename)
	}
	pi.realImage.Display()
}

// Client
func main() {
	image := NewProxyImage("sample.jpg")
	image.Display()

	// The image is not loaded again because it's already cached in the proxy
	image.Display()
}

在这个示例中,RealImage是实际的图像类,而ProxyImage是代理类。当客户端调用Display方法时,ProxyImage控制对真实对象的访问,确保图像被加载并显示。这种方式可以延迟图像的加载,提高系统性能。


孟斯特

声明:本作品采用署名-非商业性使用-相同方式共享 4.0 国际 (CC BY-NC-SA 4.0)进行许可,使用时请注明出处。

Author: mengbin

blog: mengbin

Github: mengbin92

cnblogs: 恋水无意

腾讯云开发者社区:孟斯特