Come prevenire i metodi di accesso ai dati duplicati che recuperano dati simili?

8

In quasi tutti i progetti su cui lavoro con un team, lo stesso problema sembra insinuarsi. Qualcuno scrive codice UI che richiede dati e scrive un metodo di accesso ai dati:

AssetDto GetAssetById(int assetId)

Una settimana dopo qualcun altro sta lavorando su un'altra parte dell'applicazione e necessita anche di un AssetDto , ma ora include "approvatori" e scrive quanto segue:

AssetDto GetAssetWithApproversById(int assetId)

Un mese dopo qualcuno ha bisogno di una risorsa, ma ora include le "domande" (o "proprietari" o "richieste in esecuzione", ecc.):

AssetDto GetAssetWithQuestionsById(int assetId)
AssetDto GetAssetWithOwnersById(int assetId)
AssetDto GetAssetWithRunningRequestsById(int assetId)

E diventa ancora peggio quando iniziano ad apparire metodi come GetAssetWithOwnerAndQuestionsById .

Vedi il modello che emerge: un oggetto è attaccato ad un grande oggetto grafico e hai bisogno di parti diverse di questo grafico in posizioni diverse.

Naturalmente, vorrei evitare di avere un gran numero di metodi che fanno quasi la stessa cosa. È semplicemente una questione di disciplina di squadra o c'è qualche schema che posso usare per prevenire questo? In alcuni casi potrebbe essere opportuno disporre di metodi separati, ovvero ottenere una risorsa con richieste in esecuzione può essere costosa, quindi non voglio includerle tutte le volte. Come gestire questi casi?

    
posta Ronald Wildenberg 27.09.2012 - 09:22
fonte

4 risposte

4

Per quanto riguarda la sintassi, creerei un oggetto intermedio per la creazione di query con un'interfaccia fluida:

// all the basic, cheap to query fields
AssetDto a = AssetRetriever(asset_id).fetch() 

// some common expensive fields
AssetDto a = AssetRetriever(asset_id).withOwner().withQuestion().fetch() 

// numerous less common fields may not command dedicated methods
AssetDto a = AssetRetriever(asset_id).withFields("foo", "bar").fetch() 

// Better yet, use an enum and enjoy static checking
AssetDto a = AssetRetriever(asset_id).withFields(F_OWNER, F_QUESTION).fetch() 

Spero sia abbastanza ovvio da implementare. L'unico metodo che effettivamente toccherà il database è fetch() .

    
risposta data 27.09.2012 - 17:04
fonte
2

Quando si ha a che fare con oggetti di grandi dimensioni, questo è molto comune. Mentre l'aggiunta di nuovi metodi aumenta le prestazioni, riduce significativamente la manutenibilità. E di nuovo devi scegliere tra questi due.

Suggerisco di avere un metodo che restituisce (non necessariamente il più piccolo) dei dati comunemente usati, un altro che restituisce l'intero oggetto, e probabilmente qualcun altro per le risorse più costose.

Un altro approccio consiste nell'avere metodi che restituiscono solo i campi necessari dell'oggetto, come AssetQuestions GetAssetQuestionsById(int assetId) o Owners GetAssetOwnersById(int assetId) .

Insieme a questo è necessario stabilire alcune regole sul recupero dei dati. Ad esempio, se qualcuno ha bisogno di 5 campi dell'oggetto, e c'è un metodo esistente che restituisce 8, dovrebbe essere usato il metodo esistente.

    
risposta data 27.09.2012 - 16:37
fonte
1

Ho avuto recentemente questo stesso problema e ho adottato la seguente soluzione:

I metodi di accesso ai dati dovrebbero ottenere dati solo da una singola risorsa (ad esempio, una tabella di database), e se il processo necessita di oggetti correlati aggiunti all'oggetto principale, dovrebbe richiedere il metodo responsabile per tali oggetti rispettivi.

In questo modo se hai bisogno di una risorsa con i suoi approvatori devi creare un metodo per la facciata che unisca gli oggetti.

Esempio:

public Class AssetFacade {

   public AssetDto getAssetWithQuestionsByAssetId(int assetId) { 

      AssetDto asset = AssetDao.getAssetById(assetId);
      List<QuestionDto> questions = AssetDao.getQuestionsByAssetId(assetId);
      asset.setQuestions(questions);

      return asset;
   };
 }
    
risposta data 28.09.2012 - 00:24
fonte
0

Is it simply a matter of team discipline or is there some pattern I can use to prevent this?

Sì, si tratta di alcune linee guida nello schema di denominazione per il team. Puoi impostare semplici 4 metodi come GetEntityById (), GetAllEntities (), SetEntity (), DeleteEntityById ().

Inoltre, potresti avere due dto con il nome AssetSimpleDto GetAssetById(assetId) e un altro dettagliato dto chiamato AssetDto GetAssetDetailById(assetId) . Il primo metodo e dto sono personalizzati per ridurre al minimo, mentre il secondo fornisce tutte le informazioni correlate di cui la tua funzionalità potrebbe avere bisogno.

    
risposta data 27.09.2012 - 13:45
fonte

Leggi altre domande sui tag