
Object-Oriented Design Heuristics (2017) [slides] - tjalfi
https://www.slideshare.net/kim.mens/objectoriented-design-heuristics
======
miguendes
The book the slides are based on is by far the best book on OOD/P I've ever
read. Learned a lot from it. OO is such a hard subject that most of the people
end up writing procedural code with classes (looking at you java).

~~~
kemiller2002
The book you're talking about is it the one mentioned (i quickly looked at the
slides): Object Oriented Design Heuristics?

~~~
miguendes
Yes, Object-oriented design heuristics by Arthur J. Riel

[https://www.goodreads.com/book/show/179206.Object_Oriented_D...](https://www.goodreads.com/book/show/179206.Object_Oriented_Design_Heuristics)

------
thomk
I try to follow a few rules when writing OO code.

1\. Make classes do one thing that is basically summarized in the class name.
(This also takes care of 'separation of concerns')

2\. Be careful to not over-abstract. That results in many tiny classes, aka
ravioli code. Nobody, not even you, will remember what all those little
bastards do. 3\. If a class is bigger than a page (or two) of code, it's
probably too long.

4\. Design patterns are for inspiration, not the law. Solve problems, don't
prove how smart you are.

5\. Make your classes as simple as possible. You will thank yourself later.

6\. If you have to write a comment that explains how some confusing thing
works; that code block is a good refactoring candidate.

7\. Refactor, refactor, refactor. Refactoring is rewriting code for clarity.
The more you do this, the more your code will become clear to the reader. I
find refactoring often reduces my LOC drastically.

8\. If you just learned a technique/pattern and that technique/pattern is
suddenly popping up everywhere in your code; make sure you aren't just using
it because it's fun. Say you just learned what a singleton pattern is, now
your code is littered with singletons. That's a good sign that you are forcing
yourself to use your new found toy and reconsider.

9\. Long method names. Don't be afraid to have long method names. Yes, it
looks ugly, yes it takes time but you will thank yourself later and often a
long method name will compensate for the lack of documentation on that method.

10\. Your program should basically be a bag of loosely related, self-contained
components. Think of them like parts of an engine, they each do one thing very
well and they each have an interface to the rest of the engine. Also, they can
individually be swapped out for another component (as long as they bolt up to
the engine appropriately).

Understanding OOP is definitely a paradigm shift in thinking and it is also
loaded with many a foot gun (especially when you are new).

~~~
mratsim
My rule for writing OO code is to not write OO code.

Procedural code is:

\- simpler to analyze, audit and (formally verify)

\- simpler to multithread

\- maps to what a program does: a series of transformations applied to an
input

\- maps to low-level construct in the CPU, i.e. call/ret

\- doesn't force you to use heap memory and suffer cache misses due to rampant
pointer indirection.

Note: I intentionally avoid saying functional programming.

There is a balance between having no state (Haskell) and allowing mutation
because mutation is useful (C, OCaml).

~~~
cztomsik
It is true that some parts of your project can benefit from centralised
approach (and that sometimes you really need to count every tick) but this
fashion of blaming OOP is really weird and should stop.

It is still the best way to architecture big systems. I'm not talking about
classes, I'm talking about decentralised, decoupled, small systems,
communicating with each other using messages.

~~~
dgb23
> this fashion of blaming OOP is really weird and should stop

Right. There are many places where OO fits well.

As you mentioned in the medium/large on the services/systems level. But it is
also a good paradigm to model pretty much any real, outside thing. A database,
a file-system abstraction (loading configs etc.), an external web-service, a
peripheral device (keyboard, mouse), a GUI context (the whole thing, not the
parts) and so on.

In these cases we want the properties of OOP: local retention, message
passing, abstraction through public interfaces and state-machine-like
behavior.

The issue arises when we model data with OO: A Person is not an object in your
system. It is an associated data-structure. Treat it as such. A User interacts
with an interface (CLI, config files, GUI...) treat those as objects. The data
about the User is just data about the User.

I don't have an authoritative opinion to offer here. I'm just a dude who
writes programs. This is merely the model that works for me.

~~~
mratsim
> In these cases we want the properties of OOP: local retention, message
> passing, abstraction through public interfaces and state-machine-like
> behavior.

That's not OOP but Actors or event loops.

~~~
dgb23
Depends on who you are asking.

[https://userpage.fu-
berlin.de/~ram/pub/pub_jf47ht81Ht/doc_ka...](https://userpage.fu-
berlin.de/~ram/pub/pub_jf47ht81Ht/doc_kay_oop_en)

[https://www.infoq.com/interviews/johnson-armstrong-
oop/](https://www.infoq.com/interviews/johnson-armstrong-oop/)

------
tjalfi
(submitter)

The material in the slides is based on the book Object-Oriented Design
Heuristics[0] by Arthur Riel.

[1] has a list of the heuristics. It may be incomplete.

[0]
[https://www.goodreads.com/book/show/179206.Object_Oriented_D...](https://www.goodreads.com/book/show/179206.Object_Oriented_Design_Heuristics)

[1]
[http://www.vincehuston.org/ood/oo_design_heuristics.html](http://www.vincehuston.org/ood/oo_design_heuristics.html)

------
foobar_
After a previous discussion here it seems people confuse classes with modules.
At the risk of repeating myself.

Class based inheritance - Bad

Traits, roles, mixins - You are still thinking in terms of inheritance so its
Meh.

Combining Data and Code - Slow.

Closures, Functors - Cool ... classes with single methods are as "single
responsibility" you can get.

Interface Inheritance - Go / protocols from clojure - Better

Interfaces without inheritance - Modules - Best ... the way software is meant
to be written. This is the reason why APIs, libraries are so reusable. Modules
are like contracts for the function call interface. Because of this you also
get the ability to load plugins as opposed to the whole dependency injection.

