OOP Fundamentals: Tell 📣, don't ask 🚫
Tags: oop, beginners, learning, development
Published: 2024-01-23 12:00:00

Are you still stuck in the habit of using getters and setters in your code? Well, you've landed on the right page to
grasp one of the most fundamental concepts of Object-Oriented Programming!

---

# Rethinking Object-Oriented Development

Often, developers mistakenly believe they are practicing Object-Oriented Programming (OOP) simply by employing
service-like classes. The example below is a common scenario encountered across various projects:

```typescript
class IncreaseBankAccountBalance {
    constructor(private readonly _bankAccountRepository: BankAccountRepository) {
    }

    execute({id, increase}: { id: string, increase: number }) {
        const account = this._bankAccountRepository.findById(id)
        const currentBalance = account.getBalance()
        const newBalance = currentBalance + increase
        account.setBalance(newBalance)
        this._bankAccountRepository.save(account)
    }
}

class BankAccount {
    constructor(
        private readonly _id: number,
        private _balance: number
    ) {
    }

    getBalance() {
        return this._balance
    }

    setBalance(value: number) {
        this._balance = value;
    }
}
```

In this scenario, we fetch an account from a repository and then proceed to call getters and setters to update it. It's
akin to treating a private property like a public one, exposing its value and providing a method to modify it at the
user's discretion.

---

# Unveiling the Object-Oriented Approach

The core principle of OOP is to **tell** instances to perform work rather than manipulating their properties directly.
This encapsulation of logic within domain entities, rather than imperative services, defines true OOP.

Refining our example, we can shift the increase logic from the `IncreaseBankAccountBalance` service to the `BankAccount`
class through a well-named instance method:

```typescript
class IncreaseBankAccountBalance {
    constructor(private readonly _bankAccountRepository: BankAccountRepository) {
    }

    execute({id, increase}: { id: string, increase: number }) {
        const account = this._bankAccountRepository.findById(id)
        account.increaseBalance(increase)
        this._bankAccountRepository.save(account)
    }
}

class BankAccount {
    constructor(
        private readonly _id: number,
        private _balance: number
    ) {
    }

    increaseBalance(increase: number) {
        this._balance += increase;
    }
}
```

Now, notice that we no longer expose the private _balance_ property. Any user of the `BankAccount` class must go through
the
`increaseBalance` instance method, effectively encapsulating the logic of balance increase.

---

# Elevating Immutability for Code Integrity

As a bonus, we can take it a step further by introducing immutability to our code. This minimizes side effects by
returning a new instance of `BankAccount` with the updated balance, instead of modifying its private property directly:

```typescript
class IncreaseBankAccountBalance {
    constructor(private readonly _bankAccountRepository: BankAccountRepository) {
    }

    execute({id, increase}: { id: string, increase: number }) {
        const account = this._bankAccountRepository.findById(id)
        this._bankAccountRepository.save(account.withIncreasedBalance(increase))
    }
}

class BankAccount {
    constructor(
        private readonly _id: number,
        private readonly _balance: number
    ) {
    }

    withIncreasedBalance(increase: number) {
        return new BankAccount(this._id, this._balance + increase)
    }
}
```

---

In summary, here are some key takeaways for your future coding sessions:

1. Be cautious when exposing getters and especially when exposing a setter.
2. Objects should be the sole entities allowed to modify their properties.
3. Every method must be well-named, clearly expressing its intent.

---

Stay tuned for more insights! Free to follow me on this platform
and [LinkedIn](https://www.linkedin.com/in/thomas-heniart-757077120/). I share insights every week about software
design, OOP practices, and some personal project discoveries! 💻🏄