Oggetto che può impostare la propria sottoclasse / modificare i suoi metodi con la sottoclasse?

2

Ho un database che memorizza i dati del cliente. Tutti i dati sono in una tabella. Per ogni cliente, c'è una riga al giorno. I clienti hanno diversi tipi di contratti, il loro formato dei dati rimane lo stesso, tuttavia, le dinamiche sottostanti sono diverse.

Sto creando un'applicazione per simulare queste dinamiche e sto lottando per trovare una buona struttura di oggetti per implementarla. Ho trovato due approcci:

Approccio 1

Vorrei iniziare con una superclasse per tutti i tipi di contratto. Gestire l'accesso al database e le proprietà fondamentali, come il numero del contratto, così come i metodi fondamentali (trovare prima data, valore totale, ecc.)

Quindi aggiungerei la sottoclasse per i tipi specifici per aggiungere metodi specifici (ad esempio, calcolare il valore dell'indice ottimale, il cui algoritmo dipenderebbe dal tipo di contratto).

Tuttavia, il tipo di contratto è determinato da un valore nel database. Pertanto, se l'oggetto del contratto carica i propri dati dal database, dovrebbe quindi modificare la propria classe in base al tipo. Non penso sia un buon design.

Approccio 2

In alternativa, potrei creare una classe contract_manager per contenere un elenco di tutti i contratti, recuperare i dati dal database e generare e riempire gli oggetti del contratto.

In tale scenario, tuttavia, temo che l'interfaccia da ricordare sia più complicata e l'accesso al database non possa essere nascosto all'interno dell'oggetto. Ciò sarebbe auspicabile, dal momento che queste classi faranno parte di una libreria di analisi e prototipazione per un gruppo di analisti di dati.

Quale sarebbe il modo corretto di formulare questo problema? Quale sarebbe l'approccio migliore per gestirlo?

    
posta phi 03.01.2018 - 16:40
fonte

2 risposte

6

Clients have different kinds of contracts, their data format remains the same, however, the underlying dynamics are different.

In base a questa affermazione, implementa il ereditarietà di una tabella per mappare le classi di contratto con una tabella dei contratti nel database.

I would start with a superclass for any type of contract, which handles the access to the database and fundamental properties, such as the contract number, as well as fundamental methods (find first date, total value, etc)

Naturalmente è bene avere una superclasse per definire l'interfaccia obbligatoria di tutti i contratti e per implementare il comportamento condiviso. Tuttavia, quando crei un contrat, devi conoscere il suo tipo concreto. Hai due approcci per superare questo problema:

  • Usa la composizione sull'ereditarietà: crea Contract una classe anziché una superclasse e fai riferimento a una classe ContractDynamic , che sarà quindi specializzata in base al comportamento. In questo modo puoi scegliere dinamicamente durante la lettura dei dati del contratto dal database che ContractDynamic class per istanziare (simile al schema di progettazione del proxy )
  • Preferisci Domain Driven Design: utilizza un Factory per creare nuovi dati e un Repository per recuperare il contratto dal database e creare un'istanza della classe corretta in base ai dati della riga letti.

Il secondo approccio è molto meglio. Garantisce una maggiore separazione delle preoccupazioni , disaccoppiando gli oggetti del dominio dal livello di persistenza

    
risposta data 03.01.2018 - 22:40
fonte
2

Dissocia le interfacce del contratto dall'archivio sottostante

Non esporre nessuno dei dati della tabella direttamente. Invece, crea un oggetto di implementazione (non pubblico / interno) che contenga i campi per tutti gli elementi di dati nella tabella (POJO / POCO).

Per ogni caso d'uso (tipo di contratto), scrivi un'interfaccia che si adatti al tipo di contratto e alle operazioni che vuoi fare idealmente.

Infine, scrivere implementazioni leggere (anche non pubbliche / interne) per le interfacce del contratto che richiede l'oggetto POCO come parametro del costruttore. Implementare i metodi delle interfacce del contratto utilizzando il POCO come memoria. Molto probabilmente questo sarà composto, con funzionalità condivise tra diversi contratti implementati una sola volta.

Assicurati che il tuo codice client conosca solo le interfacce e non le effettive implementazioni.

Infine, disponi di una factory che fornirà l'interfaccia corretta in base al POCO / POJO.

Questo ti dà i seguenti vantaggi:

  • oggetto "dati" condiviso che si adatta sempre perfettamente alla tabella e rende IO banale
  • belle interfacce che rendono semplice e facile lavorare con i diversi contratti
  • riutilizzo del codice a livello di implementazione privata
  • libertà di modificare le implementazioni dei diversi contratti senza modificare il codice cliente (purché le interfacce rimangano stabili)
  • facilità di testabilità
risposta data 04.01.2018 - 10:38
fonte

Leggi altre domande sui tag