Implicit Evaluation with PHP

12 April 2006

On Object Oriented Programming

There are three ways to program: functionally, procedurally, or object-oriented-aly. Any Turing-complete language will effectively let you use any of those types for development. Stereotypically, though, Scheme is a functional language, C is a procedural language, and Java is an object-oriented language.

For my own real-world use, I tend to use a hybrid procedural/OOP style. And I do that because bootstrapping purely OOP code is a little to magical for me. Assembly code, effectively what any Turing-complete language emits, is procedural. And just as a procedural language can use structs, it can use objects. But for a program to be completely object oriented, the runtime needs to know to look for a static main method in a given class. That is an unenforced expectation of the language. I don’t like it, so I stay procedural for at least that part of development.

Magical code is a big problem. At some point, I recognize that at some point, elegance be damned, code just needs to work. And that seems to be Java’s big mantra: it doesn’t matter how it works, just that it does work. And that is one of the justifications for Interfaces. Interfaces, for those fortunate enough not to have ever expierenced them, are class definitions. They are the .h file to a C++ class. They are Java’s God-child. “You don’t need to know how my class works, just that it does these things!” Thats all well and good under very strict guidelines. For code that someone a continent away developed and works, fine. It has one specific task and does that well. If it needs replaced, just develop a compatibility class to bridge from its replacement to its interface. Fine. But what about every other instance?

As it happens, your application has to implement something. It has to do something. You don’t need Interfaces for that. When you are developing an application, an unstable, incomplete application, you need to know how it works. Why it works. Knowing that TabPageOverallStatus subclasses Status and implements ITabPage, IDataPage, and ISerializable doesn’t mean squat to you when one function doesn’t work. When you call the method getTabCount and it doesn’t work, you need to know which class (or interface) defines it and if (and when) it is overridden.

A TabPageOverallStatus that defines everything it needs to, or can explicitly call methods in other discrete objects has a lower learning curve, is easier to debug than the magical class that pulls in methods from one of thirty interfaces or parent classes. After all, you NEVER know what the class or interface you’re implementing implements on its own.

If you truly do need that additional layer of abstraction, then keep it a discrete layer. But then it always has to work. It can never change. Its functionality always has to be retained. Even if its wrong.

Avoid magic in programming. Whenever you’re tempted to subclass, ask yourself, “What’s the different between calling this->getColor() and Phone::getColor() ? Now, whats the difference between the next generation of programmer knowing that getColor will be found in the phone class versus somewhere in the inheritence chain?”

Keep your code simple. If you’re not writing an operating system, it just doesn’t need to be that complex. Centralized, discrete, self-containing classes are easier to develop, easier to use and easier to fix than anything else. So just use them!

No Comments currently posted.

Post a comment on this entry: