
local images_created = 0
-- RealSubject
local Image = {}
Image.__index = Image
function Image.new(file_name)
images_created = images_created + 1
return setmetatable({file_name = file_name},
Image)
end
-- Request()
function Image:draw()
return "draw " .. self.file_name
end
-- Proxy: the same field and method names;
-- the image is created on the first draw
local ImageProxy = {}
ImageProxy.__index = ImageProxy
function ImageProxy.new(file_name)
return setmetatable({file_name = file_name},
ImageProxy)
end
function ImageProxy:draw()
self.image = self.image
or Image.new(self.file_name)
return self.image:draw()
end
-- Client
local proxy = ImageProxy.new("1.png")
-- No image is needed to answer this
local file_name = proxy.file_name
-- file_name = 1.png
local created_before = images_created
-- created_before = 0
-- The call is passed to the image
local drawn = proxy:draw()
-- drawn = draw 1.png
-- images_created = 1
print("file_name = " .. file_name)
print("created_before = " .. created_before)
print("drawn = " .. drawn)
print("images_created = " .. images_created)
Подменяет другой объект для контроля доступа к нему. Заместитель реализует интерфейс первоначального объекта.Read moreЗадача. В документе много больших картинок. Если программа загружает их все при открытии документа, открытие идёт медленно, хотя пользователь видит только первую страницу. Код, который показывает картинки, должен остаться прежним. Но загрузка должна ждать, пока картинка действительно понадобится. Идея. Заместитель встаёт на место другого объекта - реального субъекта. Интерфейс у них одинаковый, поэтому клиент не видит между ними разницы. Заместитель решает, когда и как пользоваться реальным субъектом. Этот вид, виртуальный заместитель, создаёт реальный субъект только при первом запросе, а потом передаёт ему каждый вызов. Другие виды заместителей проверяют права доступа, держат кэш или связываются с объектом на другом компьютере. Как читать пример. Реальный субъект - это изображение, которое дорого создавать. Заместитель хранит только имя файла и пустое место под изображение. В большинстве языков клиент сначала спрашивает имя файла, и заместитель отвечает сам. Когда клиент просит нарисовать изображение, заместитель создаёт настоящее изображение, запоминает его и передаёт вызов. Клиент работает только с заместителем. В некоторых языках вывод показывает ещё и момент, когда настоящее изображение загружается. Когда применять. Заместитель нужен, чтобы управлять доступом к объекту, не меняя ни сам объект, ни его клиентов. Типичные задачи - отложить дорогое создание, проверить права или посчитать вызовы. Если объект дёшев и нужен всегда, заместитель ни к чему: лишний уровень только замедляет код. Частая ошибка. Не сохранить созданный объект. Тогда заместитель создаёт новый реальный субъект при каждом вызове, и вся экономия пропадает. |