I’m struggling to get a design pattern implemented, and I’m curious if anyone can think of an elegant solution.
My app is designed for customers from different industries (lawyers, real estate agents, notaries…). All customers are stored in a table called Customer, which has a TINYINT column industry_id, containing the value of a constant to identify the industry of that specific customer. The other columns in the Customer table are not influenced by a customer’s industry.
Currently, several parts of my application contain industry-specific logic, using switch statements to loop through the different industries. For example, the method checkForCompetitors() is different, depending on the customer’s industry.
I’d like to get rid of these repetitions and dependencies by turning the Customer model into an abstract class, and making concrete classes such as LawyerCustomer, RealEstateCustomer, NotaryCustomer,… etc. My idea is to put the industry-specific logic into these concrete classes. Thus I could call $customer->checkForCompetitors() and be confident that the appropriate code is executed.
I guess I need some kind of abstract factory to create my customer objects. This factory would require an industry_id as its input parameter to determine the right class for the resulting Customer model. However, this poses a problem when loading a customer from the database, for which I do not know the industry in advance, since the industry_id is stored in the Customer table!
So my problem is: how can I combine the abstract factory approach with Yii’s find() and findOne() methods? My goal is that I could call Customer::findOne(5) and it would return an object of customer number 5 as a model of the class associated with this customer’s industry_id.
For example, if customer number 5 is a notary (as indicated by the industry_id column in the Customer table), a lookup using Customer::findOne(5) should return a model of class NotaryCustomer.
Does any of you have a decent solution for this? Obviously, the solution should not do any additional DB queries to determine the customer’s industry_id upfront.
Looking forward to your thoughts on this!