I have a class Car which has 2 properties: int price and boolean inStock. It also holds a List of abstract class State (empty class). There are 2 states which can be applied on the car and each is represented by its own class: class Upgrade extends State and class Shipping extends State.A Car can hold any number of each of the 2 states. The states have the following rules:Upgrade: adds 1 to the price for each state applied to the car after itself.Shipping: if there is at least 1 Shipping state in the list, then inStock is set to false.For example, starting with price = 1 and inStock = true:add Shipping s1    --> price: 1, inStock: falseadd Upgrade g1     --> price: 1, inStock: falseadd Shipping s2    --> price: 2, inStock: falseadd Shipping s3    --> price: 3, inStock: falseremove Shipping s2 --> price: 2, inStock: falseremove Upgrade g1  --> price: 1, inStock: falseremove Shipping s1 --> price: 1, inStock: falseremove Shipping s3 --> price: 1, inStock: trueI was thinking about the observer pattern where each add and remove operations notify observers. I had something like this in mind, but it doesn't obey the rules I posed:abstract class State implements Observer {    public abstract void update();}class Car extends Observable {    List<State> states = new ArrayList<>();    int price = 100;    boolean inStock = true;    void addState(State state) {        if (states.add(state)) {            addObserver(state);            setChanged();            notifyObservers();        }    }    void removeState(State state) {        if (states.remove(state)) {            deleteObserver(state);            setChanged();            notifyObservers();        }    }}class Upgrade extends State {    @Override    public void update(Observable o, Object arg) {        Car c = (Car) o;        int bonus = c.states.size() - c.states.indexOf(this) - 1;        c.price += bonus;        System.out.println(c.inStock +   + c.price);    }}class Shipping extends State {    @Override    public void update(Observable o, Object arg) {        Car c = (Car) o;        c.inStock = false;        System.out.println(c.inStock +   + c.price);    }}Obviously, this doesn't work. When a Shipping is removed, something has to check if there is another state setting inStock to false, so a removal of Shipping can't just inStock = true. Upgrade increases price at each call. I then added constants for the default values and attempted a recalculation based on those.I am by no means trying to impose any pattern, I'm just trying to find a solution for the above requirements. Note that in practice Car contains many properties and there are many states that can be applied in this manner. I thought about a few ways to do this:Since each observer receives Car, it can look at all the other observers currently registered and make a change based on that. I don't know if it's smart to entangle observers like this.When an observer is added or removed in Car, there will be a recalculation. However, this recalculation will have to be done on all observers regardless of the one which was just added/removed.Have an external manager class which will call the add and remove methods and do the recalculation.What is a good design pattern to implement the described behavior and how would it work?
Is the observer pattern suitable when the observers are not independent of each other?
java;design patterns;observer pattern
I ended up going with option 3 - using an external manager. The manager is responsible for adding and removing States from Cars and for notifying the observers when these changes happen.Here is how I modified the code. I removed the Observable/Observer of the JDK because I'm doing my own implementation.Each State keeps a reference to the Car its applied to.abstract class State {    Car car;    State(Card car) { this.car = car; }    public abstract void update();}class Upgrade extends State {    @Override    public void update() {        int bonus = car.states.size() - car.states.indexOf(this) - 1;        car.price += bonus;        System.out.println(car.inStock +   + car.price);    }}class Shipping extends State {    @Override    public void update() {        car.inStock = false;        System.out.println(car.inStock +   + car.price);    }}Car only holds its state (to avoid confusion: properties) and does not handle adding and removing States:class Car extends Observable {    List<State> states = new ArrayList<>();    int price = 100;    boolean inStock = true;}Here is the manager. It has overtook Cars (the observable) job of managing its States (observers).class StatesManager {    public void addState(Card car, State state) {        car.states.add(state);        for (State state : car. states)            state.update;    }    public void removeState(Card car, State state) {        car.states.remove(state);        for (State state : car. states)            state.update;    }}A few things to keep in mind:All observers are notified about every change. A more clever event distribution scheme can eliminate unneeded calls to observers' update method.The observers might want to expose more update-like methods for different occasions. Just as an example, they can split the current update method to updateOnAdd and updateOnRemove if they are interested only in one of these changes. Then the addState and removeState methods would be updated accordingly. Along with the previous point this approach can end up as a robust, extensible and flexible mechanism.I did not specify what gives the instruction to add and remove States and when that happens as it is not important for the question. However, in the case of this answer, there is the following point to consider. Since State now must be created with its Car (no empty constructor exposed) prior to calling the manager's method, the addState and removeState methods do not need to take a Car and can just read it from state.car.The observers are notified in order of registration on the observable by default. A different order can be specified.