I have two tables: tblCustomer
, tblProduct
:
tblCustomer:
Id: Integer, auto-increament
Name: Varchar(30)
....
tblProduct
Id: Integer, auto-increament
Name: Varchar(50)
customerId: Integer
....
And two 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 */
}
}
When customer register account, it call:
Customer cus = new Customer(/* ... */);
Customer.add(cus);
and when customer buy a product:
Product pd = new Product(/* ... */);
currentCustomer.addProduct(pd);
But my teacher said it not correct in OOAD (and even OOP) because Customer.addProduct
is operate on tblProduct
table, is it right? What is good design for this case?
** Update: **
Product haven't a pre-defined yet, when a customer buy a product, the store will make it and delivery to customer, so two same products is rare happen, so is tblCustomerProduct
need?
Add a DAO tier that will contain the logical part of the methods
save
,delete
,update
, etc.Here is how I usually do:
basepackage.domain
: contains all your entities (data only, no logical part - in your caseProduct
andCustomer
)basepackage.dao
: contains all your DAOs, only used to access the data, basically one per entity, each one containing methods such asfindAll() : List<E>
,findOne(K id) : E
,save(E e) : void
, etc.basepackage.service
: contains all your services, the logical part of the app. The services are the only ones that are calling the DAOs.basepackage.presentation
(orbasepackage.web
for a webapp): contains the HMI/web services/... implementation.In the table, the customer is assigned to a product, but in the method you give a customer and add a product.
So I would go for either a method pd.setCustomer(currentCustomer) instead of currentCustomer.addProduct(pd)
Or change the customer field in the product table to a products field in the customer table.
What your teacher probably means is that you need a third table, named something like "CustomerProduct". This table contains the links between customers and which products they've bought.
so, when a customer buys a product, you add this data to the table CustomerProduct. This will remove redundant data and also make deletion alot easier
Your teacher is right. It is not good Design because A class that you create should be cohesive. So that it should be responsible for doing the things that it can do. Here in your product class you have added customer id which is essentially a bad practice because A customer may purchase multiple products. This design will fail in that case. And also Product class doesn't need to know anything about the customer. All it has to know about is itself.
The relation between customer and product is an association which can be expressed as "customer buys product". So that customer id should not be there in product table.
Regarding the
currentCustomer.addProduct(pd);
method, it is not well suited because it is more suitable to product class rather than customer class.The simple solution to your problem can be create a new class which can relate product and the customer.
For e.g.
Inside this class you can add method like "AddProductForCustomer" and can write your database logic which will maintain the consistency.
Hope this clears your doubt.