I am learning software design now. I am a front-end guy so this may be a stupid question, but I really want to know the answer. Hope you could help me.
I have to design an E-commerce system. More specifically, I am designing the buying system in E-commerce. I have done some research on how to do it and found EAV. But after knowing the EAV is the anti-pattern, I don't want to use it and also I have to keep it simple for a beginner like me to understand the design.
Here is the class
diagram I have designed by myself.
And of course, I don't think this design is correct. I have spent like three days doing research and thinking about how to solve the Product
and ProductType
problem.
I just want to have a product like an iPhone, for example, has the attributes belong to the phone, a coke has the attributes belong to the drink, etc.
How could I do this?
Please tell me how to solve this problem in a simple way, cause I am new to this. Some articles or books about software design could be appreciated too.
Thank you <3
Basically you know that all the products have (at least) a product type. And you know that a product type instance will end up being a drink, a telephone, etc. So, you first need
You will need to make sure that ProductType
is either an interface
or an abstract class
or a base class
. An interface
is a declared entity type, whose capabilities are known, but not implemented. It is the job of the classes implementing the interface
to implement its methods. An abstract class
is a fully declared, but only partially defined entity type. If you have an abstract class
, then you are able to implement some of its methods, but you delegate the implementation of some of its method to its implementing subclasses. A base class
is a class
which is fully defined.
So your first decision is to make ProductType
one of the following:
interface
abstract class
class
You will need to think about what the common capabilities of product types are. If they should have some methods which work exactly the same, then you do not necessarily need an interface, but you will need an abstract class
or a base class
. If you decide not to define an interface
at this point, that's fine. Later you can define it if you realize that you need it anyway. So, assuming that the methods of the separate product types are at least partially common, you will need to have some class. By default it should be a base class
, that is, a normal class
which has all the methods a ProductType
should have implemented. Son't worry, if some specific product types should behave in a different manner in the case of some methods in comparison to the base class
, you can always override base class
methods for subclasses.
However, you might need an abstract class
. In order to decide whether an abstract class
is the way to go is to find out whether there is at least such a method that should NOT be implemented by the base class
in any circumstances, because that method is always known only on subclass-level. For example, if you have an evaluate
method, then you will probably need to implement it separately for your product types, because a phone is evaluated in a different manner in comparison to car.
Next, you need to define specific ProductType
subclasses, that is, classes which extends
/implement
ProductType
. We know that a ProductType
may have 0 or more Products, but can a product be of more product types?
A product will need to have a ProductType
if there is no possibility for more product types to be associated to a single Product
. Otherwise you will need a collection of product types by product.
Since Product
is also something much more general, you will probably need to invoke Product
methods from ProductType
. This means that you will need to decide whether Product
is an:
interface
abstract class
class
as well, with a similar thought process as the one you have used when decided what ProductType
should be.
It's a big question whether there can be subtypes, sub-subtypes, etc. for ProductType
and Product
. If that's the case, you will need to implement trees for them with proper insert/update/delete/search functionalities, as you need them
Whenever possible, do not refer to specific product types, because then you will have to copy-paste that code for other products and product types. Whenever the same pattern is true for all your product types or products, refer them by their most abstract
representation (their interface
, abstract class
or base class
, respectively) and only use concrete types at instantiation and when you are forced to.
Use factory methods for instantiation instead of constructors, because a factory method can return the instance of a subtype if that's what you need.