Domanda orientata agli oggetti Java - 2

1

Questa è un'altra domanda di follow up sulla progettazione orientata agli oggetti in generale. Sto cercando di suddividerli per separare le domande per consiglio che ho ricevuto da @ Jay in precedenza.

Ho una nuova domanda, quasi ogni fase del processo di progettazione OO. Ho cercato di ottenere le idee da libri, articoli e il web. Diventa solo più confuso. Mi piacerebbe avere qualche consiglio da parte degli esperti qui, quindi posso avere i miei concetti giusti.

Supponiamo di avere gli oggetti seguenti:

public class AddressRecord {
  protected String addressLine1;
  protected String addressLine2;
  protected String city;
  protected String state;
  protected String postalCode;
  protected String country;
  ....
}

public class AddressValidationRequest {
  private AddressRecord addresses[];
  protected ArrayList      actions;
  protected ArrayList      columns;
  protected Properties     options;
  ...
}

Devo mantenere AddressRecord completamente nascosto all'interno di Request (è Aggregation?) o esporre e accedere a AddressRecord dall'esterno (Composition)?

(Per me, anche l'ereditarietà sembrava un'opzione per estendere AddressRecord a una richiesta, anche se sento che sono entità distinte nel mondo reale, quindi ho lasciato cadere quell'idea).

Ciò che intendo è, dovrei avere AddressRecord come oggetto privato all'interno di Request e aggiungere getter / setter nella Request stessa per ogni campo in AddressRecord?

O semplicemente aggiungi getter / setter per ottenere / impostare AddressRecord [] dalla Request e quindi impostarlo all'esterno, ad esempio in un codice controller?

(Questa idea successiva l'ho ottenuta quando ho cercato di estrarre la classe AddressRecord da Request in Eclipse come di seguito:

public class AddressSearchRequest {

    AddressRecord address;

    public AddressSearchRequest(String format, String customerId, String addressLine1, String suite,
      String city, String state, String postalCode) {
        this.format = format;
        this.customerId = customerId;
        this.address.setAddressLine1(addressLine1);
        this.address.setAddressLine2(Suite);
        this.address.setCity(city);
        this.address.setState(state);
        this.address.setPostalCode(postalcode);
    }

    public void setAddressLine1(String addressLine1) {
        this.address.setAddressLine1(addressLine1);
    }
    public String getSuite() {
        return address.getAddressLine2();
    }
    public void setSuite(String suite) {
        this.address.setAddressLine2(suite);
    }
    public String getCity() {
        return address.getCity();
    }
    public void setCity(String city) {
        this.address.setCity(city);
    }
    public String getState() {
        return address.getState();
    }
    public void setState(String state) {
        this.address.setState(state);
    }
    public String getPostalCode() {
        return address.getPostalCode();
    }
    public void setPostalCode(String postalCode) {
        this.address.setPostalCode(postalCode);
    }
}

UPDATE:

Ci sono in realtà 2 diversi tipi di richieste che sto trattando - una richiesta di ricerca - prende solo un indirizzo e può restituire più corrispondenze.

Una richiesta di convalida può richiedere uno o più indirizzi.

Li ho avuti entrambi come Request provocando una certa confusione. corretto.

Nota: sto utilizzando AddressRecord anche in altri tipi di richieste e classi di risposta.

    
posta SamV 21.11.2015 - 00:16
fonte

3 risposte

1

La differenza tra aggregazione e composizione è proprietà. La composizione è più strong Se Request è composto da AddressRecord s, allora AddressRecord non può esistere al di fuori di Request . Se Request aggrega AddressRecord s, puoi creare AddressRecord senza l'esistenza di un Request .

Non ho una piena comprensione del tuo sistema, ma sembra che un AddressRecord possa esistere al di fuori del tuo Request . Ciò significherebbe l'approccio in cui fornisci un accessorio e un mutatore per la tua raccolta di AddressRecord s. Questo può assumere molte forme: puoi fornire un get / set per indice, un get / set per l'intera collezione (in questo caso, l'array), aggiungi / rimuovi metodi e così via. Ad ogni modo, ti consiglio di creare AddressRecord s al di fuori di Request e usarli (insieme ad altri dati) per popolare Request .

    
risposta data 21.11.2015 - 00:29
fonte
1

Esistono due casi diversi: o il tuo Request contiene un AddressRecord , o ne contiene più. (La domanda è un po 'confusa al riguardo.)

Se Request deve contenere più AddressRecord s, la risposta è chiaramente che deve esporre i metodi per ottenere AddressRecord s per indice o per qualche altra chiave, in modo che il chiamante ottenga un AddressRecord e funziona con esso. Il Request potrebbe quindi offrire anche metodi per aggiungere o eliminare AddressRecord s, e in particolare il metodo add() potrebbe accettare un AddressRecord esistente da aggiungere al Request , nel qual caso il Request non possiede il AddressRecords che contiene, quindi hai un'aggregazione, oppure potrebbe creare un AddressRecord internamente, nel qual caso ne possiede il contenuto. La scelta è tua.

Se il tuo Request deve contenere un singolo AddressRecord , si applicano gli stessi principi, puoi pensare che si tratti di un insieme di un elemento, quindi non c'è bisogno di aggiungere o eliminare elementi, e l'accessorio fa non è necessario un indice o una chiave. Ma se fossi nei tuoi panni utilizzerei sicuramente un accessor, quindi il chiamante dovrebbe invocare l'accessor per ottenere un riferimento all'unico e solo AddressRecord oggetto contenuto in Rquest , e quindi il chiamante dovrebbe richiamare l'oggetto AddressRecord direttamente.

L'aggiunta di metodi di mutatore a Request che delegano a un contenuto AddressRecord è un lavoro non necessario, rende le tue classi difficili da mantenere e dà l'aspetto falso che Request è derivato da AddressRecord , poiché espone un superset dei suoi metodi, ma senza avere effettivamente ereditarietà, dal momento che non puoi passare un Request là dove è previsto un AddressRecord .

Nota: un'altra strategia comunemente seguita nelle versioni più moderne di Java e nelle lingue con modelli di raccolta più completi e più flessibili (come C #) dovrebbe avere Request esporre un effettivo List<AddressRecord> getAddressRecords() , ma con java 1.4 non proverei una cosa del genere, a causa della mancanza di sicurezza del tipo.

    
risposta data 21.11.2015 - 00:43
fonte
1

Le altre risposte contengono alcuni buoni dettagli sui diversi approcci per mettere in relazione le classi l'una con l'altra, il che è fondamentale per la domanda. Ma vorrei solo rafforzare l'idea che l'ultima scelta migliore di approcci progettuali possa e scaturirà naturalmente da una comprensione di ciò che l'applicazione fa e di quali dati ci sono dentro .

Ad esempio, i record di richiesta sono semplicemente "voci di registro" ogni volta che viene effettuata una richiesta? O sono "messaggi" API che devono essere monitorati e risolti? E le richieste di convalida? E così via.

Il vantaggio più importante della progettazione orientata agli oggetti non è alcun potere di programmazione o funzionalità che potrebbe fornire per riutilizzare il codice. Il grande vantaggio di OOP è che aiuta concettualmente a chiarire il codice (con meno commenti) per gli sviluppatori che lo leggono. Se un progetto OO si trasforma in una confusione di relazioni ottuse (che può rapidamente) ... allora ha sconfitto il suo scopo principale.

    
risposta data 21.11.2015 - 04:03
fonte

Leggi altre domande sui tag