POJO nidificati, esponendo le raccolte, rilevando le modifiche

4

Ho un paio di classi di oggetti semplici per rappresentare i dati letti da un file. Sembrano qualcosa del genere:

public class Command {
    private String name;
    private List<Message> messages;
}
public class Message {
    private Type type;
    private Map<String, Object> params;
}

con getter e setter per le variabili. Tuttavia, non ero sicuro di come esporre l'elenco messages o la mappa params . All'inizio volevo avere un getter che restituisca solo la lista o la mappa, per evitare di dover scrivere una serie di metodi add / remove / iterate per ogni elenco o mappa. Gli oggetti di raccolta hanno questi metodi e molti altri, quindi è sembrato più conveniente restituire solo quegli oggetti. Tuttavia, ho anche gli oggetti per sapere quando i dati sono cambiati, in modo che una vista possa essere aggiornata di conseguenza, o per tenere traccia di se un particolare file è stato modificato e deve essere salvato. Ciò significa che dovrei implementare delegati per aggiungere / rimuovere / iterare / keyset / entrySet / etc per quei campi, ma aggiungere molti metodi extra e rendere il codice molto meno conveniente. Qual è la migliore pratica qui, quando si tratta di oggetti semplici che possono avere elenchi, mappe, insiemi, ecc. In essi, oltre a poter sapere quando i dati sono cambiati?

Ho anche avuto una domanda correlata riguardante se un oggetto figlio dovrebbe avere un riferimento all'oggetto che lo ha creato. Ci stavo pensando perché nel caso in cui un oggetto Message è stato modificato, in che modo il suo oggetto% gen_de% sa di tale modifica? Se la classe Command ha eventi a cui Message si abbona con gli ascoltatori, o se l'oggetto Command ha un riferimento all'oggetto Message in cui è contenuto, e chiama un metodo / imposta un campo in quel Command oggetto quando i dati vengono modificati? Qual è la migliore pratica qui, o dovrei cambiare completamente il modo in cui i dati dei file vengono archiviati come oggetti?

    
posta AniDev 22.06.2015 - 16:50
fonte

3 risposte

2

È buona norma non esporre le raccolte contenute direttamente ai clienti. Esiste un elenco di metodi "standard" che tipicamente forniscono sulla classe contenente per gestire la relazione (ottieni tutto, aggiungi, rimuovi, ecc.).

In teoria, si consiglia di non restituire mai la collezione effettiva al client, piuttosto una sua copia immutabile contenente gli stessi oggetti. In questo modo il cliente non può modificare direttamente la raccolta, ma deve passare attraverso i metodi di delega.

Le relazioni bidirezionali non sono un problema, ma leggermente più difficili; usali dove necessario, ma evita la complessità aggiuntiva se non lo fai. Devi assicurarti che la bidirezionalità sia mantenuta correttamente nel modello e non fare affidamento sul codice client per farlo. La complessità dipenderà da quali mutazioni sono possibili dopo la costruzione, ma generalmente:

  • Se aggiungi un messaggio a un comando, quel comando deve sempre essere quello impostato sul messaggio (e viceversa)
  • Se rimuovi un messaggio da un comando, il riferimento al comando del messaggio deve essere impostato su null (e viceversa)
risposta data 08.07.2015 - 15:55
fonte
0

Mi assumerò il rischio e assumerò che tu abbia modellato i dati il più vicino possibile alla fonte.

In questo caso:

I messaggi Elenco sono solo una struttura e sì, ha un sacco di metodi che puoi usare, ma questi metodi sono metodi tecnici, normali operazioni su una classe List.

Vuoi creare metodi nella classe Command più leggibili usando un nome chiaro, potresti ottenere alcune cose interessanti da questo approccio. F per esempio:

//pseudo-code here
public void AddMessage(Message message) 
{
  ValidateMessageSefty(); // returns an exception if is not
  List.Add(message);
}

Ho alcuni articoli facili da leggere su argomenti simili nel mio blog: CodeJoy.blogspot.com e in particolare Che cos'è il buon codice

    
risposta data 03.07.2015 - 20:28
fonte
0

A seconda del tuo scenario, potresti esporre la tua raccolta come ReadOnlyCollection (o qualcosa di simile, a seconda del tuo linguaggio di programmazione), altrimenti useresti un ObservableCollection (che ha eventi per aggiungere, rimuovere, ecc.) , che ti consentirà di reagire ai cambiamenti. Considerare se quest'ultimo è davvero necessario però. Nella maggior parte degli scenari si andrebbe alla prima rotta. Se uno sviluppatore downstream è autorizzato a apportare modifiche alle raccolte che gestisci, rendi questa un'API esplicita.

    
risposta data 08.07.2015 - 18:05
fonte

Leggi altre domande sui tag