Контейнер властивостей (шаблон проєктування)

Контейнер властивостей (англ. Property Container) — шаблон проєктування, який дозволяє розширювати властивості об'єкта під час виконання програми.

Переваги та недоліки[ред. | ред. код]

Переваги[ред. | ред. код]

  • Дозволяє змінювати об'єкт під час виконання програми.
  • Оскільки назва властивості описується стрічкою, це дозволяє використати довільний ідентифікатор обійшовши обмеження мови програмування. Наприклад, назва властивості може містити пропуски, починатись із цифри, тощо.
  • Корисний коли наперед невідомо, яку властивість треба використати, при цьому механізм рефлексії не підтримується.

Недоліки[ред. | ред. код]

  • Втрачається сувора типізація властивостей.
  • Контейнер властивостей по суті являється геш-таблицею. Однак із точки зору ООП представляти конкретні об'єкти не їх типом, а структурою даних вважається некоректним.

Реалізація[ред. | ред. код]

Нехай, необхідно заповнювати об'єкт властивостями в міру їх появи у системі. Тоді опишемо інтерфейс нашого класу.

public interface IPropertyContainer {       void SetProperty<T>(string name, T value);       T GetProperty<T>(string name);       string[] GetPropertyNames();       void RemoveProperty(string name);       void RemoveProperties(); } 

Для того, щоб не дублювати логіку контейнера властивостей у багатьох класах її можна винести в базовий клас ієрархії.

public abstract class PropertyContainerBase : IPropertyContainer {       private IDictinary<string, object> _properties = new Dictionary<string, object>();        public void SetProperty<T>(string name, T value)       {           _properties[name] = value;       }        public T GetProperty<T>(string name)       {           return (T) _properties[name];       }        public string[] GetPropertyNames()       {           return _properties.Keys.ToArray();       }        public void RemoveProperty(string name)       {           _properties.Remove(name);       }        public void RemoveProperties()       {           _innerProperties.Clear();       } } 

Тепер опишемо конкретний клас.

public class User : PropertyContainerBase {      public string Name { get; set; }  } 

Тоді властивості можна додавати та видаляти під час виконання програми, наприклад отримуючи команди від користувача.

User user = new User() {     Name = "John"; } user.SetProperty("Surname", "Doe");   . . .  var propertyName = Console.ReadLine(); var propertyValue = Console.ReadLine();  user.SetProperty(propertyName, propertyValue);   . . .   var propertiesToDelete = new [] { "Age" };  foreach (var property in propertiesToDelete) {     user.RemoveProperty(property); } 

Деякі динамічні мови програмування підтримують цей шаблон, за допомогою вбудованого механізму мови, наприклад, JavaScript. Наступні способи ініціалізації об'єктів ідентичні.

// ініціалізація властивостей var user = {     name: "John",     display() {         console.log(this.name);     }, };  // ініціалізація масивом var user = { }; user["name"] = "John"; user["display"] = function() {     console.log(user.age); };  // отримати список властивостей const properties = Object.keys(user);  // видалення властивостей delete user.name; delete user["display"]; 

Див. також[ред. | ред. код]

Джерела[ред. | ред. код]