Fundamentals 12 min read

Mastering the Observer Pattern: Real‑World Java and PHP Examples

This article explains the Observer design pattern, outlines its advantages and drawbacks, and demonstrates practical implementations through three real‑world scenarios—weather forecasting, payment processing, and data subscription—providing complete Java and PHP code samples that illustrate subjects, observers, and notification mechanisms.

Baidu Geek Talk
Baidu Geek Talk
Baidu Geek Talk
Mastering the Observer Pattern: Real‑World Java and PHP Examples

The Observer pattern decouples a single subject from multiple observers so that the subject can broadcast state changes without knowing the concrete observer implementations. It reduces coupling and provides a built‑in change‑trigger mechanism, but can introduce circular dependencies and performance overhead when many observers exist.

01 Observer Pattern in a Weather Forecast Scenario

In this scenario the weather (the WeatherSubject) is the subject. Various roles such as a meteorological department, rescue department, office workers and other citizens act as observers. When the weather state changes, each observer receives a notification and reacts accordingly.

package com;
import java.util.ArrayList;
import java.util.List;

public class ObserverPatternDemo {
    // Subject
    static class WeatherSubject {
        private int state;
        List<Observer> observers = new ArrayList<>();
        void attach(Observer observer) { observers.add(observer); }
        void notifyAllObservers() { for (Observer o : observers) { o.update(state); } }
        public int getState() { return state; }
        public void setState(int state) {
            this.state = state;
            if (state == 1) {
                System.out.println("=====明天要下大暴雨=====");
            } else {
                System.out.println("=====明天天气很好呀=====");
            }
            notifyAllObservers();
        }
    }
    // Abstract observer
    static abstract class Observer { abstract void update(int state); }
    // Concrete observers
    static class MeteorologicalDepartment extends Observer {
        @Override void update(int state) { if (state == 1) System.out.println("【气象部门】发出预警"); }
    }
    static class RescueDepartment extends Observer {
        @Override void update(int state) { if (state == 1) System.out.println("【救援部门】准备应急预案"); }
    }
    static class OfficeWorker extends Observer {
        @Override void update(int state) {
            if (state == 1) System.out.println("【打工人】思考明天怎么上下班通勤");
            else System.out.println("【打工人】努力搬砖");
        }
    }
    static class Other extends Observer {
        @Override void update(int state) {
            if (state == 1) System.out.println("【其他人】下雨啊,对我影响不大");
            else System.out.println("【其他人】明天天气不错,出去玩玩");
        }
    }
    public static void main(String[] args) {
        WeatherSubject subject = new WeatherSubject();
        subject.attach(new MeteorologicalDepartment());
        subject.attach(new RescueDepartment());
        subject.attach(new OfficeWorker());
        subject.attach(new Other());
        subject.setState(1); // heavy rain
        subject.setState(2); // good weather
    }
}

02 Observer Pattern in a Payment Processing Scenario

When a payment succeeds, several independent actions—order status update, SMS notification, logistics preparation—must be performed. The Pay class acts as the subject and notifies all registered observers without being coupled to their concrete implementations, satisfying the Open/Closed principle.

// Abstract subject (Observable)
public abstract class Observable {
    private List<Observer> observers = new ArrayList<>();
    public void add(Observer observer) { observers.add(observer); }
    public void remove(Observer observer) { observers.remove(observer); }
    protected void notifyObservers() { for (Observer o : observers) { o.update(); } }
}

// Concrete subject
public class Pay extends Observable {
    public void pay() {
        System.out.println("支付完成.");
        super.notifyObservers();
    }
}

// Observer interface
public interface Observer { void update(); }

// Concrete observers
public class Order implements Observer {
    @Override public void update() { System.out.println("修改订单状态..."); }
}
public class SMS implements Observer {
    @Override public void update() { System.out.println("账户扣款短信通知..."); }
}
public class Express implements Observer {
    @Override public void update() { System.out.println("物流开始备货..."); }
}

// Client usage
public class Client {
    public static void main(String[] args) {
        Pay pay = new Pay();
        pay.add(new Order());
        pay.add(new SMS());
        pay.add(new Express());
        pay.pay();
    }
}

03 Observer Pattern in a Data Subscription Scenario

In data‑push use cases such as publishing new novel chapters, multiple downstream services (search, cloud storage, forums, etc.) need to react. Each subscriber implements its own push method, and the publisher notifies all registered observers when new data arrives.

interface Observer { public function push($data); }

class Publish {
    private $observers = array();
    public function register(Observer $observer) { $this->observers[] = $observer; }
    public function delete(Observer $observer) {
        $index = array_search($observer, $this->observers);
        if ($index !== FALSE && array_key_exists($index, $this->observers)) {
            unset($this->observers[$index]);
        }
    }
    public function push($data) { foreach ($this->observers as $observer) { $observer->push($data); } }
}

class Search implements Observer { public function push($data) { /* push to AFS */ } }
class Cloud implements Observer { public function push($data) { /* push to Kafka */ } }

$publish = new Publish();
$publish->register(new Search());
$publish->register(new Cloud());
$publish->push($data);

Summary

The Observer pattern is appropriate when:

Multiple observers depend on a single subject (many‑to‑one relationship).

Changes in the subject must trigger a cascade of actions in the observers.

Using observers decouples the subject from concrete observers, simplifying extension and maintenance while keeping the subject unaware of which observers are registered.

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

Design PatternsJavaSoftware ArchitecturePHPObserver Pattern
Baidu Geek Talk
Written by

Baidu Geek Talk

Follow us to discover more Baidu tech insights.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.