npm.io
1.1.5 • Published 2 years ago

abstractstock

Licence
GPL-3.0-or-later
Version
1.1.5
Deps
0
Size
117 kB
Vulns
0
Weekly
0

AbstractStock

Данный пакет реализует концепцию абстрактного полиморфного класса с виртуальными методами и свойствами.
Полиморфиз - одна из концепций ООП.
Виртуальные методы и свойства - т.е методы свойства которые определяются в момент выполнения.

Данныц класс позволяет организовать код, опираясь только на общее поведение и возрощаемое значение вызываемых методов, и сигнатуры их параметров.

Обзор

Установка

Так пакет abstractstock является пакетом nodejs - то вам для установки понадобится менеджер пакетов, к примеру npm.

Для установки пакета в качестве зависимомти другого пакета.

npm install abstractstock

Что бы скачать git репозиторий пакета - вам так же понадобится git. Выполните в терминалн следующий код

git clone https://github.com/dimkl-dev/AbstractStock.git && cd ./AbstractStock && npm install  

Отличие от предыдущей версии

Версии 1.1 появилась возможность контроля присвоения и возврата значений абстрактных свойств и накпителя, так же при их определение добавлен опцианальный параметр debug выводящий отладочную информациию. Более подропный спсиок изменений:

  • в функции abstractProp и initStock добавлены следующие опциональные параметры:

    • verrifF(desc) - опциональный парметр определяющий, при определение абстрактного свойства и накпителя, функцию обратного вызова, которая вызывается перед присвоение, и возвратом значения. Чтобы значения возвращались и записывались - функция обязана возвращать значение. При вызове - в функцию передаётся в виде параметра, объект desc представляющий собой дескриптор свойства, и который имеет следующие свойства:

    • debug - опциональный параметр функций abstractProp и initStock. Если true - то будет выводится дополнительная отладочная информация. Подробности смотри в описании функций ниже.

    • deleteAbstractProp(abstractname) - удаляет абстрактное свойство

    • deleteStock(pname) - удаляет накопитель

Документация

Подробная документация представлена ниже. Так же доступна документация в формате JSDoc.

Для её просмотра можно использовать пакет JSDocLive

Для просмотра JSDoc документации у пакета установленного как зависимость - в каталоге пакета наберите команду

cd ./node_modules/poolcall/ && jsdoclive ./

Если вы скачали git-репозиторий пакета наберите

jsdoclive ./ 

Использование


//Можно использовать любой объект. Это абстрактный пример.
let obj1 = {};
obj1.name = "Boris";
obj1.say = function(){console.log(`hello ${this.name}`)};
//----------------

let {AbstractStock} = require("abstractstock");
let obj2 = new AbstractStock();
obj2.initStock("obj1", obj1);

obj2.abstractProp("_name_", "name");
obj2.abstractProp("say", "say");
//----------------------

Зачем

Очень хороший вопрос зачем. JavaScript очень гибкий язык, но попробуйте взять ссылку на метод объекта и вызвать его в другом объекте

example

obj1 = {};
obj1.name = "Boris";
obj1.say = function(){console.log(`hello ${this.name}`)};
obj1.say()//выведет 'hello Boris'

порпробуем взять у объекта obj1 метод say и вызвать его из объекта obj2

__CODE_BLOCK_6__

Если мы хотим одолжить один метод и вызвать его в контексте другого - тогда всё хорошо. Но если нам не нужно изменять контекст выполнения функции? Тогда пример выше примет следующий вид.

__CODE_BLOCK_7__

Этот метод тоже можно использовать. Он работает пока работаем с объектами(в JavaScript функции тоже объекты) Но этот приём не сработает если мы захоти с эмитировать взятие адреса у свойства имющий значение примитивного типа(строка или числа). Это можно с эмитировать при помощи свойств аксесоров(get и set свойства).


