2011-02-12 8 views
2

Travail sur une application métier utilisant la structure MVC et une architecture Business Object/DAO. Pour tout objet métier normal, les fonctions CRUD sont assez simples. Mais quelle est la meilleure façon de gérer une relation parent-enfant comme "Le client est un utilisateur"?Manière la plus efficace de refléter la relation d'héritage dans les DAO?

Je sais que les classes suivantes:

User, UserDAO, Customer, CustomerDAO 

La Customer classe peut hériter de la User très bien, mais comment voulez-vous mieux tenir compte dans les fonctions DAO CRUD?

+0

Avez-vous deux tables - 'Users' et' Customers'? Je serais surpris. Je pense à une table 'users' avec un champ' user_type'. Et puis avoir une seule VO c'est-à-dire 'Users'. Et si 'user.isCustomer()' est vrai, c'est client. Donc, soit vous ne devriez pas utiliser deux tables ou vous ne devriez pas utiliser l'héritage. – Nishant

+1

@Nishant: Ce n'est pas vrai du tout. Si les clients ont des données supplémentaires que les utilisateurs n'ont pas, vous allez encombrer la table utilisateur avec des colonnes non pertinentes. Il est certainement possible d'implémenter l'héritage avec deux tables. –

+0

@Matt Je ne parle pas de faisabilité, je pensais plus sur le design. Le client est un utilisateur - et c'est une bonne idée d'avoir les deux dans la même table. Cela m'aidera à chercher et cela a plus de sens pour moi. Si vous êtes préoccupé par l'encombrement, extériorisez les données superflues. Créez une table séparée 'customer_details' et liez-la avec une clé étrangère. Dans de nombreux cas, vous pouvez convertir un utilisateur en client.Il est plus facile de simplement changer le type au lieu de copier les données entre les tables puis d'effacer celles-ci. Juste mes 2%. – Nishant

Répondre

10

Martin Fowler a documenté quelques Object-Relational Structural Patterns qui pourraient aider:

1) Single Table Inheritance: Représente une hiérarchie d'héritage des classes comme une seule table qui a des colonnes pour tous les champs des différentes classes.

par exemple. Employee et Customer héritent tous les deux de User et sont tous deux stockés dans la table User, avec une colonne qui détermine le type d'utilisateur qu'un enregistrement particulier représente.

2) Class Table Inheritance: Représente une hiérarchie d'héritage de classes avec une table pour chaque classe.

par exemple. Employee et Customer héritent toutes deux de User et il y a trois tables pour représenter ceci. La table Utilisateur stocke les propriétés communes à tous les utilisateurs. La table Employee a un pointeur vers la table User et stocke uniquement les propriétés pertinentes pour Employees. La même chose est vraie de la table Customer.

3) Concrete Table Inheritance: Représente une hiérarchie d'héritage de classes avec une table par classe concrète dans la hiérarchie.

par exemple. Employee et Customer héritent tous les deux de la classe abstraite User et il y a deux tables pour le représenter. Une table Customer et une table Employee. Chaque table stocke des informations communes aux utilisateurs, mais stocke également des propriétés uniques.

+0

Merci. C'est utile. Donc, j'utilise # 2. Des réflexions sur la meilleure façon de mettre en œuvre les fonctions CRUD pour l'employé/le client/l'utilisateur dans le cadre de l'héritage des classeurs? – user456584

+1

Content que vous ayez trouvé cet article utile! J'aime l'idée de Matt d'enrouler le UserDAO dans le CustomerDAO. – Brandon

6

Vous pouvez avoir une instance de UserDAO dans CustomerDAO. Vous devez interagir avec les tables User et Customer pour couvrir les colonnes de la classe de base et de la sous-classe. Par exemple:

public class CustomerDAO 
{ 
    UserDAO userDao; 

    // ... initialization ... 

    public void update(Customer customer) 
    { 
     // ... first execute update of customer table ... 

     userDao.update(customer); // Should be able to pass Customer to UserDAO due to inheritance 
    } 

    public void insert(Customer customer) 
    { 
     // First insert a row in the User table so that the ID of the user can be determined. 
     userDao.insert(customer); 

     // ... Now execute insertion of row into Customer table ... 
    } 

    public void delete(Customer customer) 
    { 
     // ... first delete Customer row ... 

     // Now delete base class User row. 
     userDao.delete(customer); 
    } 
} 

Bien sûr, chaque opération client devrait probablement être enveloppé dans une transaction afin que la mise à jour des tables de l'utilisateur et le client ne manque pas de manière indépendante.

+0

J'aime l'exemple de code. – Brandon

Questions connexes