KAHIBARO
Discord Login Register

4.10 Object-Oriented Programming

Why Object Oriented Programming Matters

Most backend codebases are written using Object Oriented Programming, often shortened as OOP. As an absolute beginner, you do not need to become an OOP expert immediately, but you do need to understand what it is, why it exists, and how it changes the way you think about programs.

In earlier chapters, you saw programs as a set of variables and functions that work on data. With OOP, you start to group related data and behavior together into units called objects. This way of organizing code becomes very powerful in large backend systems.

This chapter gives you the big picture of OOP. Detailed syntax and language specifics will come later when you learn about classes and objects, inheritance, and other OOP topics in more depth.


From “Data + Functions” to “Objects”

Procedural Style: Data and Functions Are Separate

In a procedural style, you often have data stored in simple structures, and you write functions that operate on that data.

Imagine you are building a very small task management script. You might write something like this, in a Python-like pseudocode:

python
task_title = "Write documentation"
task_completed = False
def complete_task():
    global task_completed
    task_completed = True
def print_task():
    status = "done" if task_completed else "pending"
    print(f"{task_title} [{status}]")
print_task()      # Write documentation [pending]
complete_task()
print_task()      # Write documentation [done]

Here:

This is fine for tiny scripts. For real backend applications with hundreds of related pieces of data and behavior, it becomes messy and hard to maintain.

Object Oriented Style: Data and Behavior Together

In OOP, you think in terms of objects that represent entities in your system.

For the same task example, you would create a Task object that contains both the task data and the operations on that data:

python
task = Task(title="Write documentation")
task.print()        # Write documentation [pending]
task.complete()
task.print()        # Write documentation [done]

You do not need separate global variables or functions. Instead, you have:

This grouping of data + behavior inside a single unit is at the heart of OOP.


The Core Ideas Behind OOP

OOP has four commonly mentioned core ideas:

  1. Encapsulation
  2. Abstraction
  3. Inheritance
  4. Polymorphism

You will explore these ideas more deeply in related chapters, but you should understand what they mean conceptually now.

Encapsulation: Keeping Related Things Together

Encapsulation means grouping related data and the functions that work on that data into a single unit, and controlling access to that unit.

In simple terms:

Example in a backend context: a User object.

Instead of:

python
user_name = "alice"
user_password_hash = "..."
def check_password(stored_hash, password_attempt):
    # logic
    ...

You encapsulate this in a User object:

python
user = User(username="alice")
if user.check_password("password123"):
    print("Login ok")
else:
    print("Wrong password")

Here:

Encapsulation helps you:

Abstraction: Focusing on What, Not How

Abstraction means hiding complex details and exposing only what other code needs to know.

From the outside, you care about what an object can do, not how it does it.

Backend example: sending emails.

Consider this simple interface:

python
email_client.send(
    to="user@example.com",
    subject="Welcome",
    body="Thanks for registering!"
)

The code that calls email_client.send does not need to know:

All of that complexity is hidden inside the EmailClient object.

Abstraction is not only about objects. You also abstract through functions, modules, and packages. But OOP encourages you to build abstractions around real-world concepts like User, Order, Cart, Repository, EmailClient, and many more.

Key abstraction rule: Design objects so that other parts of the system can use them by reading a small, clear public interface and without needing to understand the internal details.

Inheritance: Reusing and Extending Behavior

Inheritance lets you create a new class that reuses and specializes another class.

Example: a simple payment system for an e-commerce backend.

You might have a base concept:

text
PaymentMethod

Then concrete types:

text
CreditCardPayment
PayPalPayment
BankTransferPayment

Conceptually:

In OOP terms:

You reuse common logic in the parent class, and children add or refine logic.

You will study inheritance in detail in a dedicated chapter. For now, remember the purpose: remove duplication and capture shared behavior in a common parent.

Polymorphism: One Interface, Many Implementations

Polymorphism means "many forms." In OOP, it is the idea that different objects can be used through the same interface, even though they implement the behavior in different ways.

Using the same payment example, you might write code like:

python
def process_payment(payment_method):
    payment_method.pay()
    payment_method.send_receipt()

Now process_payment can receive any payment object that understands pay() and send_receipt():

process_payment does not care which specific class it is. It just trusts that the object follows the expected interface.

This is very powerful in backend systems, because you can:

Later, in language-specific chapters, you will see how polymorphism is implemented and used in practice.


Thinking in Objects: Modeling Real Backend Problems

A big shift when learning OOP is changing how you model problems.

Instead of asking, "What functions do I need?" you ask, "What objects does my system have, and what should they be able to do?"

Let us look at a few backend examples.

Example 1: Simple User Management

Imagine a simple user system:

You might think about the following objects:

ConceptPossible Class NameExample Responsibilities
A userUserStore username, password hash, role.
Auth serviceAuthServiceRegister, log in, validate tokens.
User storageUserRepositoryLoad and save users in the database.

Now you can express operations like:

python
user = auth_service.register(username, password)
logged_in_user = auth_service.login(username, password)
user_repo.save(user)

Here, each object has a clear responsibility, and your logic is split across these objects, not in one giant script.

Example 2: Todo List API

Consider a simple backend for a todo list application.

Key concepts:

You might create:

