Monday, February 23, 2009

Stop Relational Thinking

In my opinion the only reason why relational thinking should be kept in the contemporary curriculum is because of historical purpose and the constraint imposed by contemporary corporate data centers running relational databases. Come on people, there's a much better way to do things. Why are we constrained by this outdated, inferior and inadequate mode of thinking?

Developers should never have to think relationally except when they need to interact with those ignorant of object-oriented thinking. The object model is vastly more powerful than the relational model and when developers are thinking relationally, they are creating the wrong environment. Developers should always be thinking of the domain-object model which includes behavior along with data. The data model is a subset of the domain-object model and is easy to generate when needed. The data model is considered for those on the relational side of the operation and have limited understanding (MIS types).

Yes, I understand about the object-relational impedance mismatch. All developers need to understand this important constraint when interfacing the OO world to the relational world. In the meantime, the language of the developer should be in the context of the domain-object model. If the organization isn't using an ORM tool (ie., Hibernate), then the least acceptable architecture would include a persistence layer so separation of concerns is maintained. SQL should never appear in your POJOs.

Dependency Inversion Principle

This morning I was "retroFactoring" an application for purposes of giving an assignment to my software design class requiring application of Robert (Uncle Bob) Martin's Dependency Inversion Principle. I say "retroFactoring" because I was taking the application that was already refactored back to an application that I will give to the class for refactoring. In the process of doing so, the inversion of the dependency came about forthwith when I removed the interface. This required the switch class in the 'device' ('higherlevel') layer to learn about the classes in the 'lower level' layer - the light bulb and the fan. Thus I had to place an import statement in the switch class ('higher level') so it would know about these switchable objects ('lower level'). It was when I realized that I needed to place the import statement allowing access to these 'lower level' classes that I realized I was setting up the dependency of 'higher level' classes on 'lower level' classes. This is exactly the situation Martin refers to when he states: "High-level modules should not depend on low-level modules."

Programming Without If's: Challenge One

During the time between 2005-2009 I began my software design courses with a problem I call the “Bergin Calculator Problem” (Inspired by Joe Bergin’s Polymorphic Calculator). It requires the student to program a simple calculator with only six buttons. Three number buttons (2,3,5) , two operator buttons (+,-) and an equals button. The calculator need only perform one binary operation before yielding an answer following a strike on the equals button. A typical computation would involve entering 2, 2, +, 3, 3, = … and the display would indicate the answer of 55. The display would show the numbers entered in both the pre-operator and post-operator modes, but not the operator itself. Thus, one would only ever see numbers in the display. Following each computation, striking the equals button would also render the calculator ready for a subsequent computation with an entirely new set of numbers.
Over ninety per cent of the submissions I graded used conditional logic to solve the problem. The week following, the class would go through the problem and together, construct a calculator that uses no conditional logic nor loop structures. The fact that this exercise amazes many students, indicates the very real possibility that most have been taught how to use an object-oriented language to do procedural programming - a very easy thing to do. In fact, I recall one graduate student who had taken the problem back to his work place and one of his co-workers, literally a rocket scientist, said the problem couldn’t be solved without the use of if’s. Since then, I have taken to giving problems to students that require them to produce a solution not dependent on conditional logic – I call this “Programming without if’s.”
I will discuss in another place the problem of over-engineering but for now assume it’s OK, in fact desirable, to construct an over-engineered solution. Why? The metaphor I like to use is that of the toolbox. When you go to your toolbox and see only a hammer, then every problem appears to be a nail. Most contemporary programmers were taught by procedural programmers whose only adaptation to learning object-oriented programming was to begin using an object-oriented language. One way to break out of this mental trap is to solve some problems without reaching for the hammer, which in the programmer’s case is the conditional logic structure.
Do I expect programmers to avoid using conditional logic as a best practice? No, the student of programming has to understand the difference between what we do to expand our capabilities, ie., put more tools in the toolbox, and what we do when programming professionally. Programming without if’s will expand your ability to see alternatives in the power offered to you by the object-oriented paradigm. If you’d like to take the Calculator Challenge a zipped Eclipse project named SwingCalculatorWithIfs is here. See if you can refactor this code to a solution that contains no conditional logic (if statements). A discussion of the answer will follow and I will post a solution at the same address the challenge code was posted.