Mam class Car
co ma 2 właściwości: int price
i boolean inStock
. Posiada również List
od abstract class State
(pustej klasie). Istnieją dwa stany, które można zastosować w samochodzie i każdy jest reprezentowany przez własną klasę: class Upgrade extends State
i class Shipping extends State
.
A Car
może pomieścić dowolną liczbę każdego z 2 stanów. Stany mają następujące zasady:
Upgrade
: dodaje1
się do ceny za każdy stan zastosowany do samochodu po sobie.Shipping
: jeśliShipping
na liście jest co najmniej 1 stan, toinStock
jest ustawione nafalse
.
Na przykład zaczynając od price = 1
i inStock = true
:
add Shipping s1 --> price: 1, inStock: false
add Upgrade g1 --> price: 1, inStock: false
add Shipping s2 --> price: 2, inStock: false
add Shipping s3 --> price: 3, inStock: false
remove Shipping s2 --> price: 2, inStock: false
remove Upgrade g1 --> price: 1, inStock: false
remove Shipping s1 --> price: 1, inStock: false
remove Shipping s3 --> price: 1, inStock: true
Myślałem o wzorcu obserwatora, w którym każda operacja dodawania i usuwania powiadamia obserwatorów. Miałem na myśli coś takiego, ale to nie jest zgodne z zasadami, które ustanowiłem:
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);
}
}
Oczywiście to nie działa. Kiedy a Shipping
jest usuwane, coś musi sprawdzić, czy istnieje inne ustawienie stanu inStock
na false, więc usunięcie Shipping
nie może po prostu inStock = true
. Upgrade
zwiększa się price
przy każdym połączeniu. Następnie dodałem stałe wartości domyślnych i spróbowałem ponownie je obliczyć.
W żadnym wypadku nie próbuję narzucać żadnego wzorca, staram się tylko znaleźć rozwiązanie dla powyższych wymagań. Należy zauważyć, że w praktyce Car
zawiera wiele właściwości i istnieje wiele stanów, które można zastosować w ten sposób. Pomyślałem o kilku sposobach:
- Ponieważ każdy obserwator odbiera
Car
, może patrzeć na wszystkich innych aktualnie zarejestrowanych obserwatorów i na tej podstawie dokonać zmiany. Nie wiem, czy mądrze jest uwikłać takich obserwatorów. - Po dodaniu lub usunięciu obserwatora
Car
nastąpi ponowne obliczenie. Jednak to ponowne obliczenie będzie musiało zostać wykonane na wszystkich obserwatorach, niezależnie od tego, który został właśnie dodany / usunięty. - Mieć zewnętrzną klasę „manager”, która wywoła metody dodawania i usuwania i wykonuje ponowne obliczenia.
Jaki jest dobry wzorzec projektowy do wdrożenia opisanego zachowania i jak by to działało?