Getting Started with Object-Oriented Design (Part 1): Shifting from Process-Oriented to Object-Oriented Thinking
Michiharu Ono
Posted on November 24, 2024
“Hmm… Have you ever heard of OOD?”
That’s what one of the senior developers at my company once asked me, just 10 seconds after glancing at my code.
Without thinking, I quickly replied, “Yes.”
It was an instinctive answer, but the truth was, I didn’t fully understand what Object-Oriented Design (OOD) really meant at the time—or why it even mattered 🤷♂️
When we’re just starting out as web developers, it’s easy to focus on learning new languages, frameworks, and building projects as quickly as possible. The goal is often just to get something working, and concepts like OOP or OOD can feel abstract, like something you’ll figure out “later.”
But here’s the thing: later can come much sooner than you expect, especially when your code starts growing in complexity. (At least, it did for me 😅)
At its core, object-oriented design is about managing the relationships between objects, enabling the system to adapt efficiently to future changes.
But why do we need this? And what does managing the relationships between objects mean exactly?
Two Ways to Think About Systems: Process vs. Object-Oriented Perspectives
Before we dive into answering that question, let’s first explore the object-oriented view of the world. Without adopting this mindset, the principles and patterns of OOP can feel abstract and difficult to grasp. 😌
To build a solid foundation first, I want to start by comparing two key ways of thinking about systems: the process-oriented approach and the object-oriented approach. These two paradigms offer different perspectives on how we break down and model problems.
1. The Process-Oriented View
In general, the process-oriented perspective is about focusing on the sequence of actions or steps that need to be performed in a set order to achieve a result.
Don't think too hard on this 🙆♂️
It’s similar to following a recipe, where each action follows a specific order, and one step leads to the next. The key here is flow—moving from one state to another by completing predefined actions.
Let’s take a look at the example of making tea from a process-oriented perspective, where the focus is on the sequence of steps:
- Boil Water: The first step is to boil water. The key here is that the water needs to be hot enough for the tea, regardless of how long it takes to boil.
- Add Tea Leaves: Once the water has boiled, the next step is to add the tea leaves. This step can only happen after the previous one is completed, as it depends on the water being ready.
- Let it Steep: After the tea leaves are added, the water must steep for a specific amount of time to extract the flavor.
- Pour Tea into a Cup: Finally, after the steeping process is finished, the tea is poured into a cup.
In this approach, the focus is on performing actions in a specific order. If any action is skipped or carried out out of sequence, the result will not turn out as intended.
The process-oriented view sees the world as a series of actions, each building on the one before it, where every step must follow a predetermined flow to achieve the desired outcome.
2. The Object-Oriented View
In contrast, in object-oriented view, the focus is on "objects." These objects are like little workers that have two things: information (called attributes) and actions they can do (called methods).
Instead of viewing tasks as a strict sequence of actions, here we emphasize the interaction between objects, where each object performs actions based on the requests (or "messages") it receives from other objects. In other words, each object can "ask" other objects to do things, and they act based on those requests.
Let’s revisit the tea-making example from an object-oriented perspective.
==The Objects in Tea-Making==
- Kettle: The Kettle has information like the current temperature of the water and whether it's boiling. It also has an action it can perform, like boiling the water.
- TeaBag: The TeaBag has information about the type of tea and whether it’s steeped or not. It can also steep the tea in hot water.
- Cup: The Cup holds the tea once it’s made. It has information about what’s inside (like tea or water) and whether it’s full.
- Person: The Person is the one who makes everything happen. The Person asks the Kettle to boil water, tells the TeaBag when to steep, and pours the tea into the Cup. The Person coordinates the entire process.
You can already see how we capture the world is a little bit different from the setup. Now, let’s see some examples of how these objects might work together to make tea:
==How the Objects May Work Together==
- The Person tells the Kettle to start boiling the water. The Kettle listens and heats the water without needing further help from the Person.
- After the water is ready, the Person checks the TeaBag, maybe looking at how strong the tea should be or how long to steep it. The Person then tells the TeaBag to start steeping the tea (the Person might put the TeaBag in the water and monitor how long it steeps).
- Person pours the Tea into the Cup once the tea has steeped enough, the Person checks the tea. If it’s ready, they tell the Kettle to pour the tea into the Cup. The Cup now holds the tea, ready for the Person to drink.
It is describing the same tea-making process, but do you now see the difference from the process oriented view? 🙂
In the object-oriented view, the focus is on how objects interact with each other by sending and receiving messages, rather than following a linear sequence of actions. It is just a different point of view💡 Each object has its own responsibilities and responds to messages (or method calls) from other objects based on its current state. This allows for flexibility—objects don’t rely on a predefined sequence of events but instead communicate as needed.
🤔 So, why do we need object oriented “DESIGN”?
In object-oriented applications, components (or objects) interact with each other, forming complex relationships and dependencies.
If these relationships aren’t properly managed, what would happen? A small change in one part of the code can cause problems in other areas, leading to instability and making the application harder to maintain.
Let's take the same tea-making example again, but this time imagine that the process isn’t organized well at all.
-
The Kettle and TeaBag are Too Dependent on Each Other:
- Imagine that the Kettle object not only boils the water but also decides how long the TeaBag should steep for some reason. In this setup, if you want to increase the steeping time, it might also affect how long the kettle boils the water, creating unnecessary links between unrelated tasks.
-
The TeaBag Controls the Boiling Process:
- If the TeaBag itself is somehow responsible for managing the boiling of the water, then it's now mixing two responsibilities: the boiling process and the steeping process. This would mean that any change to how the tea leaves steep (like changing tea types) could unintentionally interfere with how the kettle boils the water. This makes each object too tightly coupled and hard to modify without breaking other parts of the process.
-
The Cup Gets Involved in the Steeping:
- Now, let’s say the Cup is responsible for checking if the tea is steeped properly before it’s even poured. It may decide how long the tea should steep based on what is poured into it, creating confusion and redundant responsibilities. This prevents each object from focusing on just one task.
In this disorganized setup, making a change in one object (like adjusting how long the water boils) could unintentionally affect other objects, like the steeping time, and cause undesirable consequences, such as over-steeping or under-boiling the water. This results in a lack of flexibility and control, making it harder to manage and maintain.
Now, compare that to the organized object-oriented approach, where we treat each task as an independent object with its own responsibilities. If you want to change how long the tea steeps, you just adjust the TeaBag object without worrying about how the Kettle or Cup will be affected. This way, each part of the process is flexible, independent, and easier to manage. You can make changes to one object without breaking the entire system.
This is why we need OOD. By keeping these tasks separated, OOD lets you make adjustments and scale your system without chaos. This is why OOD is so powerful—it lets your code grow and adapt in a structured, maintainable way.
Wrapping up
OOD offers a way to manage the relationships between objects. While it might feel a little tricky at first, learning OOD ensures that your code isn’t just working for today but is also flexible and ready for future changes. By planning ahead, OOD helps you build code that’s not only sustainable but also scalable, making it easier to adapt as your project evolves.
In the next post, I will explain how to approach object-oriented design and introduce you to some tools.
Posted on November 24, 2024
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.
Related
November 24, 2024