Alright people,
In the last couple of days I've been thinking how to implement this properly, and I'd like to know what your approach would be to implement the following scenario:
I'm doing an eCommerce platform, and we have many kinds of "entities". Entities are not necessarily users that have credentials and can login in our platform, and everything should be fairly decoupled from everything else.
Real life scenario: We have customers, employees and suppliers, all of these can or not be a User, as in, they may or may not have login credentials. I can attach a contact (address info) to any of these models, or an invoice... The idea is that we may have customers that don't actually have credentials that we issue invoices to, or create an order to a user that doesn't actually login... Same for invoicing, I want to be able to invoice a customer, as well as a supplier.
The problem that I'm having is that these 3 types of user are more or less the same, they can have orders/invoices/contacts/whatever attached to them, but they aren't necessarily a user. In fact, credentials must be something that we should be able to attach to any of those models, if we want, so a supplier can have a login to access whatever they need.
How would you design this?
I would logically separate users from organizations, then create abstractions for both users and organizations, then create concrete classes for them that are composed in whatever combination is appropriate for each. You don't really have three types of users, you have two types, employees and representatives of outside organizations. Those outside organizations could have multiple authorized users (or not), and they may also have relationships with your employees. You don't mention whether a customer represents a single person or an organization, that makes a difference in how you model your domain. Here's how I would model it, assuming that a customer is logically an organization, not an individual person. If Customer
is a person, authorizedUsers
would move down into the Supplier
, and Customer
would have a single User
property.
abstract class TransactionalEntity
{
String name;
Set<Address> billingAddresses;
Set<Address> shippingAddresses;
Set<Invoice> invoices;
Set<Order> Orders;
Set<User> authorizedUsers;
}
abstract class User
{
String firstName;
String lastName;
String email;
String username;
String password;
}
class Supplier extends TransactionalEntity
{
Set<Product> suppliedProducts;
}
class Customer extends TransactionalEntity
{
Employee salesRepresentative;
}
class Employee extends User
{
String title;
Double salary;
Date startDate;
Address homeAddress;
Employee supervisor;
}