Return to Home Page
      Blog     Consulting     Seminars     Calendar     Books     CD-ROMS     Newsletter     About     FAQ      Search
 

9-14-03 Solve the Real Problem

Note: Because I've started treating this weblog as a place for essays that take a long time to write – which is fine, sometimes, but that attitude often stifles the easy flow of words – I decided to try an experiment, prompted by a reader question. Occasionally I get a reader question that stimulates some thoughts that might qualify as a non-essay weblog; some ideas that might be worth sharing.

I received an email this morning from a reader struggling with a project where he has already made a certain number of baseline architectural decisions, without, I think, really considering whether they are appropriate or necessary:

I'm trying to develop a business application in C++. I want to be able to build a framework of the business objects which can be extended later without touching the framework source.

My main problem (one of them anyway) has been designing a way for these objects to be persistent. I want to use a relational database product. The headache comes from being able to do polymorphic reads of the data from the database.

I have made various attempts to design a way around this but have just been running around in circles with factories, abstract factories etc and still no luck. I have read in your book Thinking in C++ about virtual constructors which I hoped would do it for me.

Problem Description

If have a class hierarchy of classes that looks like this.

Animal
  |
  +---Vertebrate
  |   |
  |   +---Mammal
  |   |
  |   +---Reptile
  |   |
  |   +---Fish
  |   |
  |   +---Bird
  |    
  +---InVertebrate
      |
      +---Insect

I want to be able to load from the database from any node in the hierarchy and have it polymorphically load the correct object types. E.g. If I load all animals from the database I want the set to contain instances of Reptiles, Fish, Insect as appropriate. I also want to be able to go down the hierarchy and load all instances of Vertebrates and have it load the correct instances of its subclasses.

Many of the solutions I've seen require the supertype to know of its subtypes and sometimes even requires instantiating an instance of a factory instance of each of the types even if it may not be used.

I want the superclasses to be built into a framework like for example a biology framework or accounting framework. Applications built on the framework would now extend the framework by creating new subclasses of the classes provided in the framework. In this situation it is not possible to go and modify the factory classes in the framework.

I hope you can help me with a solution to this problem.

You are trying to solve the problem of the "Object-Relational Mapping" (OR Mapping). Research that and you'll begin to understand the complexity of this problem. If you really need an OO database or the appearance of one, you should probably try to use an existing OO database rather than trying to build your own.

In addition, I suspect you have prematurely decided that you must build a framework. Read Martin Fowler on this, as well as some of his (and other folks) other writings on frameworks.

Finally, it sounds like you need to do what Dave Thomas and Andy Hunt call Tracer Bullets. You need to build an end-to-end solution, doing (from Extreme Programming, a.k.a. XP) "The simplest thing that could possibly work," and then decide what problems you really need to solve, rather than deciding up front that you have to have an OR Mapping, a framework, or even that you have to use C++.

One of the biggest reasons for software failures is not understanding what problem you really need to solve: the customer's problem. And even if you understand that it's about the customer, you are only part way there – you have to understand what the customer's actual problems are, and these are usually different than what the customer thinks their problems are. Often, the best way to flush out the true needs of the customer is to interview them, caputure some of the basic "User Stories" (another XP term) and implement those stories in the simplest and fastest way possible. Consider using a rapid development language like Python on an existing application server like Zope (which already has a built-in OO database) to build something fast and present it to the customer, just to see if you are even trying to solve the right problem.

He replied:

Thanks for replying really quickly and thanks for the slap on the wrist. I think your answer was really what I needed. The project I'm working on has been delayed for about 2 months now and up till now there seems to be no visible progress on it.

It has been a long and torturous chain of decisions that finally led me to even try to develop the application in C++ at all. I had for the last couple of years abandoned my C++ roots for Visual Basic, mainly because most of the requirements of our clients did not require using C++. However I decided to come back to C++ because VB just seemed to be a waste of time. Every project had to be rewritten again despite all the work you had done in a previous project trying to build some reusable components. I just got frustrated trying to do things in VB I could easily have done in C++. Years before that I had been working with a RAD tool called Magic which allowed you to deploy applications really fast, but that again drove me up the wall. It's implementation of even the simplest things like Comboboxes was dreadful. I could probably have lived with it if I didn't know any better. Alas here I am again thinking of dragging my self back to VB. Maybe I will eventually and maybe not. But one thing I will definitely do is concentrate on the user perspective by doing some UIs and slowly and gently start doing my domain classes and their implementation.

Thank you again

The problem with Visual Basic (pre-.NET, anyway) is that it tends to encourage a bad style of programming; in particular, mixing the UI and the business logic together, which discourages the creation of maintainable programs in favor of rapidly-developed, but hard-to-maintain programs. Thus, as you observe, you end up disposing of old programs rather than maintaining or reusing them. See Martin Fowler's article on Technical Debt.

Visual Basic doesn't have to work like this, despite the language and development environment. If you know that your goal is to separate business logic from UI to promote maintainable, reusable code you can do it. In addition, VB.NET has true OO support (along with all the other useful .NET doodads) and so it may satisfy your longings for C++ features. If you have deep knowledge of VB and it solves a lot of your problems for you (not, however, the OO database problem as far as I know), then it might be the most expedient solution to developing your system.

Project development is risk management, and depending on your needs this might be the best way to minimize your risks. I have often made the mistake of premature assumptions and only much later have come around to seeing (once again) that I should have tried "The simplest thing that could possibly work," even if that only gave me enough information to move on to a more complex solution. Most of the time, the simplest thing was all that I needed.

    Links I Read
Cafe Au Lait
Artima
Daily Python URL
Martin Fowler
Joel on Software
Paul Graham
Cringely
Search     Home     Web Log     Articles     Calendar     Books     CD-ROMS     Seminars     Services     Newsletter     About     Contact     Site Feedback     Site Design     Server Maintenance     Powered by Zope
©2003 MindView, Inc.