obj2 = {
    say: ()=>{obj1.say()},
    get _name_(){return obj1.name},
    set _name_(pval){obj1.name = pval}
    /* если потребно определять акссесоры на
    существующем методе - то потребно использовать 
    Object.defineProperty*/
}


console.log(obj2.name); // выведет Boris
obj1.name = 'Ivan';
obj1.say();// выведет Ivan
obj2.say();// выведет Ivan

obj2._name_ = 'Peter';
obj1.say();// выведет Peter
obj2.say();// выведет Peter


Как видитие, имитировать указатели и ссылки в Javascript можно. Но использую только встроенные возможности языка - это громоздко, и потребно учитывать на какие типы данных потребно ссылка

Реализация ссылок при помощи AbstacktStock

Для на гляднасти я прпроведу ниже полный код реализации ссылок как на нативном JavaScript, так и использованием пакета AbstractStock.

Нативный JavaScript

obj1 = {};
obj1.name = "Boris";
obj1.say = function(){console.log(`hello ${this.name}`)};

obj2 = {
say: ()=>{obj1.say()},
get _name_(){return obj1.name},
set _name_(pval){obj1.name = pval}
}
с использованием AbstractStock

let obj1 = {};
obj1.name = "Boris";
obj1.say = function(){console.log(`hello ${this.name}`)};

//---блок инициализации
let {AbstractStock} = require("abstractstock");
let obj2 = new AbstractStock();
obj2.initStock("obj1", obj1);

//----Определение ссылок
obj2.abstractProp("_name_", "name");
obj2.abstractProp("say", "say");
//----------------------

Как можно видеть из примеров выше - при использование AbstractStock, потребно определить блок инициализации, но определение самих ссыллок - проще и нагляднее. На демонстрационном примере разница не велика, но с ростом числа ссылок - код определения ссыллок уменьшается до половины. И становится гораздо наглядней.

Всех кого заинтересовал данный подход - прошу проследовать дальше.

Терминология

Для реализация задумки был введён ряд понятий:

Термины не упомянутые в списке выше расматриваются в обще принятом смысле

Внутренние переменные

Здесь описаны перменные на которых держится работа класса. Прямого досту к ним нет, но можно получить ккопию их значений или ссылку на них. Этот раздел введён в описани, так как приего наличии легче объяснить работу некоторых функций и некоторые термины

AS_stock

Хранит ссылку на внешний объект. Является частью накопителя который инициализируется функцией initStock. Именно в контексте этой переменной и разрешаются все Абстрактные-свойства.

ASlist

Внутренняя перменная экземпляра объекта AbstractStock. Является картой сопастовление абстрактных свойств. Перменная имеет тип объкта, значение свойств которой задаются внутри функции abstractProp.

Сама переменная имеет следуюй вид


 {
     ....
     abstractProp: stockProp,
     ....
 }

где:

Другими словами переменная является объектом, свойствами которого являются имена абстрактных свойств, а значениями имена свойств или методов накопителя

API

initStock(pname, pstock, [verrifF], [debug])

Инициализирует Накопитель и свойство(имя свойства указывается в параметре pname) у абстрактного накопителя через которое накопитель можно получить или же сделать накопителем другой внешний объект. Контроль над этими процессами можно расширить через callback функцию определяемую в параметре verrifF. Подробности смотри ниже.

парметры
name type Description
pname String имя накопителя (а также имя сойства, через которе будет даступен накопитель)
pstock Object накопитель
[verrifF] undefined NaN
[debug] Boolean Опциональный параметр. Значение по умолчанию false. Если устанавливается значение в true - то будет выводится дополнительная отладочная информация. Подробности смотри ниже.

К одному экземпляру AbstractStock может быть привязан только один внешний объект, а повторный вызов метода initStock преведёт к следующим действиям:

  • переопределяет накопитель (параметр pname)
  • для доступа к накопителю создаёт новоё свойство у экземпляра класса AbstractStock
  • изменит контекст выполнение всех абстрактных свойств определённых ранее.
  • Привязка свойства для доступа к накопителю, определённое ранее, также будет изменена(будет возврощать объект указанный в параметре pstock)

