Observer Pattern — Intro
الـ "Publish-Subscribe" — One object notifies a collection of others about changes.
الـ Observer Pattern = pattern behavioral بـ "publish/subscribe":
- عند ما object واحد بيتغير state، بيـ notify a collection of other objects.
- الـ observers بيسجّلوا نفسهم عند الـ observable / subject.
- الـ Subject بيحتفظ بـ collection of observers.
- عند تغيير state، الـ Subject بيخبّر كل الـ observers تلقائياً.
state: a=50% b=30% c=20%
3 different observers بيرسموا نفس الـ data بطرق مختلفة. عند تغيير الـ Subject، كل الـ Observers يتم تحديث تلقائياً.
- Office Boy: "I'm here at your service" (subscribe/register)
- Manager: "Thanks. I'll call you when I need you" (subject acknowledges)
- Manager (later): "Hey, I have something to ask you for." (notify)
- Office Boy: "Sure, what do you need?" (update)
- Manager: "Please, can I have a cup of tea?" (specific event)
الـ Manager (Subject) doesn't know exactly what each Office Boy (Observer) will do — they handle their own reactions.
UML Structure
4 classes: Subject + Observer interfaces + their concrete implementations.
┌────────────────────────────┐ ┌──────────────────────────┐
│ Subject │ ◇ ─────→│ «interface» Observer │
├────────────────────────────┤observers├──────────────────────────┤
│ -observers : List │ │ +update() │
│ +attach(o : Observer) │ └──────────────────────────┘
│ +detach(o : Observer) │ △
│ +notify() │ │ implements
└────────────────────────────┘ │
△ ┌───────────────────────────┐
│ extends │ ConcreteObserver │
┌────────────────────────────┐ ├───────────────────────────┤
│ ConcreteSubject │ ←observes│ -observerState │
├────────────────────────────┤ │ -subject : ConcreteSubject│
│ -subjectState │ │ +update() │
│ +getState() │ └───────────────────────────┘
│ +setState() │
└────────────────────────────┘
Note on notify(): "For all x in observers { x.update(); }"
Note on update(): "observerState = subject.getState();"
Observable + Observer.4 Key Players
كل player له responsibility محدد.
- يحتفظ بـ list of observers.
- Interfaces للـ attach / detach observers.
notify()method = loop on observers and call update on each.
- Updating interface للـ objects اللي بيوصلها الـ notification.
- الـ method الأساسية:
update(). - Defines the contract لكل observer.
- Stores "state of interest" للـ observers.
- Sends notification when state changes (calls
notify()). - Provides
getState(),setState().
- Implements
update(). - Has reference to its
ConcreteSubject. - Maintains its own state synchronized with the subject.
Sequence Flow
The order of interactions when state changes.
Lifelines: :ConcreteSubject · :ConcreteObserver-1 · :ConcreteObserver-2
- External or internal call invokes
setState()on:ConcreteSubject. :ConcreteSubjecttriggers internalnotify()cycle.:ConcreteSubjectsendsupdate()message to:ConcreteObserver-1.:ConcreteObserver-1responds by callinggetState()back on:ConcreteSubjectto fetch the new data.:ConcreteSubjectsendsupdate()message to:ConcreteObserver-2.:ConcreteObserver-2responds by callinggetState()back on:ConcreteSubjectto fetch the new data.
getState(). في الـ push model، الـ Subject بيدفع (push) الـ data كـ parameter في الـ update().Java Implementation ⭐ (Winter 2023 Q3)
الـ Java standard library فيه Observable class و Observer interface (deprecated بعد Java 9 لكنها لسه في الـ exam).
| Class/Interface | Method Summary |
|---|---|
interface Observer | void update(Observable o, Object arg) — called when observed object is changed. |
class Observable | void addObserver(Observer o) — adds observer to set. |
void notifyObservers() — if changed, notify all observers. | |
protected void setChanged() — marks this Observable as having been changed. |
import java.util.Random;
class Subject1 {
public String getNumber() {
Random random = new Random();
int randNum = random.nextInt(10000);
return String.valueOf(randNum);
}
}
class Client {
private Subject1 subject;
public void setSubject(Subject1 subject) {
this.subject = subject;
}
public void update() {
System.out.println("Client got num: " + subject.getNumber());
}
}
public class Main {
public static void main(String[] args) {
Subject1 subject = new Subject1();
Client client = new Client();
client.setSubject(subject);
client.update(); // Client manually pulls — no auto-notify
}
}
الـ goal: لما Subject.getNumber() يتعمل call، الـ Client يوصله notification تلقائياً.
1️⃣ Imports + Client (implements Observer)
import java.util.Observer;
import java.util.Observable;
class Client implements Observer { // 0.5 mark
private Subject subject;
public void setSubject(Subject subject) {
this.subject = subject;
subject.addObserver(this); // 1 mark — register self
}
public void update(Observable subject, Object newNum) { // 0.5 mark
System.out.println("Client got new num: " + newNum);
}
}
2️⃣ Subject (extends Observable)
class Subject extends Observable { // 0.5 mark
public String getNumber() {
Random random = new Random();
int randomNumber = random.nextInt(100);
String newNum = String.valueOf(randomNumber);
setChanged(); // 0.5 mark — mark dirty
notifyObservers(newNum); // 1 mark — auto-notify everyone
return newNum;
}
}
3️⃣ Main (Loop demo)
public class Main {
public static void main(String[] args) {
Subject subject = new Subject();
Client client = new Client();
client.setSubject(subject);
for (int i = 0; i < 10; i++) {
subject.getNumber(); // Observer auto-notified each time
}
}
}
┌─────────────────────────┐ ┌──────────────────────────┐
│ «interface» Observer │ │ Observable │
├─────────────────────────┤ ├──────────────────────────┤
│ +update(Observable,Obj) │ ←───── │ +addObserver(Observer) │
└─────────────────────────┘ │ +notifyObservers() │
△ │ +setChanged() │
│ implements └──────────────────────────┘
│ △
┌─────────────────────────┐ │ extends
│ Client │ │
├─────────────────────────┤ ┌──────────────────┐
│ -subject : Subject │─────────────→│ Subject │
│ +setSubject(Subject) │ ├──────────────────┤
│ +update(Observable,Obj) │ │ +getNumber():Str │
└─────────────────────────┘ └──────────────────┘
MVC — Model View Controller
Architectural pattern (مش design pattern). أعم وأشمل من Strategy/Observer.
- MVC = Architectural pattern (high level). مش زي Strategy/Observer.
- بيقسّم الـ whole application لـ 3 separate parts.
- معروف قبل GoF design patterns — موجود من 1979.
- Sun (Java): "MVC is the recommended architectural design pattern for interactive applications."
- Data + business logic
- Rules, strategies
- Observable (Subject)
- Notifies Views of changes
- Displays the Model
- Observer of Model
- UI representation
- Can have edit components
- Accepts user input
- Mediates: View ↔ Model
- Sends messages to Model
- In Java: listeners are controllers
MVC Roles & Data Flow
كل component له responsibilities محددة. الـ flow بيدور كذا الشكل.
- Provide access to the state of the system.
- Provide access to the system's functionality.
- Can notify the view(s) that its state has changed.
⚠️ Model = Observable
- Display the state of the model to the user.
- Register with the model (Model = observable, Views = observers).
- Get notified when Model state changes.
👁️ View = Observer
- Accept user input: clicks, key presses, mouse, sliders.
- Send messages to Model (may trigger notifications).
- Send appropriate messages to View.
🎧 Controller = Listener in Java
- أحياناً في برامج صغيرة، Controller + View بيتجمعوا.
- Appropriate لما الـ Controller و View very interdependent.
- The Model should remain independent.
- Clarity of design — easier to implement and maintain.
- Modularity — changes to one module don't affect others. Can develop in parallel.
- Multiple views — same model can have many views (games, spreadsheets, PowerPoint, Eclipse, UML tools).
MVC + Observer Pattern Connection
الـ MVC بيستخدم الـ Observer pattern للـ communication بين Model و View.
| MVC Role | Observer Pattern Role |
|---|---|
| Model | Subject (Observable) |
| View | Observer (ConcreteObserver) |
| Controller | External trigger (calls Model.setState) |
@Observable (1), @EventListener (2), @Observer (3) ويسأل ايه classes 1, 2, 3 بالترتيب؟ الإجابة: Model, Controller, View.| Layer | Class | Role |
|---|---|---|
| Model | Game | Grid arrays · game state · turn logic · rule evaluation |
| View | TextFieldView | Display rows/columns as text fields |
| View | DrawingView | Custom graphical X/O rendering |
| Controller | MouseListener | Mouse input handler |
| Controller | ActionListener | Button events |
Multiple views للـ same game model — text version أو drawing version. لما الـ Model يتغير، الاثنين يتم تحديث.
┌──────────────────┐ notify ┌──────────────────────────┐
│ TTTGame (Model) │ ──────────→ │ GameListener (Controller)│
│ observable │ │ implements ActionListener │
└──────────────────┘ ├──────────────────────────┤
│ +actionPerformed() │
└──────────────────────────┘
↑
│ implements
┌──────────────────────────┐
│ «interface» Observer │
│ (ActionListener) │
└──────────────────────────┘
في Java Swing، الـ JFrame = view container, ActionListener = controller. الـ Game logic = Model — completely separate من الـ UI.
MVP Variation
Model-View-Presenter — an updated MVC variation.
الـ MVP بيستبدل الـ Controller بـ Presenter. الـ Presenter:
- Communicates with both Model and View directly.
- Mediates more strictly than Controller — لا تواصل مباشرة بين Model و View.
- Updates the state in Model via
setState()+ retrieves data viaget. - Instructs the View directly via
changeView().
الفرق المهم: في MVC الـ View بيراقب Model مباشرة. في MVP الـ View ما يعرفش الـ Model — كل التواصل يمر عبر الـ Presenter.
| Aspect | MVC | MVP |
|---|---|---|
| 3rd Component | Controller | Presenter |
| View ↔ Model | Direct (Observer) | Indirect (via Presenter) |
| Testability | Harder (View tied to Model) | Easier (Presenter is testable) |
| Common in | Web frameworks, classic GUI | Android (old), .NET |
Exam Bank — Lecture 13
8 أسئلة على Observer و MVC. Q3 Winter 2023 ضم Observer implementation كاملة.
notifyObservers(customerData) وكل observer يستجيب.
@Observable (1), @EventListener (2), @Observer (3), what are classes 1, 2, 3 in order?- Model =
@Observable(notifies of state changes) - Controller =
@EventListener(responds to events) - View =
@Observer(receives notifications)
notifyObservers() for observers to actually be notified?Observable class بيتطلّب إنك تستدعي setChanged() الأول لـ mark the observable as having been changed. لو ما قلتش بـ كده، notifyObservers() ما يفعلش شيء.
List<Observer> ويوفّر methods لـ attach() و detach() الـ observers.
ActionListener plays the role of:actionPerformed()). ده exactly الـ Observer pattern.
في MVC: ActionListener = Controller. الـ Observer pattern یستخدم تحت بـ Java Swing implementation.
Cheat Sheet
Observer + MVC quick reference.
📡 Observer Pattern — 4 Players
☕ Java Observer API
🏗️ MVC Architecture
✅ MVC Benefits
🆚 MVC vs MVP
🔗 Observer ↔ MVC Mapping
Rapid Revision
Flashcards · Common Mistakes · Doctor favorites.
🚨 Common Mistakes
⭐ What Dr. El-Ramly Loves
- Q1.17 Pub-Sub scenario (water company / banking) — Observer.
- Q1.18 MVC role identification — مرتبط بـ Observer terminology.
- Q3 Winter 2023 Observer Pattern in Java with Subject + Observable + setChanged + notifyObservers.
- Recurring conceptual — when notify-many is needed, use Observer.