36

设计模式 - 代理模式

 3 years ago
source link: http://violetzijing.is-programmer.com/posts/215445.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

意图: 为其他对象提供一种代理以控制对这个对象的访问。

主要解决: 在直接访问对象时带来的问题,比如说:要访问的对象在远程的机器上。在面向对象系统中,有些对象由于某些原因(比如对象创建开销很大,或者某些操作需要安全控制,或者需要进程外的访问),直接访问会给使用者或者系统结构带来很多麻烦,我们可以在访问此对象时加上一个对此对象的访问层。

何时使用: 想在访问一个类时做一些控制。

如何解决: 增加中间层。

关键代码: 实现与被代理类组合。

应用实例: 1、Windows 里面的快捷方式。

优点: 1、职责清晰。 2、高扩展性。 3、智能化。

缺点: 1、由于在客户端和真实主题之间增加了代理对象,因此有些类型的代理模式可能会造成请求的处理速度变慢。 2、实现代理模式需要额外的工作,有些代理模式的实现非常复杂。

注意事项: 1、和适配器模式的区别:适配器模式主要改变所考虑对象的接口,而代理模式不能改变所代理类的接口。 2、和装饰器模式的区别:装饰器模式为了增强功能,而代理模式是为了加以控制。

有那么一点 lazy loading 的意思。

package main

import "fmt"

type Image interface {
	Display()
}

type RealImage struct {
	Filename string
}

func NewRealImage(filename string) *RealImage {
	image := &RealImage{
		Filename: filename,
	}
	image.LoadFromDisk()

	return image
}

func (r *RealImage) Display() {
	fmt.Println("display ", r.Filename)
}

func (r *RealImage) LoadFromDisk() {
	fmt.Println("loading ", r.Filename)
}

type ProxyImage struct {
	RealImage *RealImage
	Filename  string
}

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

func (p *ProxyImage) Display() {
	if p.RealImage == nil {
		p.RealImage = NewRealImage(p.Filename)
	}
	p.RealImage.Display()
}

func main() {
	var image Image
	image = NewProxyImage("test.jpg")
	image.Display()
	fmt.Println("image doesn't need to be loaded")
	image.Display()
}

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK