Активний об'єкт (англ. Active object) — шаблон проектування, який відокремлює виконання методу від виклику методу для об'єктів, кожен з яких знаходиться у власному потоці керування.[1] Мета полягає в тому, щоб запровадити паралелізм за допомогою асинхронного виклику методів і планувальника для обробки запитів.[2]

Шаблон складається з шести елементів:[3]

  • Об'єкт-замісник (проксі), який забезпечує інтерфейс для клієнтів із загальнодоступними методами.
  • Інтерфейс, який визначає методу доступу до активного об'єкта.
  • Список поступаючих запитів від клієнтів.
  • Планувальник, який вирішує, який запит виконати наступним.
  • Реалізація методів активного об'єкта.
  • Процедура зворотного виклику або змінна для отримання клієнтом результату.

Приклад ред.

Java ред.

Приклад шаблону активного об'єкта в Java . [4]

Далі наведено стандартний клас, який надає два методи, кожен з яких встановлює певне значення типу double для змінної val. Цей клас НЕ відповідає шаблону активного об’єкта.

class MyClass {

    private double val = 0.0;

    void doSomething() {
        val = 1.0;
    }
    void doSomethingElse() {
        val = 2.0;
    }
}

Клас є небезпечним у багатопоточному сценарії, оскільки обидва методи можуть бути викликані одночасно, тому значення val може бути невизначеним — це класична умова гонки. Можна використовувати синхронізацію для вирішення цієї проблеми, що в цьому тривіальному випадку легко. Але як тільки клас стає складним, синхронізація може стати дуже складною. [4]

Для того, щоб переписати цей клас саме як активний об’єкт, можна зробити наступне:

class MyActiveObject {

  private double val = 0.0;
  private BlockingQueue<Runnable> dispatchQueue = new LinkedBlockingQueue<Runnable>();

  public MyActiveObject() {
    new Thread (new Runnable() {
          
        @Override
        public void run() {
          try {
            while (true) {
              dispatchQueue.take().run();
            }
          } catch (InterruptedException e) {  
            // ok, перервати диспетчер
          }
        }
      }
    ).start();
  }

  void doSomething() throws InterruptedException {
    dispatchQueue.put(new Runnable() {
        @Override
        public void run() { 
          val = 1.0; 
        }
      }
    );
  }

  void doSomethingElse() throws InterruptedException {
    dispatchQueue.put(new Runnable() {
        @Override
        public void run() { 
          val = 2.0; 
        }
      }
    );
  }
}

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

Примітки ред.

  1. Douglas C. Schmidt; Michael Stal; Hans Rohnert; Frank Buschmann (2000). Pattern-Oriented Software Architecture, Volume 2: Patterns for Concurrent and Networked Objects. John Wiley & Sons. ISBN 0-471-60695-2. 
  2. Bass, L., Clements, P., Kazman, R. Software Architecture in Practice. Addison Wesley, 2003
  3. Lavender, R. Greg; Schmidt, Douglas C. Active Object. Архів оригіналу за 22 липня 2012. Процитовано 2 лютого 2007. 
  4. а б Holub, Allen. Java Active Objects - A Proposal. Архів оригіналу за 22 червня 2013. Процитовано 16 червня 2014. 

Посилання ред.