Пример кода смотри ниже

подробное описание оциональных параметров:
Функция сосздаёт свойство-аксессор т.е сосоздаёт get и set функции, которые при чтение и записи свойства и выполняют всю логику работы. callback функция, передаваемая в параметре virrifF, позволяет расширить их поведение путём её вызова, и получения значение, как перед возвратом, так и перед записью значения. В процесс вызова, в качестве параметра, передаётся объект дескриптор - который полностю описывает детали вызова. Полный список свойств дескриптора смотри выше

  • verriF(desc) - её определение дополняет поведение свойства следующим образом:

    • при чтение - вызывается перед возвратом значения, и возвращённый результат используется как результат чтения свойства. При вызове передаётся объект desc со следующими свойствами:
    • при записи - вызывается перед записью значения, и возвращённый результат используется как значение саписи свойства. При вызове передаётся объект desc со следующими свойствами:

    Если вкачестве значения параметра verrifF передано примитивное значение или объект отличный от объекта функции - то будет сгенерирована ошибка со следуещем содержанием
    'TypeError: verrifF is not function'

  • debug - (Boolean) по умолчанию значение false. Если передать значения true - то будет выведена дополнительная отладочная информация содержание которой зависит от значения параметра verrifF :

    • если параметр verrifF имеет неопределённое значение(undefined, null, NaN:) - то при определение абстрактного накопителя будет выведен блок сообщениё между строками '---start debug massage---' и '---end debug massage---\n'. Так же в режиме console.info будет выведена следующая информация:

    • если значением параметра verrifF имеет значение примитивного типа или объект отличный от объекта Function - то при определение абстрактного накопителя перед генерацией ошибки через console.error() будет выведена следующая информация:

abstractProp(abstractname, stockname, [verrifF], [debug])

Определяет или переопределяет уже существующее абстрактное свойство. Контроль над этими процессами можно расширить через callback функцию определяемую в параметре verrifF. Подробности смотри ниже.

парметры
name type Description
abstractname String имя абстрактного свойства
stockname string имя свойства в накопителе
[verrifF] undefined NaN
[debug] Boolean Опциональный параметр. Значение по умолчанию false. Если устанавливается значение в true - то будет выводится дополнительная отладочная информация. Подробности смотри ниже.

Имя абстрактного свойства задоное в параметре abstractname становится доступным как свойство экземпляра класс AbstractStock

подробное описание оциональных параметров:
Функция сосздаёт свойство-аксессор т.е сосоздаёт get и set функции, которые при чтение и записи свойства и выполняют всю логику работы. callback функция, передаваемая в параметре virrifF, позволяет расширить их поведение путём её вызова, и получения значение, как перед возвратом, так и перед записью значения. В процесс вызова, в качестве параметра, передаётся объект дескриптор - который полностю описывает детали вызова. Полный список свойств дескриптора смотри выше

  • verriF(desc) - её определение дополняет поведение свойства следующим образом:

    Если вкачестве значения параметра verrifF передано примитивное значение или объект отличный от объекта функции - то будет сгенерирована ошибка со следуещем содержанием
    'TypeError: verrifF is not function'

  • debug - (Boolean) по умолчанию значение false. Если передать значения true - то будет выведена дополнительная отладочная информация содержание которой зависит от значения параметра verrifF :

    • если параметр verrifF имеет неопределённое значение(undefined, null, NaN:) - то при определение абстрактного свойства будет выведен блок сообщениё между строками '---start debug massage---' и '---end debug massage---\n'. Так же в режиме console.info будет выведена следующая информация:

    • если значением параметра verrifF имеет значение примитивного типа или объект отличный от объекта Function - то при определение абстрактного свойства перед генерацией ошибки через console.error() будет выведена следующая информация:

