Duplicazione dei dati, può essere una pratica inevitabile in questo esempio?

2

Supponiamo di avere dipendenti diversi di tipo Employee memorizzati in un elenco all'interno di una classe SubCase .

public class SubCase{
    protected ArrayList<Employee> employees;
    ...
}

SubCase rappresenta una parte di un progetto in cui i dipendenti lavorano. Hanno un ruolo specifico fisso nel progetto, ma quel ruolo è all'interno un'altra classe Project . Il progetto conosce SubCase ma è una relazione non prioritaria.

Normalmente, non abbiamo bisogno di conoscere il ruolo degli utenti a livello di sottocasi e, pertanto, abbiamo creato l'intera applicazione tenendo presente questo aspetto e ora è piuttosto difficile ottenere il ruolo specifico che un utente ha utilizzato Classe SubCase, ma in una sottoclasse di Subcase, è importante sapere quale tra gli utenti di una sottocartella ha un ruolo FinancialExpert.

Sarebbe un problema se facessi una variabile privata separata:

public class SubCaseExtension extends SubCase{
    private User financialExpert;
}

in cui è possibile salvare financialExpert ? Usando questo, sarebbe facile sapere quale utente è l'esperto finanziario, ma formerebbe un codice duplicato perché il dipendente che è un finanziario sarà aggiunto anche al ArrayList dei dipendenti.

I dati duplicati in questo caso possono essere giustificati?

    
posta CedricCornelis 04.08.2016 - 16:08
fonte

3 risposte

2

Hai - quasi (vedi sotto) - nessuna "duplicazione dei dati", dal momento che ciò di cui ti occupi effettivamente è un riferimento allo stesso oggetto due volte, non con una copia di un oggetto.

Se dovessi avere a che fare con il ruolo di un datore di lavoro all'interno di una sottocategoria, su base regolare, la soluzione suggerita da @ TulainsCórdova potrebbe andare bene, tuttavia, dato che hai scritto

Normally, we don't need to know the Role of the users at SubCase level

quindi credo che scambiare ArrayList<Employee> con qualcosa di più generale solo per far fronte a un raro caso limite mi sembra uno stratagemma per la tua situazione. Quindi la tua soluzione suggerita è un buon approccio IMHO, quando ti interessi alcuni dettagli.

L'aggiunta della variabile financialExpert in una sottoclasse, anche se è solo un riferimento, introduce una sorta di ridondanza, perché devi assicurarti che financialExpert possa contenere un elemento della lista employees corrispondente (e non un completamente diverso Employee oggetto).

Se questo diventa un problema o meno dipende da come l'elenco employees viene inizializzato e manipolato. È necessario accertarsi che il financialExpert non venga rimosso da questa lista accidentalmente in un secondo momento, oppure è necessario assicurarsi che il programma sia in grado di gestire tale situazione in modo affidabile. Ad esempio, se gli oggetti SubCase (o almeno la parte che modifica la lista employees ) sono progettati in modo immutabile, vengono inizializzati solo una volta, il che rende facile garantire che le due variabili non escano dal sync.

    
risposta data 04.08.2016 - 16:46
fonte
4

Il mio suggerimento è che tu sostituisca:

protected ArrayList<Employee> employees;

con

protected HashMap<Employee,Role> employees;

.. nei progetti e "Sottocasi".

In questo modo conoscerai sempre il ruolo che un Dipendente gioca in un progetto.

Saranno necessari alcuni refactoring. Penso che in questo modo non sarà necessaria alcuna duplicazione speciale di codice.

EDIT: non suggerisco che il ruolo sia una proprietà del Dipendente poiché suppongo che un Dipendente possa partecipare a diversi progetti con ruoli diversi.

Rispondi a questo commento:

@CPerkins, Projects has such hashmap, but it has to be available in SubCase and SubCaseExtension also. And Project only know about SubCase and SubCaseExtension, but not the other way around.

Poiché le sottocaselle avrebbero anche la HashMap (come suggerito sopra), lascia che il progetto aggiunga le coppie chiave / valore pertinenti alla classe interna tramite un metodo addEmployeeWithRole(Employee e, Role r); in SubCase. Nessun dato duplicato qui perché gli oggetti vengono passati per riferimento in Java.

    
risposta data 04.08.2016 - 16:36
fonte
0

Va bene, basta avere un puntatore al Dipendente. vale a dire

public class Subcase
{
    protected ArrayList<Employee> employees;
    private string financialExportId;

    private User financialExpert 
    {
        get 
        {
            return employees.FirstOrDefault(i=>i.Id == financialExportId);
        }
    }
}
    
risposta data 04.08.2016 - 17:16
fonte