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

Матеріал з Вікіпедії — вільної енциклопедії.
Перейти до навігації Перейти до пошуку

Контейнер властивостей (англ. 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"];

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

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