I’m starting off this series talking about Object Oriented Programming. It’s amazing how many people write C# or VB (.NET) with long, procedural methods with really no understanding of the true fundamentals of OO design.
I know, I know – it’s not you, and know what? I’m not talking about you.. but check out the code from the person next to you. See what I mean?
Just because you’re writing in an OO language, doesn’t mean that you’re writing OO code, or taking advantage of the Object Oriented benefits. An Object Oriented language is more than classes with methods, properties and events (even VB 6 had that!).
Learn the Fundamentals.
Get to know Interfaces, abstract classes, structs. I’m not picking on the thousands and thousands of extremely talented .NET developers that came from VB6 (I’m one of them), but I am acknowledging the fact the there are OO tools and strategies at your disposal now that never were before. Dig in to the delegates and the various eventing models, chained constructors, virtual and overridden methods. Go beyond if statements, while loops and language syntax similarities and embrace your new polymorphic self.
Perhaps, you’ve been a very successful developer for a very long time, I’m not saying that you have to change how you write all of your code. I am however, suggesting that you should realize that you have more tools in your toolbox than you might be aware of, and that if you learn how to use those tools, you will be more successful using the right tool for the right job.
Go beyond the fundamentals. A friend of mine teaches Object Oriented Analysis and Design for SMU, he once told me that if you have to use an if statement in your code then you’re not doing OO – it’s now procedural. I think he meant his statement in jest, (Although, he actually doesn’t allow his students to use if statements past the third section in his course) but the point was well taken. Beyond language semantics lie’s a whole world of patterns, approaches, and ways of doing OO that can make your life much, much simpler.
Pragmatic – Make new friends, but keep the old ones..
I’m not that much of an OO purist. I actually do feel that sometimes a well laid our “procedural” method can be easier to read, and communicate the intent of the code, but it’s a balancing act. Every time you write an if/switch statement you fork the flow of your code and increase it’s complexity, reducing your ability to maintain and test it. An OO purest might create a polymorphic object at this point and hop over to it instead of writing that if statement. I’m not saying that one way is better than the other. Like I said, writing readable/maintainable/testable code is a balancing act.
Beware of being “too” OO. It’s easy to get too pure on your OO. I’ve worked on systems where I had to fight through 7 to 8 levels of inheritance debugging and fighting all the way to figure out what in the world the system was doing. I’ve seen developers take 30 lines of procedural code and convert them in to 60 or 70 unique classes spread out over 6 projects. You can have too much of a good thing!
Is it OK to be “procedural” sometimes… can you be too OO?
The truth is, you want to use the right tool for the right job. The code on top is probably pretty readable and is fine… *right now* it won’t be too long and you’re going to want to start moving it closer to something like on the bottom. Why? With every scenario, and rule that gets applied to shipping orders, this code becomes less readable and harder to test. It won’t be long until you’re going to want to start validating (unit testing) your various order processes independent of each other. You’re going to want to break apart the coordination of an order, determination (the factory) of an order, from how it is actually handled… as you do that, your code will start to become more SOLID… but we’ll save that for the next post.
Interview Question Alert
Some of the related questions that I often ask:
Q:What’s the difference between an Interface and an Abstract class? When would you use one over the other? What implications does that have?
A: Interfaces define the contract with zero implementation, Abstract classes can have some implementation, but for the most part don’t. You can inherit from one base class, but implement as many Interfaces as you’d like to. Abstract classes can be versioned (if you’re going to strongly name them) but Interfaces cannot be versioned. Bonus Answer: Whenever you create an abstract class, you should always have an Interface to go with it, then code your dependencies to the Interface, not the abstract class.
Q: “Polymorphic” is a big OO word that developers like to throw around. Give a practical example of when you’ve used polymorphic behaviors in your code.
A: Anytime you use an abstract factory you’re implementing polymorphic principals. So the “processor.Process()” method above would be an example of Polymorphism, so would most Interface based development.
I hope this post has inspired you at some level to keep honing your development skills. I know that it was heavier on the “why” and low on the “how” specifics… I think that’s part of the point. You’ve got to go tackle some of this yourself. So go on, get out there.