пример
    let arr = new Array(5,7,8)// это внешний объект(массив)
    let as = new AbstractStock // экземпляр класса AbstractStock

    //свяжем экземпляр класса AbstractStock с внешним объектом arr

    let pname = "as_array"; // свойствоо с этим именем и будет накопителем
    let pstock = arr;  // ссылка на внешний объект.
    as.initStock(pname, pstock);
    //arr теперь доступен также под именем as.as_array , или as[pname]
    console.log(arr === as[pname]);//true
    console.log(arr === as.as_array);//true

    // опрделелим as.in псевдонимом для метода arr.push
    let abstractname = "in";
    let stockname = "push";

    as.abstractProp(abstractname, stockname);

    //Обращаемся к определённому свойству
    as[abstractname](11); // as.in(11) - будет тотже результат

    console.log(arr);
    //[ 5,7,8,11 ]

    console.log(as[pname]); //или console.lof(as.as_array)
    //[ 5,7,8,11 ]

    // опрделелим as.count псевдонимом для свойства arr.length
    let abstractname2 = "count";
    let stockname2 = "length";
    as.abstractProp(abstractname, stockname);

    console.log(as.count) // или as[abstractname2]
    //3

При переопределение абстрактного свойства в консоль выводится предупреждение в которое добавлены следующие свойства:

Если при определение нового абстрактное свойство,
в накопителе не найдено свойство с именем указаным в пармететре stockname - в консоль будет выведено предупреждение, в которое добавлены следующие свойства:

getASlist

Метод возращает копию карты абстрактных свойств(копию значений переменной ASlist)

getStock

Возврощает ссылку на внутреннию переменную AS_stock, тем самым давая прямой доступ к накопителю. Данная возможность является экспериментальной. Её наличие и поведение могут быть изменены в следующих версиях.

AbstractStock.prototype.validStock
парметры
name type Description
[pstock = this.getStock()]
optiona
String Внешний объект для валидации с абстрактным накопителем. По умолчанию, в качестве Внешнего объекта используется накопитель. Т.е проверяет сам себя.

Проверят возможность разрешения абстрактных свойств отнсительно внешнего объекта передоваемого через параметр pstock. В исходном коде(в коментариях указоно что эта функция проводит валидацию абстрактного накопителя. Это объясняется тем - что используется значение по умолчанию, и функция применяется для проверки коректности абстрактных свойст )

Возврощает объект с резултатами провкерки и имеет следующую структуру:

{
    status,
    abstractProps{
        abstractProp{
            stockProp,
            statusProp
        }
    }
}

где:

  • status (boolean: true|false) - общий статус провекрки. true - всё хорошо, false - одно или более из Абстрактных свойств не прошло проверки.

  • abstractProps - предстовляет собой хеш таблицу, Ключами которой являются имена Абстрактных свойств(abstractProp), а значением каждого из клчей является объект содержащий следующие данные

    • stockProp - имя свойства в объекте переданным через параметр pstock
    • statusProp (boolean: true|false) - статус проверки Абстрактных свойствj
      true - имя свойства, переданного через stockProp есть в параметре pstock false - свойство, переданное через stockProp в параметре pstock не найдено.
deleteAbstractProp

Удаляет абстрактное свойство

парметры
name type Description
abstractname String Имя абстрактного свойства

Returns: Boolean


Если абстрактное свойство с именем указаным в параметре abstractname найдено и его успешно удалось удалить - то функцией будет возвращено значение true. Так же будет удалена ссответсвующая запись из внутренней переменной ASlist

Если абстрактное свойство с именем указаным в параметре abstractname не найдено - то функцией будет возвращено значение false. Также в собщениях console.warn() будет выведена следующая информация:

deleteStock

Удаляет накопитель

парметры
name type Description
pname String имя накопителя

Returns: Boolean


Если накопитель с именем указаным в параметре abstractname найден - то функция вернёт значение true. Таже произойдут следующие действия:

Если накопитель с именем указаным в параметре abstractname не найден - то функция вернёт значение false. Таже console.warn() будет выведена следующая информация:

Keywords