Problema di design della classe

0

Sono nuovo di OOP e un sacco di volte sono diventato perplesso in situazioni simili a questo esempio:

Attività: genera un documento XML che contiene informazioni su una persona. Supponiamo che le informazioni siano prontamente disponibili in un database. Ecco un esempio della struttura:

<Person>
    <Name>John Doe</Name>
    <Age>21</Age>
    <Address>
        <Street>100 Main St.</Street>
        <City>Sylvania</City>
        <State>OH</State>
    </Address>
    <Relatives>
        <Parents>
            <Mother>
                <Name>Jane Doe</Name>
            </Mother>
            <Father>
                <Name>John Doe Sr.</Name>
            </Father>
        </Parents>
        <Siblings>
            <Brother>
                <Name>Jeff Doe</Name>
            </Brother>
            <Brother>
                <Name>Steven Doe</Name>
            </Brother>
        </Siblings>
    </Relatives>
</Person>
  • Ok consente di creare una classe per ogni tag (ad esempio: Persona, Nome, Età, Indirizzo) Supponiamo che ogni classe sia responsabile solo per se stessa e per il elementi direttamente contenuti
  • Ogni classe saprà (definita da default) le classi che sono direttamente contenute in esse
  • Ogni la classe avrà una funzione process () che aggiungerà se stessa e la sua i bambini al documento XML che stiamo creando
  • Quando un bambino viene disegnato, come nella riga precedente, avremo anche loro il processo di chiamata ()
  • Ora siamo in un ciclo ricorsivo in cui ogni oggetto disegna i propri figli fino a quando tutti sono disegnati

  • Ma cosa succede se solo alcuni dei tag devono essere disegnati, e il resto lo sono opzionale? Alcuni sono opzionali in base a se i dati esistono (se li abbiamo esso, dobbiamo disegnarlo), e alcuni sono opzionali in base alle preferenze dell'utente che genera il documento

  • Come ci assicuriamo che ogni oggetto ha i dati di cui ha bisogno per disegnare se stesso e i suoi figli? Possiamo passare una vasta schiera attraverso ogni oggetto, ma sembra schifoso non è vero? Potremmo avere ogni oggetto interrogare il database per questo, ma ci sono molte domande e come fa a sapere qual è la sua domanda?
  • Cosa se vogliamo sbarazzarci di un tag più tardi? Non c'è modo di fare riferimento loro.

Ci ho pensato per 20 ore ora. Sento di fraintendere un principio di progettazione o mi sto avvicinando a questo tutto sbagliato. Come faresti a programmare qualcosa di simile?

Suppongo che questo problema possa essere applicato a qualsiasi scenario in cui esistono classi che creano altre classi, ma le classi create necessitano di informazioni da eseguire. Come faccio a ottenere loro le informazioni in un modo che non sembra disordinato?

    
posta Matthew Flynn 10.10.2013 - 04:34
fonte

2 risposte

1

Una risposta parziale, che affronta i punti chiave della tua domanda:

  • Each class will know (have defined by default) the classes that are directly contained within them

Una classe dovrebbe conoscere le altre classi solo nella misura necessaria per fare il suo lavoro. Se tutto ciò di cui hai bisogno è generare un documento XML che potrebbe essere piccolo come un costruttore, un metodo loadFromDatabase() per compilare i campi e un metodo toXML() per creare i frammenti XML di cui avrai bisogno. Tutto il resto è meglio conservarlo privato, incluso tutto ciò che è necessario per far funzionare il costruttore e i metodi pubblici.

  • Each class will have a process() function that will add itself and its childeren to the XML document we are creating

Un approccio migliore sarebbe una classe Person (che corrisponderebbe al livello superiore dell'XML desiderato) con un metodo toXML() che restituisce il documento XML completo, facendo così chiamando i metodi toXML() del bambini e componendo i frammenti come appropriato.

    
risposta data 10.10.2013 - 11:00
fonte
0

Alcuni suggerimenti per costruire il grafico dell'oggetto:

Come hai detto, per popolare gli oggetti dovresti passare una struttura dati attraverso la gerarchia degli oggetti. Ma questo è vero solo se costruisci il grafico dall'alto verso il basso.

Un approccio migliore sarebbe quello di costruirlo dal basso verso l'alto usando, ad es. una fabbrica (l'esempio è scritto in Java):

public class Person {
    private String name;
    private int age;
    private Address address;
    private List<Relatives> relatives;        

    public Person(String name, int age, Address address, List<Relatives> relatives) {
        this.name = name;
        this.age = age;
        this.address = address;
        this.relatives = relatives;        
    }
}

public class Address {
    String street;
    String city;
    String state;

    public Address(String street, String city, String state) {
        this.street;
        this.city;
        this.state;
    } 
}

public interface Relative {
}

public interface Parent extends Relative {
}

public class Mother implements Parent {
    private String name;

    public Parent(String name) {
        this.name = name;
    }
}

// and some more classes; this is left as an exercise to the reader ;)

public class PersonFactory {
    public static Person newPerson() {
        // create the address       
        Address addr = new Address("100 Main St.", "Sylvania", "OH");
        // create the list of parents
        List<Parent> parents = new List<Parent>();
        parents.add(new Mother("Jane Doe"));
        parents.add(new Father("Jane Doe"));
        List<Sibling> siblings = new List<Siblings>();
        // analogue to parents

        List<Relatives> relatives = new List<Relatives>();
        relatives.add(parents);
        relatives.add(siblings);
        // now create the person and return him

        return new Person("John Doe", 21, addr, relatives);
    }
}

Il passaggio delle dipendenze dirette tramite il costruttore viene chiamato dependecy injection. Questo può essere ottenuto manualmente (ad esempio usando le fabbriche) o usando le librerie come Spring o Juice (in Java).

(L'unica responsabilità di PersonFactory è la costruzione del grafico dell'oggetto).

    
risposta data 23.10.2013 - 14:21
fonte

Leggi altre domande sui tag