Devo creare una nuova classe?

0

Diciamo che ho una classe Car . Gli oggetti di questa classe verranno archiviati in una raccolta e ogni oggetto dovrebbe conoscere altri elementi della raccolta, poiché per ogni auto è necessario calcolare un valore in base agli elementi della raccolta a cui appartiene.

Questa è una generalizzazione del mio problema, ma penso che catturi l'idea in modo abbastanza accurato. Qual è l'approccio giusto a questo? Devo creare una nuova classe CarLogic , memorizzare le auto in una raccolta e mettere tutta la logica per eseguire questi calcoli nella nuova classe?

O forse è meglio mantenere il riferimento alla collezione a cui appartiene l'oggetto Car in% oggetti Car se la classe Car dovrebbe calcolare quei valori?

    
posta user5539357 03.03.2016 - 21:37
fonte

2 risposte

4

Hai tre problemi in questo codice:

  1. Aggregazione / memorizzazione di automobili (raccolta)
  2. Fare cose sulla macchina (auto).
  3. Calcola valori per più macchine (???).

Attualmente il calcolo non è assegnato a una classe. Dato che la preoccupazione è molto diversa dalle altre due, non ha senso mescolarla in una classe esistente. Ciò viola i SRP .

Un design pulito assegnerebbe questa preoccupazione a una nuova classe, un CarCalculator. A seconda dei requisiti di questo calcolo, potrebbe essere invocato in diversi modi. Due che vengono in mente:

  1. Il codice che popola la collezione di auto potrebbe creare la calcolatrice e invocarla nella raccolta.

    Collection<Car> cars = new CollectionType();
    // Populate cars
    new CarCalculator().calculate(cars);
    return cars;
    
  2. La raccolta stessa potrebbe essere estesa per richiamare la logica di calcolo.

    Collection<Car> cars = new MyCollectionType(new CarCalculator());
    // Populate cars: collection updates using its calculator
    return cars;
    

Il vantaggio di entrambe le soluzioni è che le auto non hanno bisogno di visibilità in una collezione (cosa succede se non sono in una?), e la collezione può fare ciò che sa fare meglio: contenere auto. La calcolatrice non ha bisogno di gestire le auto (aggiunta, rimozione, ecc.) Né memorizza le proprietà delle auto. Calcola solo cose.

    
risposta data 03.03.2016 - 22:07
fonte
0

Dipende dal tuo caso reale, ovvero le informazioni che devi recuperare da una raccolta.

In alcuni casi, un oggetto potrebbe avere una conoscenza limitata del proprio ambiente all'interno della raccolta. Ad esempio, gli elenchi con collegamento doppio possono funzionare in questo modo. Un Car conoscerà sia gli elementi precedenti che quelli successivi e utilizzerà queste informazioni per eseguire qualche azione o manifestare alcuni comportamenti (ad esempio, una macchina robotica current potrebbe seguire current.Previous e inviare segnali a current.Next in modo che il il prossimo seguirà la current car, oppure si potrebbe decidere che il comportamento di una lista doppiamente legata è la questione della lista stessa (e del codice che elabora la lista), e non è il business di Car a conosci la precedente o la prossima auto, in questo caso la lista userà un wrapper generico, come DoublyLinkedListItem<T> , ed è questo oggetto che conterrà sia l'oggetto Car che i riferimenti agli elementi precedente e successivo.

In altri casi, preferiresti mettere la logica al di fuori della classe Car , sia nella raccolta stessa (come un Train è un insieme di RailwayCar s con la sua logica corretta che non ha niente da fare all'interno di RailwayCar ), o in una classe molto diversa.

Infine, ci sono casi in cui la logica appartiene a Car stessa e dipende dalla collezione, ma la conoscenza della Car dei suoi dintorni non ha bisogno di essere estesa. Facciamo un esempio in cui una macchina ha bisogno di conoscere la potenza totale delle auto nella raccolta quando si avvia il motore. In questo caso, invece di dare all'automobile il riferimento all'intera collezione (e lasciare che ogni macchina attraversi l'intera collezione e fare i conti, individualmente), puoi semplicemente calcolare la somma e consegnarla all'automobile:

horsepower = cars.sum(c => c.horsepower);
sampleCar.startEngine(totalHorsepower: horsepower);
    
risposta data 03.03.2016 - 22:04
fonte

Leggi altre domande sui tag