Статьи

Определение динамических активов — PHP Project pt. II

В настоящее время я работаю над функцией проекта, которая позволяет пользователям отслеживать активы, которые существуют на месте. Интересной частью этой функции является то, что актив может быть практически любым, и что свойства одного экземпляра актива могут практически не совпадать со свойствами другого актива.

Свойства в этом контексте относятся не только к атрибутам актива, но и к тому, как эти атрибуты отображаются, вводятся пользователем при добавлении / редактировании актива и проверяются при сохранении актива пользователем. Активы могут иметь вложенные активы, образуя дерево. И самое интересное: пользователи должны иметь возможность определять свои собственные активы, с типами данных свойств, отображением и проверкой, контролируемыми пользователем.

Я не буду говорить о том, как хранятся активы (до тех пор, пока несколько дней назад это был переход между MySQL или MongoDB без схемы .) Вместо этого далее следует серия публикаций, описывающих наше решение для определения актива, отображение форм добавления и редактирования и проверка ресурса. В этом первом посте рассказывается, как определяются типы активов.

Актив в основном представляет собой пакет свойств, и каждое свойство имеет атрибуты, которые определяют, какие значения оно может содержать, и намеки на то, как оно должно быть представлено пользователю при отображении или редактировании.

Например: водопроводная система в вашем доме может иметь такие свойства, как «дата установки» или «источник воды» (где источником воды может быть «город» или «колодец»). Система также может иметь подэлементы, например «вода». обогреватель «, который имеет такие свойства, как» тип «(газовый, электрический, солнечный) и» дата последнего обслуживания «. Также может быть список «ливней», которые также являются под-активами и имеют такие свойства, как «местоположение», «размер» и «необходимо очистить».

Нашим первым шагом было определение класса для каждого типа ресурса, который включал бы свойства типа и способ отображения этих свойств. Проблема с этим решением была двоякой: во-первых, мы в настоящее время не знаем, какие свойства будут иметь или не понадобятся каждому из наших активов (поэтому схема типа актива будет изменяться); и во-вторых, мы не хотим, чтобы нашим пользователям приходилось писать код для определения своих собственных типов активов. На самом деле, мы еще не знаем всех активов, которые нам нужно будет отслеживать для наших собственных целей.

Нашим решением было хранить определения активов в виде данных, а не кода. Затем все, что нам нужно, — это механизм, который читает определение и создает динамический объект класса «без класса». Синтаксис определения — JSON, хотя код, который фактически создает конкретные экземпляры активов, нене важно, как хранятся определения.

Вот некоторые определения для вышеупомянутой системы сантехники (я намеренно добавил некоторые ограничения, чтобы продемонстрировать другие биты синтаксиса определения):

{
  "plumbing" : {
    "type" : "plumbing",
    "display" : "Home Plumbing",
    "instance_name" : "Installed %installation_date%",
    "fields" : {
      "water_source" : {
        "type" : "string",
        "options" : ["city", "well"],
        "other" : "Where does the water come from",
        "default" : "city"
      },
      "installation_date" : {
        "type" : "date",
        "required" : true
      },
      "water_heater" : {
        "type" : "subasset",
        "options" : ["gas_heater", "electric_heater"],
      },
      "showers" : {
        "type" : "subasset",
        "options" : ["shower"],
        "collection" : true,
        "max" : 5
      }
    }
  },

  "another_type" : {
    ...
  },
  ...
}

Все активы должны иметь «тип», который должен быть уникальным среди всех определений активов. «display» — необязательное поле; если не указано, на дисплее отображается строка типа «type» в верхнем верблюжьем регистре, а подчеркивания заменяются пробелами (например, «plumbing_system» становится «Plumbing System»). Отображение используется для идентификации типа экземпляра актива для пользователя, главным образом в формах ввода / редактирования и отчетности.

«Имя_экземпляра» — это строка форматирования, используемая для представления конкретного ресурса пользователю. Перенос имени поля в% заменит фактическое значение этого поля при отображении ресурса пользователю. В приведенном выше примере, если сантехнический актив имеет дату установки «6/12/2009», то актив будет отображаться пользователю как «Установлен 12/12/2009».Если имя_экземпляра не указано, именем экземпляра по умолчанию является идентификатор ресурса.

Остальная часть ресурса представляет собой список полей, проиндексированных внутренним именем поля, каждое из которых имеет некоторую комбинацию описательных атрибутов. Атрибут «type» является единственным обязательным атрибутом для поля и должен иметь одно из значений «string», «int», «boolean», «datetime», «date», «float» или «subasset». Разница между датой и датой и временем заключается исключительно в том, как они представляются пользователю (и насколько детально хранится значение: даты всегда округляются до полуночи).

«required» — логический флаг, указывающий, можно ли сохранить актив без значения в этом поле или нет. «скрытый» — это еще один логический флаг, указывающий, должно ли поле быть представлено пользователю. Мы должны быть осторожны, если поле является обязательным и скрытым, приложение должно предоставить значение. Хороший способ сделать это — использовать атрибут «default», который задает значение по умолчанию для этого поля. Если поле не скрыто, значение по умолчанию будет предварительно введено или выбрано для пользователя в форме «Добавить актив».

Атрибут «options» содержит список допустимых значений для поля. Исключение составляют поля «поднабора», в этом случае options представляет собой список допустимых типов поднабора (в нашем примере с сантехникой газовые нагреватели и электрические нагреватели могли бы иметь свои собственные типы активов со своим собственным набором полей, и экземпляр любого из них мог бы быть действительным значением для поля «water_heater».) Если для поля поднабора не указаны параметры типа, предполагается, что любой тип актива является допустимым.

Если пользователю должно быть разрешено вводить собственное значение в дополнение к, то можно использовать атрибут «прочее». Если «other» является логическим значением true, тогда в список параметров будет добавлена ​​опция «Other», и пользователь сможет ввести любое значение, которое ему нравится. «other» также может быть строкой, в этом случае это текст, который отображается как опция «Other», а метка в любом поле формы используется для ввода ввода пользователя.

Некоторые поля содержат несколько значений. В этих случаях атрибут «collection» имеет логическое значение true. По умолчанию одно и то же значение может появляться в коллекции несколько раз. Если это нежелательно, атрибут «уникальный» может использоваться для проверки того, что каждое значение появляется только один раз. Использование комбинаций «collection», «unique» и «options» может привести к довольно сложным формам поведения (которые будут показаны в будущем сообщении).

Есть также атрибуты «max» и «min». В коллекции значения атрибутов являются целыми числами, определяющими, сколько значений может быть в этой коллекции. В противном случае они представляют верхнюю и нижнюю границы значений integer, float, date и datetime.

Синтаксис определения до сих пор дает нам всю гибкость, необходимую для определения известных типов активов нашего проекта, и мы считаем, что в будущем он будет полезен для простого добавления новых типов и предоставления пользователям возможности определять свои собственные типы активов (возможно, через форму что переводится в определение JSON.)