views:

97

answers:

3

Suppose I have a customer object that has all of the standard customer properties (name, address, contact, etc). We get a new customer (Acme) who has a very specific request that invoices we send to them have our ID as a barcode. We don't want to this for all of other customers, so we intend on doing this as a special case for Acme. Now, let's suppose that many of customers have these small one-off requests. What would be the best way to mode this data:

I see a couple possibilities and their benefits/tradeoffs:

1) Hardcoded, at the point of the deviation, checking for id or customer name.
Benefits: Least effort, single point of integration
Tradeoffs: Sloppy code, highly prone to error. Modifying flags requires new deployment. Difficult to find deviations as properties grow in number.

2) DB columns on Customer for each property. Flags would be set to true for the one customer, false for all the rest.
Benefit: Relatively simple, properties can be changed on the fly
Tradeoff: Makes very wide databases and sloppy schema. As more properties are added, the data will become increasingly unmanageable. Code will get sloppy too as many unnecessary properties will need to be mapped.

3) Hard-coded property mapping. A Map that holds special properties for customers. The map can then be requested for special properties, and code flow can go forth from there.
Benefits: Single point of management.
Drawback: Hardcoded. Customer IDs/Names would be in the code. Making changes requires deployments.

4) CustomerProperty table with key/value columns.
Benefits: Clean. Single point of management. Dynamic.
Drawbacks: Relative complex, compared to the other solutions.

Obviously, choices would vary depending on the circumstances. If we have hundreds of deviations, it would be important to have a single point of management. If it was truly a one-off deviation, I think #1 would be okay, albeit hackish.

I have my opinions on what is best in which case....but I'd like to know everybody else's opinions.

A: 

I prefer the fully normalized approach; I'd have a table that enumerates the different one-off special requests, with its primary key. Then I'd have a join table that has two columns, both foreign keys, with the first column the customer's id, and the second column the id from the special requests table.

lumpynose
So lumpy votes for 4)
Merritt
+1  A: 

I would go with option 4. From experience, when I have opted for the quicker options, the result was inevitably the implementation of the optimal solution and the hack only caused problems. I always try to approach these problems from a domain perspective and in this case 4 is the best model. The difference in implementation is minimal compared to the maintenance of all the artifacts and eventual refactoring you will have to do.

eulerfx
2, and maybe 1, work well enough for a one-such situation. But you specifically said "suppose that many of customers have these small one-off requests", which means that this is a recurring situation, one that you'll need to support over time, and to my mind 4 is the way to go. Definitely use a model like lumpynose's, containing lots of descriptive information on each special case.
Philip Kelley
+1  A: 

I did a lot of 1) on a previous project of mine, and eventually moved to a solution like number 4). I used the location of my hacks to place hooks for customization. It definitely was easier to manage, especially as the customization requests grew.

I originally thought that 2) would work for your particular scenario (not accounting for the supposed additional customization requests, just the barcode request), because I assumed that other clients might also eventually want a barcode on their invoices. However, I could also see them wanting the barcoded information in a different format than what you initially designed for the first customer, so this would potentially lead to the problem you started with.

So I say go with 4), and therefore implement a many-to-many relationship beween your customization entities and your customer entities. Initially the customization entites should not need be more than values to perform switch statements in your application code where customization should occur.

Merritt