Objects & Pursuit of Happiness: Understanding Object Oriented Programming (OOP)

Written by raffaeleflorio | Published 2021/10/14
Tech Story Tags: oop | object-oriented-programming | object-behavior | java | object-happiness | object-oriented-system | programming | objects | web-monetization

TLDRI think happiness is a good criterion to help us to find and verify objects. After all, objects are living organisms. Unfortunately, the majority of object-oriented systems are tragedies. And common practices, considered good, are actually bad. The issue is that they are not related to the domain. I have defined some sad and happy objects to prove my point.via the TL;DR App

Responsibilities are what differentiate objects. They represent what an object can do for us. And in a good object-oriented system, each object should have correct responsibilities.

Is there any criterion to help us to verify and find them? I think happiness is a good answer.

A metaphor

The common way to define objects is wrong. Objects are not just data plus functions. In other words, objects are not a C file containing structs and related functions. They are much more.

Alan Kay, the OOP inventor, majored in biology. For this reason, the analogies between cells - the smallest unit of life - and objects are far from casual. Objects are inspired by the cells. Objects are inspired by life. Objects are living organisms. And in an object-oriented system, they collaborate to evoke a specific domain. Each object is responsible to do something.

Thanks to this point of view, the happiness definition makes sense:

Happiness is a state of well-being that encompasses living a good life, one with a sense of meaning and deep contentment.

So an object is happy if it does what it should do in the modeled domain. No more, no less.

Objects are in pursuit of happiness.

An example

The majority of object-oriented systems are tragedies. And common practices, considered good, are actually bad. I refer to DTO, ORM, Service objects, etc…

To show the differences I’ll consider a domain model with two points of view. The first one using common practices, the second one using object thinking.

The domain regards a pastry shop showcase. Talking with the pastry shop owner we identified five high priority user stories:

  • As an owner, I need to track pastry details, so that I can update my catalog;
  • As an owner, I need to remove tracked pastry details, so that I can update my catalog;
  • As an owner, I need to see tracked pastry details, so that I can manage my catalog;
  • As an owner, I need to sell pastry with a given quantity, so that clients can buy them;
  • As a client, I need to see the pastry showcase, so that I can see what I can buy.

Sad objects

With common practices in mind we usually start with:

interface PastryRepository {
  void save(Pastry pastry);
  void delete(String name);
  List<Pastry> findAll();
}

@Entity
class Pastry {
  @Id
  private String name;
  private Double price;
  private List<String> ingredients;

  // getters, setters ...
}

interface ShowcaseRepository {
  void save(ShowcaseEntry);
  List<ShowcaseEntry> findAll();
}

@Entity
class ShowcaseEntry {
  @Id
  private UUID id;
  private Pastry pastry;
  private Integer quantity;

  // getters, setters ...
}

class PastryService {
  // constructor

  void sell(Pastry pastry, Integer quantity) {
    // sell a pastry
  }

  void save(Pastry pastry) {
    // save a pastry
  }
}

According to the previous happiness definition, the Pastry objects have suicidal thoughts. They’re central in the conversation with the owner, but here they’re underestimated. They're screaming that they can do more for us. They are reclaiming respect.

Furthermore, we defined PastryService, PastryRepository, ShowcaseEntry and ShowcaseRepository . But the pastry shop owner never mentioned them in our conversation. They’re out of place. In other words, they don’t know their place in the Universe (the domain).

It’s a tragedy.

Happy objects

We can start with:

interface Pastry {
  void sell(Integer quantity);
  JsonObject description();
}

interface Details {
  void track();
  JsonObject description();
}

interface Showcase {
  void add(JsonObject description, Integer quantity);
  JsonArray description();
}

interface Catalog {
  void add(JsonObject description);
  void remove(CharSequence name);
  Optional<Details> details(CharSequence name);
  JsonArray description();
}

The first difference is that every object concerns the domain. They aren’t out of place. After all, they were born starting from user stories.

The second difference is that there isn’t any passive object. In the previous example, Pastry was a DTO without responsibilities. It was nothing more than a Map or a C struct. It was really sad because from the stories it’s clear that it'd like to sell itself. And with the responsibility to describe itself it knows its role in the Universe (the domain). Analogous reasoning applies to the other objects.

Conclusion

Considering the living organism metaphor, the happiness criterion can help us to identify responsibilities and objects.

If an object has too many responsibilities, it will be under pressure. And this means we missed one or more objects.

If an object hasn't responsibilities (e.g. DTO), we added bad objects that don't reflect the domain.

In conclusion, sad objects don't reflect the modeled domain. The latter should be the only one that drives us while writing object-oriented systems. With this in mind, we can assign correct responsibilities. And ask ourselves:

Is this object happy to have this responsibility in this domain?

If we forgot this point we’ll write tragedies. And common practices commit this crime.

So happy coding and let’s spread happiness!


Written by raffaeleflorio | 🪐 Abstractions explorer in love with OOP | 🧭 Software Architect | ☕ Java Developer
Published by HackerNoon on 2021/10/14