Sto creando una libreria in C # che verrà utilizzata per interrogare i database.
Per utilizzare questa libreria, un utente deve prima dire alla biblioteca cosa contiene lo schema del database, creando Schema
, Table
e Column
oggetti.
Un oggetto Schema
è composto da:
- Un nome, che è un
string
. - Una raccolta di
Table
oggetti di sua proprietà.
Un oggetto Table
è composto da:
- Un riferimento all'oggetto
Schema
che lo possiede. - Un nome, che è un
string
. - Una raccolta di
Column
oggetti di sua proprietà.
Infine, un oggetto Column
è composto da:
- Un riferimento all'oggetto
Table
che lo possiede. - Un nome, che è un
string
. - Un tipo, che è uno dei valori
String
,DateTime
eReference
. - Se il tipo è
Reference
, quindi un target, che è un riferimento a unTable
oggetto all'interno dello stessoSchema
.
Posso pensare a un sacco di modi per progettare un'interfaccia pubblica per la creazione di questi oggetti, ma tutti hanno dei difetti. Quale approccio dovrei usare?
Ecco le idee che ho pensato:
Fornisci solo classi mutevoli
L'utente può creare Schema
, Table
e Column
oggetti e quindi modificare tutte le proprietà di questi oggetti dopo il fatto.
Svantaggi:
- Garantire che gli stati di questi oggetti rimangano coerenti tra loro potrebbe essere difficile.
- Poiché tutti questi oggetti sono mutabili, l'utente dovrà tenere presente che potrebbe cambiare in qualsiasi momento. (E anche io, l'autore della biblioteca!)
Fornire solo classi immutabili: edizione naive
Le classi Schema
, Table
e Column
sono tutte immutabili. Tutte le proprietà di questi oggetti devono essere specificate al momento della creazione. Non puoi creare un Schema
senza specificare tutto il Table
s che contiene e non puoi creare un Table
senza specificare a quale Schema
appartiene.
Fatal downside:
- La creazione di oggetti non sarebbe effettivamente possibile: non è possibile creare uno schema senza prima creare le sue tabelle e non è possibile creare tabelle senza prima creare lo schema.
Fornisce solo classi immutabili: costruzione dal basso verso l'alto
Per prima cosa, crei oggetti Column
. Successivamente, crei Table
oggetti passando in Column
oggetti. Infine, crei un oggetto Schema
passando in Table
oggetti. Tutte queste classi sono immutabili.
Svantaggi:
- L'oggetto
Column
non può avere una proprietà che indica a qualeTable
appartiene la colonna, poiché l'oggettoColumn
viene creato prima che l'oggettoTable
sia, e l'oggettoColumn
sia immutabile. Allo stesso modo, l'oggettoTable
non può avere una proprietà che indica a qualeSchema
appartiene. - La proprietà "tabella di destinazione" di un oggetto
Column
dovrà essere solo una stringa, non un riferimento a un oggettoTable
. - L'utente API è costretto a creare oggetti in un ordine specifico. Cosa fare se si desidera creare prima le tabelle e aggiungere colonne in un secondo momento?
Fornisci due tipi di classi immutabili
Fornire due famiglie di classi. Innanzitutto, ci sono le classi SchemaDefinition
, TableDefinition
e ColumnDefinition
, che funzionano esattamente come nell'approccio "bottom-up construction".
Esistono anche Schema
, Table
e Column
classi, anch'esse immutabili. Queste classi hanno tutte le proprietà che potresti sperare: un Schema
ha una proprietà che ti dice di tutto il suo Table
s, e un Table
ha una proprietà che ti dice a quale Schema
appartiene.
Le classi Schema
, Table
e Column
non hanno costruttori pubblici. Invece, c'è una classe SchemaFactory
che prende un SchemaDefinition
e la usa per creare un gruppo di Schema
, Table
e Column
oggetti, e poi ti dà Schema
.
Svantaggi:
- Ci sono due classi per ogni tipo di oggetto di business, invece di uno solo.
- L'utente API è ancora obbligato a creare oggetti in un ordine specifico.
Fornire classi mutevoli e immutabili
Fornire due famiglie di classi. Innanzitutto, ci sono le classi SchemaMutable
, TableMutable
e ColumnMutable
, che funzionano esattamente come nell'approccio "fornire solo classi mutabili".
Esistono anche Schema
, Table
e Column
classi, che funzionano proprio come nell'approccio "due tipi di classi immutabili". Esiste una classe factory che prende un SchemaMutable
e ti dà Schema
.
Svantaggi:
- Ancora una volta, ci sono due classi per ogni tipo di oggetto di business.
- E ancora, garantire che gli stati di questi oggetti rimangano coerenti tra loro potrebbe essere difficile.