Ho un class Car
che ha 2 proprietà: int price
e boolean inStock
. Detiene anche un List
di abstract class State
(classe vuota). Ci sono 2 stati che possono essere applicati sull'auto e ognuno è rappresentato dalla sua stessa classe: class Upgrade extends State
e class Shipping extends State
.
Un Car
può contenere qualsiasi numero di ciascuno dei 2 stati. Gli stati hanno le seguenti regole:
-
Upgrade
: aggiunge1
al prezzo per ogni stato applicato all'automobile dopo di sé. -
Shipping
: se c'è almeno l'1% di stato diShipping
nell'elenco, quindiinStock
è impostato sufalse
.
Ad esempio, iniziando con price = 1
e 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
Stavo pensando al modello di osservatore in cui ogni operazione di aggiunta e rimozione notifica agli osservatori. Avevo in mente qualcosa di simile, ma non obbedisce alle regole che ho posto:
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);
}
}
Ovviamente, questo non funziona. Quando viene rimosso un Shipping
, qualcosa deve controllare se c'è un altro stato che imposta inStock
su falso, quindi una rimozione di Shipping
non può essere solo inStock = true
. Upgrade
aumenta price
ad ogni chiamata. Ho quindi aggiunto costanti per i valori predefiniti e ho tentato un ricalcolo basato su quelli.
Non sto affatto cercando di imporre alcun modello, sto solo cercando di trovare una soluzione per i requisiti di cui sopra. Nota che in pratica Car
contiene molte proprietà e ci sono molti stati che possono essere applicati in questo modo. Ho pensato ad alcuni modi per farlo:
- Poiché ogni osservatore riceve
Car
, può guardare tutti gli altri osservatori attualmente registrati e apportare una modifica in base a ciò. Non so se è intelligente intrigare osservatori come questo. - Quando un osservatore viene aggiunto o rimosso in
Car
, ci sarà un ricalcolo. Tuttavia, questo ricalcolo dovrà essere eseguito su tutti osservatori indipendentemente da quello appena aggiunto / rimosso. - Avere una classe "manager" esterna che chiamerà i metodi add e remove e ricalcola.
Che cos'è un buon schema di progettazione per implementare il comportamento descritto e come funzionerebbe?