说代理模式之前,先把享元模式简单的说下。
这一次的例子是创建许多图像,但最后只会用到其中一张。
享元模式,基本就是我们程序开头常见的那些静态常量定义,还有字典的使用。而在类里面使用的话就是 __slots__ 这个关键字,能减少内存。总而言之享元模式就是要让你方便和高效的模式,可多多使用。
那么代理模式,也可以说是一个能减少内存和使用空间的模式。从书上的例子给看,给我的印象就是,你可以先创建一个类,让这个类代理着创造些东西,当你真正需要哪一个东西时,再从这个类里面来获取,这时才是真的使用,占了内存。
书上用了一句话“若想用一个对象来代表另一个对象,则可使用‘代理模式’”。这一次的例子是创建许多图像,但最后只会用到其中一张。
image = ImageProxy(Image.image, 300, 60)
image.rectangle(0, 0, 299, 59, fill=YELLOW)
image.ellipse(0, 0, 299, 59, BLUE, RED)
image.line(431, 13, 435, 132, GREEN)
image.line(123, 43, 4235, 32, BLACK)
image.save(filename)
class ImageProxy:
def __init__(self, ImageClass, width=None, height=None, filename=None):
assert (width is not None and height is not None) or filename is not None
self.Image = ImageClass
self.commands = []
if filename is not None:
self.load(filename)
else:
self.commands = [self.Image, width, height]
def load(self, filename):
self.commands = [(self.Image, None, None, filename)]
def set_pixel(self, x, y, color):
self.commands.append((self.Image.set_pixel, x, y, color))
def line(self, x0, y0, x1, y1, color):
self.commands.append((self.Image.line, x0, y0, x1, y1, color))
def rectangle(self, x0, y0, x1, y1, outline=None, fill=None):
self.commands.append((self.Image.rectangle, x0, y0, x1, y1, outline, fill))
def ellipse(self, x0, y0, x1, y1, outline=None, fill=None):
self.commands.append((self.Image.ellipse, x0, y0, x1, y1, outline, fill))
def save(self, filename=None):
command = self.commands.pop(0)
function, *args = command
image = function(args)
for command in self.commands:
function, *args = command
function(image, *args)
image.save(filename)
return image
关键点在:
1.用自定义的一个类 ImageProxy 来代替 Image.image 创造图像,这样只有在调用 save 方法时才会真正创建图像
2.使用存储命令的方式来执行新建图像,即 save 的实现方法
这个代理模式还是蛮让人眼前一亮的,因为设计程序就是追求的方便高效实用。希望以后可以能用在某个地方吧。