Tuesday, July 16, 2013

SOLID (object-oriented design) according to Candice

The final exam I wrote for my degree was a theoretical module about software development. I cried before, during and after the exam. Without a photographic memory, having no frame of reference makes it incredibly difficult to make sense of theory. Those SOLID principles in the text-book looked like something the authors had made up and the examiners could easily fill 10% of an exam paper by asking a student to regurgitate. The people I work with today regularly talk about each of these things and coming back to review the SOLID principles I wonder why it was so hard to remember them in the first place.

For years I worked in teams where design was based on instinct and we made it up as we went along, or at least that was my perception. We never used terms like "single responsibility" and "dependency inversion". We never thought about "open/closed" and interfaces were few and far between. I didn't know that there was anything wrong with the way we were doing it. We solved problems quickly and we deployed features regularly. Was our code manageable? In my opinion, it "smelled" pretty shit and I had no idea why. The SOLID principles, had I given them any thought, could have made all the difference.

S IS FOR SINGLE RESPONSIBILITYOkay, so why is this important? Have you ever SEEN what happens when you have a class that takes in a very complex object and validates the contents, then logs stuff to the database, then does some processing on all of the various properties and returns some complicated result? Let me tell you. That is one very big, unreadable mess of code that should never have ended up in just one class. There are functions that spanhundreds of lines of code because everything is so tightly coupled that the idea of refactoring makes yourhead hurt. Every time one thing has to change, you are terrified that something else is going to break and when it does (because that's inevitable, right?) it takes ages to figure out which part is falling over and why.


Single responsibility talks about classes or modules having just one reason to change. Now wouldn't that be nice? If I have to make a change to the algorithm that calculates the discount that a customer is due, I shouldn't be seeing the general ledger entries being logged to the database in the same class. Calculating a value and logging it to the database in the same class violates this principle. Just because something is five lines long, it still isn't a reason to shove it with another responsibility.

O IS FOR OPEN/CLOSED PRINCIPLEI'm not going to lie to you. This one still feels a little higher grade. Officially, this principle says that "software entitiesshould be open for extension, but closed for modification". It really means that I should be able to extend something (derive a new thing from it and override where necessary or, in the case of an interface, implement its members in my own special way) but I must not change the original one.

I wonder if this is a bit like Barbie. The original Barbie doll is the basis of all other Barbie dolls. You can't change the original Barbie. She's closed for modification, but totally open for extension. The different versions of Barbie have different hair and different clothes. Some of them are bendy. Some of them have a tan. With all the transitions that Barbie has made she still needs to conform to some minimum set of requirements, one of which is her height. Otherwise, she's not Barbie. She's a Bratz doll or an imitation and we've forgotten who she is and where she came from. I'm not sure if I'm understanding this principle so well...

L IS FOR LISKOV SUBSTITUTION PRINCIPLEBarbara Liskov. She is a girl. Yay for girls! She was one of the first women in the USA to earn a Ph.D. in the area of computer science. This principle states, and I quote Wikipedia "in a computer program, if S is a subtype of T, then objects of type T may be replaced with objects of type S (i.e., objects of type S may be substituted for objects of type T) without altering any of the desirable properties of that program (correctness, task performed, etc.)."

In girl talk, if I replace Barbie A with new and better Barbie B that was derived from A, then Ken shouldn't know the difference. Why? Barbie B can do all the things herpredecessor did. The meals will still be cooked properly, she will still look amazing, and Ken will still be standing there with stars in his eyes wondering just how she does it.

I IS FOR INTERFACE SEGREGATION PRINCIPLE (ISP)To segregate means to set apart, divide, isolate, you get the picture. If you do the reading on this, the Xerox example will probably come up. I had to read it twice before it made sense to me. This principle is actually very simple. No client should be forced to depend on methods it does not use. In the example, some module knows how to print, staple, you name it. Each small function on the copier depends on the big-ass module that can do everything when really it should be the other way around.

If you implement an interface and you end up throwing a NotImplementedException in one of the methods because it'll never be used, you have violated this principle. The interface is too big. Split it out into subsets.

D IS FOR DEPENDENCY INVERSION PRINCIPLEOne should "Depend upon Abstractions. Do not depend upon concretions." I didn't know what a concrete class was until I was studying for an exam and had to learn about some or other programming pattern. I hadn't heard this term before because in the project I was working on, all our classes were concrete. A concrete class is actually just a class that can be instantiated. It's not abstract, nor is it an interface. It's a thing. Like Stiletto is a concrete type that implements an interface IFootwear. IFootwear cannot be instantiated so it is not concrete. Where possible, depend on IFootwear rather than Stiletto.

I don't have a great way to explain why this is important, although testability comes to mind. Since I'm lazy, and it's quite late, I think that you might find the dude who wrote this article gave it a lot more thought than I probably ever will!

CONCLUSIONLike everything in life, there are exceptions to the rules and one of my favourite things about being a developer is experimenting. Sometimes what you end up with is "textbook", and sometimes it isn't. I think that people like Uncle Bob, Barbara Liskov, Martin Fowler etc got it very right because they probably coded themselves into the same corners we all have. The SOLID principles really make sense when you think about them retrospectively and when you have that frame of reference. That's my take on it, anyway!
Full Post

No comments:

Post a Comment