Активний об'єкт () — шаблон проектування, який відокремлює виконання методу від виклику методу для об'єктів, кожен з яких знаходиться у власному потоці керування. Мета полягає в тому, щоб запровадити паралелізм за допомогою асинхронного виклику методів і планувальника для обробки запитів.Bass, L., Clements, P., Kazman, R. Software Architecture in Practice. Addison Wesley, 2003

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

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

Приклад

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

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

class MyClass {

    private double val = 0.0;

    void doSomething() {         val = 1.0;

    void doSomethingElse() {         val = 2.0;

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

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

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;

);

Див. також Модель акторів

Примітки

Посилання Ultra-high performance middleware based on Disruptor Active Object in C++14 Active Object implementation in C++11