Principles of Object-oriented Programming: Why SOLID?

SOLID for Newbies

Future Principled Programmer

As a newly hatched programmer, comparing notes comes second nature to me. How can my code be more legible (but not verbose), elegant (but not clever), and defensive (but not paranoid)?

The easy rule of thumb passed down by my instructors has been “Make it work, make it right, make it fast”, a phrase that has been associated with a design paradigm that has come to be known as ‘agile software development‘ (and the wikipedia page). (see sidebar [under construction].

But the assumption underlying that phrase is that you will be refactoring multiple times. How can we make sure our code can even be refactored? The object-oriented programming  (OOP) paradigm can make things either worse or better by separating chunks of code into blocks of associated functionality. One of the nifty mnemonics for a series of ‘principles’ that guide in the right direction are what are known as The SOLID Principles of OOP.

SOLID Principles of OOP

S)ingle Responsibility Principle

“There should never be more than one reason for a class to change.”

Example: If your building closes a floor for renovations, you should only need to modify one class in your elevator’s program–and that the class should only need to be altered when floors are added or deleted.

That said, a word of caution: some programs are small, or simple, and it would be possible to subdivide endlessly for variations and potentialities that may never happen.

Open/Closed Principle

Classes/functions should be open for extension, but closed for editing/modification. It should be usable “as is”. Never modify them, just extend them.
Because it’s very messy, and would probably ruin the coat.

[credit: Betrand Meyer (1988).]

This is done by abstraction. E.g., a drawing class should not implicitly mean to draw with a black pen on paper. Rather, it should be to draw with something onSomethingElse. Then I could draw on paper, or even on nothing (maybe you want your SimPersons to do the wave, or dance to YMCA) through a simple extension overlaying the draw class.

Liskov Substitution Principle
Subtypes must be substitutable for their base-types.
Your Duck superclass will crash when it tries to fly the eDucky even though Batteries Not Included (for Ducks).

Technically, this can be expressed as:

Don’t introduce new behavior into a subclass that the base class couldn’t do.

E.g., you have a Bird Class, and a Duck subclass. Any Bird can fly with any Duck. But say you add a Penguin subclass.  A call to the [Bird fly] on a Penguin will crash your program, since Penguins cannot fly.

Without help, that is.


A cool corollary of this is that if you follow the LSP, you implicitly are adhering to the Open/Closed Principle. LSP => OCP

Interface Segregation Principle

Classes that implement interfaces should not be forced to implement methods they do not use.

Use small interfaces, not “fat” ones.

Reset and Write for streams, but not for Write-Only (Printers) or Read-Only (Screen).

Dependency Inversion Principle

a) High-level modules should not depend on low-level modules — both should depend on abstractions.
b) Abstractions should not depend on details – rather, details should depend on abstractions.

E.g., Xcode’s SVC depends on GIT? Bad. Xcode’s SVC uses GIT? Good.

Xcode –> SVC interface –> GIT

E.g., MVC.

We can test modules independently of each other. We can mock or fake interfaces to test the business logic.

Print {with logic x} to {appropriate source}

Print…to file…to PDF…to email client…to printer.

Helpful Unicode Characters

While the standard keyboard usually grants access to all the keys in regular use, and creates hotkeys for power use, in the middle lie the forlorn, neglected symbols. Symbols tap into an ancient and effective register for quick and immediate recognition, so they are especially appropriate to squeezing more functionality from said keyboard. Moreover, as a relative beginner in a class with other relative beginners, I find that communicating hotkeys and shortcuts is not as effective without the appropriate icons. So here they are, along with the unicode number needed to type them.

[How do you type unicode characters? Switch to the unicode hex input keyboard, then hold ⌥ + ???? and the icon magically appears!]

Source: obvious, no?

[How do you add the unicode hex input keyboard? See below.] By the by, you’ll often see these characters’ numbers preceded by & or # or x’s. They refer to the number’s base, and the character system used. So these characters are actually preceded by a Ux????. ‘U’ for unicode, and ‘x’ for hexadecimal.

Mac Special Key Icons and Unicode Number
 – F8FF
⌘ – 2318 – the Command Key symbol
⌥ – 2325 – the Option Key symbol
⇧ – 21E7 – the Shift Key (really just an outline up-arrow, not Mac-specific)
⎋ – 238B – the Escape Key (also not Mac-specific; described as “BROKEN CIRCLE WITH NORTHWEST ARROW”, or an escape character from ISO 9995-7).
And while we’re at it, some related (not mac-specific):
⇥ – 21E5 – the Tab Key symbol
⏎ – 23CE – the Return Key symbol
⌫ – 232B – the Delete Key symbol
⌽ – 233D – a possible substitute for the Power symbol
And even less used, but still common enough to merit Apple’s attention:
Mnemonic note: ALL the common arrow symbols are from 2190 to 21FF (list here), so play around, have fun!
← – 2190
↑ – 2191
→ – 2192
↓ – 2193…
⇞ – 21DE – Page Up symbol
⇟ – 21DF – Page Down symbol
Adding the Unicode-Hex Input keyboard

Go to Preferences  → KeyboardInput Sources and search for “Unicode”, and check the box.