← Back to the index page

Proxy

The Proxy pattern is a structural design pattern that provides a substitute or placeholder for another object. It manages access to the original object, enabling you to execute specific actions either before or after forwarding a request to that object. By nature, Proxy is very similar to Decorator, but with one significant difference that decorator extends the object, but proxy substitutes the object.

Proxy Scheme

Usually Proxy is used for:

While Decorator for:

In many aspects, Proxy and Decorator are very similar.

Hero class

Here is simple Hero class with some fields like damage, hit points, damage, and experience. Also it contains two methods Hero:attack() and Hero:defend().

---@class Hero
---@field private name string
---@field private hp number
---@field private damage number
---@field private xp number
local Hero = {}
Hero.__index = Hero

---@return Hero
function Hero:new(name, hp, damage, xp)
    local t = {
        name = name,
        hp = hp,
        damage = damage,
        xp = xp,
    }
    return setmetatable(t, self)
end

function Hero:attack()
    print("Hero is attacking")
end

function Hero:defend()
    print("Hero is defending")
end

return Hero

HeroProxy class

In this example, the proxy pattern might be very overwhelming, but it is done for simplicity. Here Proxy acts like a filter and checks can the hero perform any actions like attack or defend.

---@class HeroProxy
---@field private hero Hero
local HeroProxy = {}
HeroProxy.__index = HeroProxy

---@param hero Hero
---@return HeroProxy
function HeroProxy:new(hero)
    local t = {
        hero = hero,
    }
    return setmetatable(t, self)
end

function HeroProxy:attack()
    if self:canAttackOrDefend then
        self.hero:attack()
    else
        print("cannot attack, hero is dead")
    end
end

function HeroProxy:defend()
    if self:canAttackOrDefend then
        self.hero:defend()
    else
        print("cannot defend, hero is dead")
    end
end

---@return boolean
function HeroProxy:canAttackOrDefend()
    return self.hero.hp > 0
end

return HeroProxy

HeroProxy usage

local Hero = require("Hero")
local HeroProxy = require("HeroProxy")

local hero = Hero:new("Max", 100, 10, 22)
local proxy = HeroProxy:new(hero)
proxy:attack() -- Hero is attacking
hero.hp = 0    -- set hit points to zero, which means hero is dead
proxy:attack() -- cannot attack, hero is dead

Feedback

For feedback, please check the contacts section. Before writing, please specify where you came from and who you are. Sometimes spammers go insane. Thank you in advance for your understanding.

← Back to the index page