admin管理员组

文章数量:1122846

I am trying to implement the Observer design pattern in Java without using built-in libraries like java.util.Observer or PropertyChangeSupport. I want to create a simple system where observers (listeners) can subscribe to a subject and get notified whenever the state of the subject changes.

import java.util.ArrayList;
import java.util.List;

class Subject {
    private List<Observer> observers = new ArrayList<>();
    private String state;

    public void subscribe(Observer observer) {
        observers.add(observer);
    }

    public void unsubscribe(Observer observer) {
        observers.remove(observer);
    }

    public void setState(String state) {
        this.state = state;
        // Notify observers
    }

    public String getState() {
        return state;
    }
}

class Observer {
    private String name;

    public Observer(String name) {
        this.name = name;
    }

    public void update(String state) {
        System.out.println(name + ": " + state);
    }
}


What Did You Try and What Were You Expecting?
I tried iterating over the observers list in the setState method and calling an update method on each observer. I expected the observers to print the updated state, but I am not sure how to link the Subject and Observer classes correctly.

What Actually Happened?
Currently, the program compiles but doesn’t produce the expected output because I haven’t implemented the notification logic.

Expected Result:
I want the Subject class to notify all subscribed observers whenever the state changes, producing the following output:

Observer 1: State Changed!
Observer 2: State Changed!

I am trying to implement the Observer design pattern in Java without using built-in libraries like java.util.Observer or PropertyChangeSupport. I want to create a simple system where observers (listeners) can subscribe to a subject and get notified whenever the state of the subject changes.

import java.util.ArrayList;
import java.util.List;

class Subject {
    private List<Observer> observers = new ArrayList<>();
    private String state;

    public void subscribe(Observer observer) {
        observers.add(observer);
    }

    public void unsubscribe(Observer observer) {
        observers.remove(observer);
    }

    public void setState(String state) {
        this.state = state;
        // Notify observers
    }

    public String getState() {
        return state;
    }
}

class Observer {
    private String name;

    public Observer(String name) {
        this.name = name;
    }

    public void update(String state) {
        System.out.println(name + ": " + state);
    }
}


What Did You Try and What Were You Expecting?
I tried iterating over the observers list in the setState method and calling an update method on each observer. I expected the observers to print the updated state, but I am not sure how to link the Subject and Observer classes correctly.

What Actually Happened?
Currently, the program compiles but doesn’t produce the expected output because I haven’t implemented the notification logic.

Expected Result:
I want the Subject class to notify all subscribed observers whenever the state changes, producing the following output:

Observer 1: State Changed!
Observer 2: State Changed!

Share Improve this question asked Nov 23, 2024 at 5:06 SadeemSadeem 311 silver badge2 bronze badges
Add a comment  | 

2 Answers 2

Reset to default 3

Let me help you on your problem:

To implement a custom Observer Pattern in Java without using built-in libraries like java.util.Observer or PropertyChangeSupport, we can create a program like below:

Step 1: Define the Observer interface

public interface Observer {
    void update(String message); // Observer gets a notification
}

Step 2: Define the Subject Interface

public interface Subject {
    void registerObserver(Observer observer);  
    void unregisterObserver(Observer observer); 
    void notifyObservers(String message);       
}

Step 3: Implement the ConcreteSubject

import java.util.ArrayList;
import java.util.List;
    
public class ConcreteSubject implements Subject {
    private final List<Observer> observers  = new ArrayList<>(); // List to store observers
    
    @Override
    public void registerObserver(Observer observer) {
        observers.add(observer);
    }
    
    @Override
    public void unregisterObserver(Observer observer) {
        observers.remove(observer);
    }
    
    @Override
    public void notifyObservers(String message) {
        for (Observer observer : observers) {
            observer.update(message); // Notify each observer
        }
    }
}

Step 4: Implement the ConcreteObserver

public class ConcreteObserver implements Observer {
    // A unique identifier for the observer
    private final String name; 

    public ConcreteObserver(String name) {
        this.name = name;
    }

    @Override
    public void update(String message) {
        System.out.println(name + " received update: " + message);
    }
}

And we can test the observer pattern like below:

public class ObserverPatternTest {
    public static void main(String[] args) {
        // Create the subject
        ConcreteSubject subject = new ConcreteSubject();
        
        // Create observers
        Observer observer1 = new ConcreteObserver("Observer 1");
        Observer observer2 = new ConcreteObserver("Observer 2");
        Observer observer3 = new ConcreteObserver("Observer 3");
        
        // Register observers
        subject.registerObserver(observer1);
        subject.registerObserver(observer2);
        subject.registerObserver(observer3);
        
        // Notify observers
        System.out.println("State change 1st time.....");
        subject.notifyObservers("First Update");
        
        // Unregister an observer and send another notification
        subject.unregisterObserver(observer2);
        System.out.println("State change 2nd time.....");
        subject.notifyObservers("Second Update");
    }
}

Output:

State change 1st time.....
Observer 1 received update: First Update
Observer 2 received update: First Update
Observer 3 received update: First Update
State change 2nd time.....
Observer 1 received update: Second Update
Observer 3 received update: Second Update

Your Observer needs to have some action associated with it. When state changes, that action will get triggered.

public class Driver {
    public static void main(String[] args) {
        Subject subject = new Subject();
        
        new Thread(() -> {
            Observer observer = new Observer(subject, value -> 
                System.out.println("Successfully executed this with value: "+value+" inside thread : "+Thread.currentThread().getName())
            );
            try {
                subject.subscribe(observer);
            }
            catch(Exception ex) {
                
            }
        }).start(); 
        
        new Thread(() -> {
            for(int i=0;i<100;i++) {
                String value = "hello"+i;
                System.out.println("Updating the state to: "+value);
                subject.setState(value);
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }).start();
    }
}
class Subject {
    private List<Observer> observers = new ArrayList<>();
    private String state;

    public void subscribe(Observer observer) {
        observers.add(observer);
    }

    public void unsubscribe(Observer observer) {
        observers.remove(observer);
    }

    public void setState(String state) {
        this.state = state;
        observers.forEach(observer -> observer.update(state));
    }

    public String getState() {
        return state;
    }
}

interface Action{
    
    public void doSomething(String value);
}

class Observer {
    private Action action;
    private Subject subject;

    public Observer(Subject subject, Action action) {
        this.subject = subject;
        this.action = action;
    }

    public void update(String state) {
        // you can log subject or do something else
        action.doSomething(state);
    }
}

本文标签: oopHow to Implement a Custom Observer Pattern in Java Without Using Builtin LibrariesStack Overflow