Загалом, так, слід використовувати слабкі посилання. Але спочатку нам повинно бути зрозуміло, що ви маєте на увазі під «слухачами подій».
Відкликання дзвінків
У деяких стилях програмування, особливо в умовах асинхронних операцій, прийнято представляти частину обчислення як зворотний виклик, який виконується в певну подію. Наприклад, Promise
[ 1 ] може мати then
метод, який реєструє зворотний виклик після завершення попереднього кроку:
promise =
Promise.new(async_task) # - kick off a task
.then(value => operation_on(value)) # - queue other operations
.then(value => other_operation(value)) # that get executed on completion
... # do other stuff in the meanwhile
# later:
result = promise.value # block for the result
Тут зареєстровані зворотні дзвінки then
повинні мати чіткі посилання, оскільки обіцянка (джерело події) є єдиним об'єктом, що містить посилання на зворотний виклик. Це не проблема, оскільки сама обіцянка має обмежений термін експлуатації, і сміття збиратиметься після завершення ланцюга обіцянок.
Шаблон спостерігача
У шаблоні спостерігачів суб'єкт має список залежних спостерігачів. Коли суб'єкт переходить у певний стан, спостерігачів повідомляють відповідно до деякого інтерфейсу. Спостерігачі можуть бути додані до теми та видалені з них. Ці спостерігачі не існують у семантичному вакуумі, але чекають подій з якоюсь метою.
Якщо цієї мети більше не існує, спостерігачів слід видалити з теми. Навіть у мовах, зібраних зі сміттям, це вилучення, можливо, доведеться виконувати вручну. Якщо ми не зможемо видалити спостерігача, він буде зберігатися в живих за допомогою посилання від суб'єкта до спостерігача, а разом з цим і всіх об'єктів, на які спостерігач посилається. Це втрачає пам'ять і погіршує продуктивність, оскільки (зараз марний) спостерігач все ще буде повідомлений.
Слабкі посилання виправляють цю витік пам'яті, оскільки вони дозволяють спостерігачеві збирати сміття. Коли суб'єкт проходить навколо, щоб повідомити всіх спостерігачів і виявить, що одне зі слабких посилань на спостерігача порожнє, це посилання може бути безпечно видалено. Крім того, слабкі посилання можуть бути реалізовані таким чином, що дозволяє суб'єкту зареєструвати зворотний виклик очищення, який видалить спостерігача після збору.
Але зауважте, що слабкі посилання - це лише допомога, яка обмежує шкоду, забуваючи зняти спостерігача. Правильним рішенням було б зробити так, щоб спостерігач був відсторонений, коли це вже не потрібно. Варіанти включають:
Робити це вручну, але це схильне до помилок.
Використовуючи щось подібне для пробного використання ресурсу на Java або using
в C #.
Детерміновані руйнування, наприклад, через ідіому RAII. Зауважте, що в мові з детермінованим вивезенням сміття це все ще може вимагати слабких посилань суб'єкта на спостерігача, щоб викликати руйнівник.