В Lua я могу написать простой модуль, подобный такому
local database = require 'database'
local M = {}
function M:GetData()
return database:GetData()
end
return M
, который при необходимости будет загружаться один раз, и все будущие версии будут загружать одну и ту же копию.
Если бы я хотел использовать объектно-ориентированный подход, я мог бы сделать что-то вроде:
local M = {}
M.__index = M
function M:GetData()
return self.database:GetData()
end
return function(database)
local newM = setmetatable({}, M)
newM.database = database
return newM
end
Где M загружается только один раз, и каждая копия newM просто содержит свои собственные данные и используетметоды оригинального M.
Когда дело доходит до тестирования, с помощью ОО-подхода я могу просто передать поддельную версию «базы данных» и проверить, что она вызывается, но с первым подходом я не могу.
Итак, мой вопрос: как я могу сделать так, чтобы первый подход поддерживал DI / тестирование, не делая его похожим на класс?
Я думал заключить его в замыкание примерно так:
local mClosure = function(database)
local M = {}
function M:GetData()
return database:GetData()
end
return M
end
return mClosure
но затем каждый раз, когда он вызывается, он создает новую копию M, поэтому он теряет преимущества обоих предыдущих подходов.