ConceptPossible Class NameExample Responsibilities
A userUserUser data, user-specific logic.
A taskTaskTask data, mark as done, set due date.
A listTaskListContains multiple tasks, add/remove tasks, etc.
StorageTaskRepositoryInteract with database for tasks.
API layerTaskControllerReceive HTTP requests, call services or repositories.

Example flow in code-like thinking:

python
# In a controller handling "POST /tasks"
task = Task(title="Buy milk", owner=user)
task_repo.save(task)
return task.to_dict()

Again, you see how objects represent entities and operations in your system.


Objects, Classes, and Instances

OOP talks a lot about three words:

These are related but not the same.

Class: The Blueprint or Template

A class is a definition of what an object of a certain type looks like and what it can do.

Think of a class as a blueprint for building houses:

Similarly, a class describes:

Backend example: a user blueprint:

text
class User:
    data: username, email, password_hash, role
    methods: check_password, change_password, is_admin

That is the "recipe" for building user objects.

Object: The Actual Thing in Memory

An object is one concrete thing that was built using a class.

Using the house analogy again:

In code:

python
alice = User(username="alice@example.com")
bob = User(username="bob@example.com")

Here:

They share the same blueprint but hold different data.

Instance: An Object of a Specific Class

The word instance is usually used as "instance of a class."

For example:

"Object" and "instance" are often used interchangeably, but "instance" emphasizes that this object belongs to a specific class.

You will see phrases like:

They all describe concrete objects in memory.


State and Behavior

At the simplest level, an object has:

State: Data Stored in the Object

Backend example: a Session object in an authentication system.

Its state might include:

At runtime, for a particular user:

text
Session(
  user_id=42,
  created_at="2026-08-27T12:00:00Z",
  expires_at="2026-08-27T14:00:00Z",
  ip_address="192.0.2.10",
  user_agent="Mozilla/5.0",
  is_active=True
)

All of that is "inside" one object.

Behavior: Methods That Operate on the State

The same Session object might have methods like:

When you call these methods, they use and modify the internal state.

Example sequence:

python
session.is_expired()        # checks created_at and expires_at
session.extend(3600)        # updates expires_at
session.invalidate()        # sets is_active to False

The idea is that you do not manually manipulate small pieces of state from outside. Instead, you call meaningful methods on the object itself.

Important OOP habit: Modify an object's state through its methods, not by randomly changing its internal variables from outside.

This keeps your code safer and more predictable.


Responsibilities and Design

A large part of OOP is about deciding what each class should be responsible for.

If you give a class too many responsibilities, it becomes huge and hard to change. If you give it too few, you end up with many tiny classes that are hard to understand.

A good rule of thumb, related to clean code principles, is:

Single Responsibility Idea: Each class should have one main reason to change, which usually corresponds to one clear responsibility.

Examples in a backend:

Separating responsibilities across different classes helps you:

How OOP Shows Up in Backend Projects

You might be wondering where you will actually see OOP in backend development. Here are some places and patterns you will encounter again and again.

Domain Models

Most backends represent a "domain" such as:

You will often create domain model classes that reflect real entities in that domain, such as:

These classes usually:

Example for an order:

text
class Order:
    data: items, status, user, created_at
    methods: add_item, remove_item, total_price, complete, cancel

Data Access Layers

You usually do not have your controllers directly writing SQL queries everywhere. Instead, you put database logic into special classes, often called repositories.

Examples:

These objects provide methods like:

You will see this again when you learn about ORMs and the repository pattern.

Services

A service is a class that coordinates operations between different parts of the system.

Examples:

Service classes often:

Examples: Procedural vs OOP Style in Backends

To better understand OOP, compare a procedural-style backend snippet to an object-oriented one.

Example: Simple Login Flow

Procedural Style

python
def get_user_by_username(db, username):
    # run SQL
    ...
def verify_password(stored_hash, password):
    # check hash
    ...
def login(db, username, password):
    user = get_user_by_username(db, username)
    if not user:
        return None
    if not verify_password(user["password_hash"], password):
        return None
    session_token = create_session_token(user["id"])
    save_session(db, user["id"], session_token)
    return session_token

Everything is functions and dictionaries (or other data structures). There is nothing wrong with this for small code, but it does not scale nicely.

Object Oriented Style

With OOP, you might have:

Conceptual code:

python
user = user_repo.find_by_username(username)
if not user:
    return None
if not user.check_password(password):
    return None
session = session_manager.create_session(user)
return session.token

Here is what changed conceptually:

Your code is now expressed in terms of objects that correspond to the concepts in your system. This often makes it easier to read and maintain.


When OOP Helps and When It Can Hurt

OOP is very useful, but it is not magic. It can also be overused.

Where OOP Helps

OOP is especially helpful when:

Backend applications with users, orders, payments, permissions, and so on, typically benefit a lot from OOP structures.

Where OOP Can Hurt

OOP can cause trouble when:

The goal is balance. Use classes when they help you model your domain, and keep them simple and focused.


Summary

In this chapter, you learned the foundational ideas behind Object Oriented Programming:

In the next chapters, you will dive deeper into classes and objects, inheritance and composition, and clean code principles, where you will see how these ideas are expressed in real code and how they guide the structure of backend applications.

Views: 6

Comments

Please login to add a comment.

Don't have an account? Register now!