- PVSM.RU - https://www.pvsm.ru -

Все начинается с примера.
w // хост (мама)
{
function table(qIn = {})
{
q["tit"] = "Wargana"; /** init-секция */
q["render"] = function(q){ };
qIn = merge(q, qIn); /** merge-секция */
if (q["m"] == "img") q = merge(q, img.table(qIn), qIn);
if (q["m"] == "map") q = merge(q, gmap.table(qIn), qIn);
q["render"](q); /** action-секция */
}
}
img // плагин 1 (дочка)
{
function table(qIn = {})
{
q["render"] = function(q) { return "img" + qIn["tit"]; };
return q;
}
}
gmap // плагин 2 (дочка)
{
function table(qIn = {})
{
q["render"] = function(q) { return "map" + qIn["tit"] + this.markers(qIn); }
return q;
}
function markers(qIn = {})
{
q["layer"] = function(q) { };
qIn = merge(q, qIn);
if (q["layerM"] == "cadastr") q = merge(q, cadastr.markers(qIn), qIn);
return q;
}
}
cadastr // плагин 2.1 (внучка)
{
function markers(qIn = {})
{
q["layer"] = function(q) { return "cadastr"; }
return q;
}
}
/** client-секция, примеры */
w.table({m : "img"})
w.table({m : "map", layerM : "cadastr"})
w.table({m : input("tableM"), layerM : input("gmapLayerM")})
q = merge(q, ..., qIn);
qIn в самом конце merge списка это гарантия высшей власти клиента: насколько сложно код бы себя ни параметризировал, клиент всегда может «навязать в свою игру».
Главное в схеме «Init — Merge — Act» — это связка «Init — Act», а Merge — вторичен.
function some(qIn = {})
{
q["render"] = function(q){ return 1; };
q = merge(q, qIn);
return q["render"](q);
}
Предельная инит-генеалогия:
function some(){ q["render"] = function(q){ return 1; }; return q["render"](q); }
Выход в ноль:
function some(){ return 1; }
function some(){ q["isGrab"] = 0; q = merge(q, plugSome(q)); }
function plugSome(qIn = {}) { q["isGrab"] = 1; q = merge(q, qIn); return q; }
Init-секция up-хоста some() дефолтизируя параметр isGrab для гарантии безопасной работы своей act-секции (которой в данном случае вообще нет), одновременно задает интерфейс для всех своих плагинов, подключаемых в merge-секции.
Этот пример до кучи иллюстрирует IMA-плагинизацию просто на функциях, а передаваемый внутрь плагина параметр q обеспечивает уже упомянутую выше гарантию высшей власти клиента. Разумеется, в любой момент, можно эту власть или ограничить, проведя какие-то пред-преобразования с q или вообще отказаться от даун-инклузии q в сетку плагинов.
Сеточная плагинизация на общей шине создает единое пространство имен для всей подсетки плагинов, с одной стороны, создавая возможность повторного использования одних и тех же сигнатур в разных хостах, коими могут быть даже две разные public-функции одного и того же модуль-хоста, например:
modHost
{
function a(){ q["isGrab"] = 0; }
function b(){ q["isGrab"] = 0; }
}
Благодаря этому устраняется задача вводить modHost.isGrabA, modHost.isGrabB
А с другой стороны, даже самый камчатский сеточный плагин (если ему позволит автор сетки) может воспользоваться ресурсами всей up-трассы параметризации, чтобы выстроить свое поведение в зависимости от логики контекста.
Параноики в любой момент для успокоения нервной системы могут устроить неймспейсовый разрыв, отказавшись от мержа перед ретурном шины:
function a(){ q["isGrab"] = 0; q = merge(q, b(q)); }
function b(qPro = {})
{
q["isGrab"] = !qPro["isGrab"]; ;
/* q = merge(q, qIn); */
return q;
}
Сведя лепку алгоритма с модульного уровня на уровень потока исполнения, выбор типа становится точно таким же параметром как и параметризация уже выбранного типа:
if (input.getM() == "img") imgW.table({width : 50})
vs
w.table({m : input("m"), width : 50})
Хостов (как единиц смысла верхнего уровня) становится меньше, параметров становится больше.
function some(qIn = {})
{
// init-секция
q["total"] = 15;
// merge-секция
// q = merge(q, someA(), someB(), qIn);
qA = someA();
qB = someB();
qPro["total"] = q["total"] + qA["total"] + qB["total"] + qIn["total"];
q = merge(a, someA, someB, qIn, qPro);
// act-секция
}
Автор: rbri
Источник [1]
Сайт-источник PVSM.RU: https://www.pvsm.ru
Путь до страницы источника: https://www.pvsm.ru/programmirovanie/51298
Ссылки в тексте:
[1] Источник: http://habrahabr.ru/post/206896/
Нажмите здесь для печати.