В последнее время я довольно много копался в этом паттерне и могу сказать вам, что найти информацию о нем довольно сложно. Йегге называет это прототипом или свойствами, но оба они довольно сильно используются и известны как два других, различных паттерна. Некоторые люди называют системы, подобные той, что предлагает Йегге, «строго [sic] типизированными», так что это еще один путь исследований.
Это действительно изящная идея, и в одних приложениях она имеет массу достоинств, а в других - много недостатков. То, что вы получаете, по сути, является очень гибким средством построения «типов» во время выполнения, но вы теряете на многих языках строгую проверку типов, чтобы это сделать. Самый простой способ реализовать это как Dictionary<string,string>
. Затем вы должны использовать приведение, чтобы вернуть ваши строковые значения обратно в качестве фактических значений. Ключом к сохранению управляемости такого дизайна является то, что вы никогда не будете напрямую ссылаться на свойство в коде, если можете его избежать. Такие вещи, как theProtoObject["owner"] = "protoman"
убьют вас, если «каноническое» имя этого слота изменится. Это также может привести к таким проблемам, как JavaScript (который использует этот шаблон в качестве своей объектной модели), где, если вы неправильно введете имя ключа, вы добавите новый слот.
Одним из наиболее вероятных обновлений, которые вы, вероятно, сделаете в производственной системе, является использование каких-то специализированных типов для значений и некоторого «тяжелого ключа» для ключа, чтобы вы могли получить немного дополнительной типизации и безопасности. информация о вашей модели.
Я видел несколько приложений, которые его используют. Недавно меня поразил один удивительный пример, когда я искал открытый исходный код в своей отрасли: страхование котировок. OpenQuote - очень гибкий проект для цитирования страховки любого общего типа. Он написан на Java, но если вы знаете C #, он должен читаться довольно хорошо. В его основе лежит объект Type
, который содержит этот бит кода:
/** A dynamic collection of attributes describing type */
private List<Attribute> attribute = new ArrayList<Attribute>();
А что такое Attribute
? Это:
* An attribute is defined as "One of numerous aspects, as of a subject". Generally, another
* type will own a (composite) collection of Attributes which help describe it.
Таким образом, в основном Attribute
является своего рода парой ключ-значение, содержащей уникальный строковый идентификатор (имя поля) и строковое значение, а также перечисление типов в сочетании с некоторым регулярным выражением для проверки и обработки значений. Таким образом, он может хранить значения многих типов и преобразовывать их обратно в значения Java, обеспечивая при этом некоторую безопасность.
Затем продолжается построение множества типов моделей, специфичных для предметной области, поверх этого ядра. Таким образом, объект страхового полиса можно рассматривать как имеющий гибкий, расширяемый список преимуществ, который можно добавлять, удалять или изменять во время выполнения. Каждое преимущество может иметь свойства, расширенные или уменьшенные на них.
Итак, это пример используемой схемы и достойного варианта ее использования: страховые полисы могут быть очень гибкими по желанию андеррайтеров до момента продажи, поэтому очень гибкая модель хорошо работает для нее .
Недостатки - это в значительной степени то, что описывает Йегге. Производительность может быть плохой, особенно при наивной реализации. Проверка типов и безопасность наносят удар, и ваши объекты сложнее рассуждать, потому что вы точно не знаете, какие свойства у них.