Announcements
The original Smalltalk-80 dependency mechanism (addDependent:, changed:, update:) is still present, but modern Pharo code uses Announcements: typed events delivered by an Announcer.
33.1 Observer, the Smalltalk way
The original Smalltalk-80 dependency mechanism (addDependent:, changed:, update:) is still present, but modern Pharo code uses Announcements: typed events delivered by an Announcer.
33.2 Defining announcements
(setAccount:from:to: assigns the three slots; add a newBalance getter.)
Announcement << #BalanceChanged
slots: { #account . #oldBalance . #newBalance };
package: 'Bank-Core'
BalanceChanged class >> account: anAccount from: old to: new
^ self new setAccount: anAccount from: old to: new33.3 Announcing
"Add an #announcer slot to BankAccount, initialized lazily"
BankAccount >> announcer
^ announcer ifNil: [ announcer := Announcer new ]
BankAccount >> deposit: anAmount
| old |
old := balance.
balance := balance + anAmount.
self announcer announce: (BalanceChanged account: self from: old to: balance)33.4 Subscribing
BalanceChanged , AccountClosed subscribes to several announcement classes at once.
| acct |
acct := BankAccount owner: 'Ada'.
acct announcer
when: BalanceChanged
do: [ :ann | Transcript crShow: 'New balance: ' , ann newBalance printString ]
for: self. "subscriber: used to unsubscribe later"
acct deposit: 50. "Transcript: New balance: 50"
acct announcer when: BalanceChanged send: #balanceChanged: to: aView. "message-based"
acct announcer unsubscribe: self. "remove all subscriptions of a subscriber"33.5 Notes
Subscriptions hold strong references by default; use acct announcer weak when: ... send: ... to: ... for weak subscriptions, or always unsubscribe when the subscriber goes away.
Announcements are delivered synchronously in the announcing process.
SystemAnnouncer uniqueInstance broadcasts system events (class added, method modified) — the basis for tools that refresh automatically.