The Myth of Reusability

Don't be fooled. Reusability is not free.

You are building an inventory system for a large chain of car dealerships. You know that cars have a lot in common with one another. Cars all have wheels. Cars all have an engine. Cars all have a unique identifier known as a VIN. Etc. So, rather than designing a new data model for every possible type of car, you come up with a base class that contains these commonalities, something like this:

public class Car { public string VIN; public Engine Engine; public Color Color; public List Wheels; public decimal MSRP; }

As the project progresses, you end up with quite a few different classes based off of this base car class: PickupTruck, Sedan, Suv, Limo, etc. The project turns out to be a major success, so they ask you to help design their new sales system. Not surprisingly, the sales system has a few things it needs to add to your base car definition, mainly SoldToCustomer and SalesPrice. So, we modify our base class to contain the extra fields that our sales system needs. The sales system doesn't really care about the type of engine or the type of wheels, but it gets that additional information for free.

After the sales system comes the web site. Next you build the CRM system and the EDI interface with the manufactures. With each revision, the car object continues to grow. Each system really doesn't need more than a handful of the properties, but it gets them free: reusability at its finest. Then, one day, it happens. It's time to rewrite the inventory system. The actual event may vary from company to company, but it always comes. Maybe it's a merger. Maybe it's a new programming language. Maybe everyone comes to the conclusion that the core of the system just blows. After all, when you built the inventory system, you were young and inexperienced. You've learned a lot since then.

It is at this point that you realize that all these systems didn't really get their extra functionality for free. The base car object now has 50 or so various properties on it, and you really don't know which ones the inventory system actually uses. You may be 90% sure about half of them--but you sure as hell wouldn't bet your paycheck on it. You didn't build the CRM system or the EDI interfaces, you had moved to management by then. To make matters worse, half the guys you worked with to build the inventory system are off doing other things now. Of course, even if you could narrow down which properties the inventory system was using, it wouldn't really matter. All of the other applications depend on the inventory system. They share the database. They share the classes. They share the tests. You can't possibility rewrite the inventory system without rewriting everything else. Oh... Shit.

As it turns out, the billing system never ended up needing to know about the type of wheels or the engine. Neither did the CRM system or the EDI. About all they ever used in those other systems was the VIN and the Color... and a hell of a lot of workarounds were coded because of that. You actually ended up having to create objects like CarSummary that weren't really derived from car, just so that you could display a list of these things without waiting 30 seconds for it to pull back the data. CarSummary didn't include wheels or engines, just the basic data about a car that every one of the systems used... well, except the inventory system, which used lazy loading instead... and the reports which bypass everything and go straight to the DB.

The more you think about it, the more you realize how much of a pain in the ass this is going to be. Of course, it should have been obvious. You should have noticed it when you had to bring the inventory system down to roll out a new version of the CRM system. You should have noticed it when you started coding all those caching workarounds for the web site. You should have noticed it when EDI changes inadvertently broke that screen on the inventory system... but you didn't. Now you're going to have to tell your boss that swapping out the inventory system is a 3-5 year project. Of course, that's quite perplexing to him, since it only took 8 months to roll out the inventory system the first time around. If these new tools are so much better, why is it going to take 4-6x longer to build the new system? And what is the new system really going to do to justify all that cost?

This situation could have been avoided.

The technical term for the cause of this cluster-fuck is "coupling." I would hope that most developers have at least a cursory idea of what coupling is--enough of an understanding to know it has bad connotations. But usually we think of coupling in terms of obviously bad design decisions. The truth is that coupling is also found in systems that are designed quite well. In fact, you can't have reusability without some form of coupling. The consequence of coupling is that it assumes stability. When you couple two classes, you are agreeing to rewrite or rework one of those classes when the other changes. As a result, you need to minimize or eliminate coupling between portions of code that have independent concerns, so that you can deal with those concerns without worrying about everything else at the same time.

How do we do this? To start with, we need to stop trying to reuse every possible bit of code. Always remember: reuse is not free, the cost of reuse is coupling. There are situations where reuse makes a lot of sense, but it generally makes the most sense within an isolated space. For example, user interface libraries are generally a good candidate. But take a look at the code that is shared. The shared code has to do with drawing, element ordering, controls, bindings, etc. all of these are user interface related. The data grid may be used to interact with a lot of SQL data, but a properly designed data grid generally doesn't have code to directly interact with SQL, because that is outside of the user interface domain.

