Контейнер властивостей (шаблон проєктування)
Зовнішній вигляд
Контейнер властивостей (англ. 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.]