2013-05-03 4 views
0

J'ai deux tables: tblCustomer, tblProduct:OOAD problème de conception

tblCustomer: 
    Id: Integer, auto-increament 
    Name: Varchar(30) 
    .... 

tblProduct 
    Id: Integer, auto-increament 
    Name: Varchar(50) 
    customerId: Integer 
    .... 

Et deux classes: Customer, Product:

public class Product 
{ 
    private int id; 
    private int name; 
    /* Other stuffs */ 
} 

public class Customer 
{ 
    private int id; 
    private String name; 
    private String phoneNumber; 

    /* get-set and others stuffs */ 

    public static boolean add(Customer cus) { 
     /* This is for insert a customer to tblCustomer */ 
    } 

    public boolean addProduct(Product pd) { 
     /* This is for insert a product to tblProduct with current customer Id */ 
    } 
} 

Lorsque le client compte registre, il appel:

Customer cus = new Customer(/* ... */); 
Customer.add(cus); 

et quand le client acheter un produit:

Product pd = new Product(/* ... */); 
currentCustomer.addProduct(pd); 

Mais mon professeur dit-il pas exact dans OOAD (et même POO) parce que Customer.addProduct est fonctionne sur la table tblProduct, est-il juste? Quel est le bon design pour ce cas?

** Mise à jour: ** produit pas encore un pré-défini, lorsqu'un client achète un produit, le magasin fera et la livraison au client, donc deux mêmes produits est rare arriver, est donc tblCustomerProduct besoin ?

Répondre

1

Ajouter un niveau de DAO qui contiendra la partie logique des méthodes save, delete, update, etc.

Voici comment je fais habituellement:

  • basepackage.domain: contient toutes vos entités (données uniquement, pas de partie logique - dans votre cas Product et Customer)
  • basepackage.dao: contient tous vos DAO, uniquement utilisé pour accéder aux données, essentiellement une par entité, chacun contenant des méthodes telles que findAll() : List<E>, findOne(K id) : E, save(E e) : void, etc.
  • basepackage.service: contient tous vos services, la partie logique de l'application. Les services sont les seuls qui appellent les DAO. (basepackage.web pour une application Web): contient l'implémentation IHM/services Web/....
+0

Le service est-il égal à la couche de contrôle (dans le modèle à 3 niveaux)? –

+0

Il est égal au modèle (si vous référez à MVC) –

+0

@ BìnhNguyên Oui, il a plusieurs noms: niveau d'entreprise, niveau de contrôle, niveau de service, niveau logique ... – sp00m

2

Ce que votre professeur veut probablement dire, c'est que vous avez besoin d'une troisième table, nommée quelque chose comme "CustomerProduct". Cette table contient les liens entre les clients et les produits qu'ils ont achetés.

tblCustomerProduct: 
    Id: Integer, auto-increament 
    CustomerId: Varchar(30) 
    ProductId: Varchar(30) 

donc, lorsqu'un client achète un produit, vous ajoutez ces données à la table CustomerProduct. Cela supprimera les données redondantes et facilitera également la suppression.

+0

Je n'ai pas remarqué que 'Product' n'est pas prédéfini, quand un client achète un produit, le magasin va le faire et la livraison au client –

+0

Les produits doivent être stockés dans le système, sinon comment un client achèterait un produit sans voir quels produits sont disponibles? Votre solution actuelle créera une nouvelle ligne dans le tblProducts chaque fois qu'un client achète un produit. Cela rendra ces lignes redondantes. Ce que votre enseignant veut que vous fassiez, c'est créer une troisième table comme je l'ai décrit. –

+0

Notez également que votre professeur a dit citation: 'Mais mon professeur a dit qu'il n'est pas correct dans OOAD (et même POO) parce que Customer.addProduct fonctionne sur tblProduct'. Ce que votre professeur veut dire, c'est qu'il n'est pas correct de faire fonctionner Customer.addProduct sur la table Product, dans laquelle vous aurez besoin d'une troisième table sur laquelle vous "opérerez". –

1

Dans le tableau, le client est affecté à un produit, mais dans la méthode, vous donnez un client et ajoutez un produit.

Je pencherais pour un ou l'autre pd.setCustomer méthode (currentCustomer) au lieu de currentCustomer.addProduct (pd)

Ou changer le champ client dans la table de produit à un champ de produits dans la table des clients.

2

Votre professeur a raison. Ce n'est pas une bonne conception car une classe que vous créez doit être cohérente. Alors qu'il devrait être responsable de faire les choses qu'il peut faire. Ici, dans votre classe de produits, vous avez ajouté un identifiant client qui est essentiellement une mauvaise pratique, car un client peut acheter plusieurs produits. Cette conception échouera dans ce cas. Et aussi la classe de produits n'a pas besoin de savoir quoi que ce soit sur le client. Tout ce qu'il doit savoir, c'est lui-même.

La relation entre le client et le produit est une association qui peut être exprimée comme «client achète le produit». Donc, cet identifiant client ne devrait pas être présent dans la table des produits.

En ce qui concerne la méthode currentCustomer.addProduct(pd);, il n'est pas bien adapté car il est plus adapté à la classe de produit plutôt qu'à la classe de client.

La solution simple à votre problème peut être créer une nouvelle classe qui peut relier le produit et le client.

Par exemple.

CustomerProduct 

customerid 
productid 

Dans cette classe, vous pouvez ajouter la méthode comme « AddProductForCustomer » et pouvez écrire votre logique de base de données qui maintiendra la cohérence.

Espérons que cela clarifie votre doute.

+0

Je n'ai pas remarqué que le produit n'est pas prédéfini, lorsqu'un client achète un produit, que le magasin le fait et qu'il le livre au client, un article CustomerProduct est-il nécessaire? –

+0

@ BìnhNguyên: Comment le client va acheter un produit sans le voir? Il doit exister quelque part dans le système. Alors seulement il l'achètera. Même si vous voulez que cela fonctionne, insérez d'abord le produit dans la base de données. Obtenez l'ID du produit inséré et créez une entrée dans la table CustomerProduct. – ankurtr