Saturday, May 13, 2017

Program to an Interface and not an Implementation

I have been struggling with trying to understand what it means to "Program to an interface and not an implementation." Nick Hodges said if he could teach new developers one thing it would be "program to an abstraction, not an implementation". This is the same thing. (https://goo.gl/GVbaoU)

So I asked Hodges to explain this to me. Instead of trying to regurgitate some sort of answer that might come up short of what I was looking for, he sent me a link to a fascinating thread on StackOverflow (https://goo.gl/PNq7bY). This really is a great read. After reading it I was close to understanding but still not getting all of it.

I have recently started reading Head First Design Patterns by Eric Freeman & Elisabeth Robson. This book does an absolutely fantastic job of describing the GoF design Patterns that Uncle Bob so bluntly told me I need to understand. To be quite honest, I never would have bought this book solely based on the cover. (Not buying this book would have been a mistake.)



Amazon: https://goo.gl/MVybeZ

On page 11 of Head First Design Patterns they point out Design Principal #2: "Program to an interface and not an implementation." They do an excellent job of explaining what this means. My ability to understand what they mean... "Not so much". This is even after reading page 11 three times and reading the entire SO link Hodges sent me.

Why am I so dim?
How come everyone else gets it but me?

Ah ha, it hits me.

Each Delphi Unit has an Interface section and an Implementation section. In Delphi these sections are like Public Scratch Paper and Private Scratch Paper. (https://goo.gl/B7U5RR) All Delphi noobs are taught to stick stuff in the Interface section that you want to share with other units and stick stuff in the Implementation section that you don't want other units to have access to.

That is NOT what it means to "Program to an Interface and not an Implementation."

I had to unlearn what I had known about Interface and Implementation because of my 25+ years of Turbo Pascal/Delphi. And relearn that there are different meanings associated with Interface and Implementation. Sometimes it takes the light bulb a long time to go on

My end goal in all of this "new learning" is to understand Dependency Injection and how to put DI to use when I design/redesign software. I'm slowly getting there. Delphi's Interface and Implementation sections have different usage and meaning than the OOP Design Principle: Program to an interface not an implementation.

So, what does it mean to "Program to an interface and not an implementation"?

You have to figure this out on your own. I'm not trying to be a smart ass here. Once you get it, you'll get it. Asking someone for a quick 5 minute explanation won't do it. You'll have to dig and keep trying until it makes sense for you. In learning this concept some people use widgets. Some use sprockets. Some use ducks. I like chess.

Think about the simplest piece in a chess game. The Pawn.

What's the same about every pawn?
What's different about each pawn?
If you forget about color, how many different pawns are there? 8, 1, 3, 4 ?
What about the pawn to the far-left?
What about the pawn to the far-right?
What about the pawn that reaches the last row?
How many different moves does a pawn have?
Do all pawns have the same moves?

Trying to understand what it means to "Program to an interface and not an implementation" requires a different way of thinking.

Here is my completely oversimplified chess example:
+--------------------------------+
| PawnMovement (Interface)       |
+--------------------------------+

+--------------------------------+
| PawnMovementImplementations    |
+--------------------------------+
ForwardOne 
ForwardTwo
AttackLeft
AttackRight
EnPassant

So to me learning how to "Program to an interface and not an implementation" means making sure your pawn has movement not what the pawn's movement is.

Think this:
Pawn1.PawnMovement.ForwardOne
Pawn1.PawnMovement.ForwardTwo
Pawn1.PawnMovement.AttackRight
Pawn1.PawnMovement.EnPassant

Don't Think this:
Pawn1.ForwardOne
Pawn1.ForwardTwo
Pawn1.AttackRight
Pawn1.EnPassant

Enjoy!

Semper Fi,
Gunny Mike