Контейнер властивостей (шаблон проєктування)
Контейнер властивостей (англ. 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"];
Див. також[ред. | ред. код]
Джерела[ред. | ред. код]
- Шаблоны проектирования. Введение [Архівовано 20 жовтня 2020 у Wayback Machine.]