We'll talk about specifics soon, but first remember this: when you build the inventory system, focus on building an inventory system. When you build the CRM system, focus on building a CRM system. When you build the EDI interfaces, focus on building EDI interfaces. All these systems don't need to share the same database. All these systems don't need to contain the same objects. These systems will need to communicate, but the communication should be explicit and isolated from the core of the system. Then, when the time comes to rewrite the inventory system, you have a much simpler, much smaller chunk of code to replace, and you'll know where to find it.

Linked By

Reader Comments

  • Dan F says Dude, nice post. I've been coming to this slow realisation myself. "One size fits all" usually ends up looking pretty silly :)
  • RH says Can't agree more! OO reusability looks so pretty on paper but just stinks in real life--kinda like communism.
  • AW says IMHO the article is misleading in its title,
    and shows that there are some things that
    you could learn about system design.

    "Always remember: reuse is not free,
    the cost of reuse is coupling."

    From the article it is obvious that you are
    talking about reuse of domain objects across
    systems, but reuse is a broader concept, and

    also incorporates service reuse.

    Service reuse is more important in design
    because it enables the effective handling of
    functional complexity of systems.

    I do agree with you that it is preferrable to

    use domain object translation to enhance the
    decoupling of collaborating systems, but
    decoupling should also be achived (more importantly)
    through the enforcement of service contracts and
    applying the "Single Responsibility Principle"
    - at a specific level of granularity
    .

    you said:
    "Not surprisingly, the sales system has a few
    things it needs to add to your base car definition,
    mainly SoldToCustomer and SalesPrice.
    So, we modify our base class to contain the extra
    fields that our sales system needs."
    This is just bad design -
    SoldToCustomer and SalesPrice are not attributes of a car!

    My suggestion to you:
    Go to www.solms.co.za
    click downloads
    register
    once registered, log in
    click course notes
    download:
    STCD_BusinessAnalysisUsingUML.pdf
    STCD_ObjectOrientedAnalysisAndDesignUsingUML.pdf.zip

    these may just give you an insight into how to build
    the system that business guys want.

    p.s. I am NOT employed by Solms TCD
  • Jesse Ezell says While there is a place for service reuse, simply replacing domain objects with services does not solve any real problems. It is just as easy to construct bad service contracts as it is to construct bad classes.
  • ben says 100% agree

    Jesse.

    no one said replacing domain objects with services just that they are seperate systems with potentially their own DB.


    "Always remember: reuse is not free,
    the cost of reuse is coupling.

    From the article it is obvious that you are
    talking about reuse of domain objects across
    systems, but reuse is a broader concept, and "

    No he is not ...Plenty of single domain /app have the same problem when they become large.

    "also incorporates service reuse.

    Service reuse is more important in design
    because it enables the effective handling of
    functional complexity of systems.

    I do agree with you that it is preferrable to

    use domain object translation to enhance the
    decoupling of collaborating systems, but
    decoupling should also be achived (more importantly)
    through the enforcement of service contracts and
    applying the "Single Responsibility Principle"
    - at a specific level of granularity
    "

    this article does not mention services ! It simply makes an opservation that re-use in large modular apps with shared code ( can be a DLL coupled via an interface) dont live up to the promise. No solution is mentioned or implied . Instead of services seperate independent modules can achieve the same result.
    .


    "Not surprisingly, the sales system has a few
    things it needs to add to your base car definition,
    mainly SoldToCustomer and SalesPrice.
    So, we modify our base class to contain the extra
    fields that our sales system needs.
    This is just bad design -
    SoldToCustomer and SalesPrice are not attributes of a car!"

    Agree this is bad design but is often done , Not because SoldToCustomer and SalesPrice are not part of car . For a car dealer these are perfectly fine and that is the main problem with reusability , the same things means different things to different groups. The reason its not good design is that the concept of car and all the existing code should be changed to break down these different views of car however it is likely changing the earlier systems maybe hard to explain to your boss so short cuts are made.

    With regard to UML based tools which you are plugging i often find these give pretty crappy designs in large systems after a while as they are focused on conceptual domain objects ( which tend to grow as was mentioned in the article) . Systems tend to grow better when using systems based on objects as an action and leaving the original object pretty sparse and simple however most tools stear users in the opposite direction.



Name 
Url
Comments