SOLID : Open closed principle, explain simply
Tags: programming, typescript, architecture
Published: 2022-09-11 09:49:23

Open closed principle defines like that

> Software elements (classes, modules, function...) should be open for extension, but closed for modification

😦? ← if you react like this now, keep reading this article👍

## 👎 Bad code
This is super small application that you can find how to say "Good morning" in each country
```typescript
class Country {
  name: string
  constructor(name: string) {
    this.name = name
  }
}

const greetingList = (countries: Country[]) => {
  countries.forEach(country => {
    switch (country.name) {
      case 'poland':
        console.log('dzien dobry')
        break
      case 'japan':
        console.log('ohayo')
        break
      case 'usa':
        console.log('good morning')
        break
      default:
        console.log('* no data *')
        break
    }
  })
}

const countries: Country[] = [
  new Country('poland'),
  new Country('japan'),
  new Country('usa')
]

greetingList(countries)
// dzien dobry
// ohayo
// good morning

```

😅 How could be bad code ?? 

well, if you want to add "spain" now, you would modify code like this
```typescript
const greetingList = (countries: Country[]) => {
  countries.forEach(country => {
    switch (country.name) {
      case 'poland':
        console.log('dzien dobry')
        break
      case 'japan':
        console.log('ohayo')
        break
      case 'usa':
        console.log('good morning')
        break
      // 👇 add this code "spain", this is key code!
      case 'spain':
        console.log('buenos dias')
        break
      default:
        console.log('* no data *')
        break
    }
  })
}

const countries: Country[] = [
  new Country('poland'),
  new Country('japan'),
  new Country('usa')
  // 👇 add this code "spain"
  new Country('spain')
]
```

This is exactly anti open-closed principle because `greetingList()` should be closed, we don't want it to be open.
In other words, we shouldn't modify `greetingList()` when we add/extension 
Someone even makes some mistake while modifying code.

## 👍 Good code
So how we write code ?? 
```typescript
// create interface
interface ICountry{
  greeting(): string
}

// create each country class
class Poland implements ICountry {
  greeting = () => 'dzien dobry'
}

class Japan implements ICountry {
  greeting = () => 'ohayo'
}

class Usa implements ICountry {
  greeting = () => 'good morning'
}

const greetingList = (countries: ICountry[]) => {
  for (let i = 0; i < countries.length; i++) {
    console.log(countries[i].greeting())
  }
}

const countries: ICountry[] = [
  new Poland(),
  new Japan(),
  new Usa()
]

greetingList(countries)
```

Important part of good code is creating **each country class** which depends on ICountry interface.
Then when you add "spain", just like that ↓

```typescript
// create interface
interface ICountry{
  greeting(): string
}

// create each country class
class Poland implements ICountry {
  greeting = () => 'dzien dobry'
}

class Japan implements ICountry {
  greeting = () => 'ohayo'
}

class Usa implements ICountry {
  greeting = () => 'good morning'
}

// 👇 add just "Spain class"
class Spain implements ICountry {
  greeting = () => 'Buenos dias'
}

// ⭐ Don't need to modify this function! 
// ⭐ It means greetingList is closed, but for extension, it is opened
const greetingList = (countries: ICountry[]) => {
  for (let i = 0; i < countries.length; i++) {
    console.log(countries[i].greeting())
  }
}

const countries: ICountry[] = [
  new Poland(),
  new Japan(),
  new Usa(),
  new Spain()
]

greetingList(countries)
```
Now as you see, just add Spain class. You don't need to modify `greetingList()`, so you might not make some mistake when you add country 👍

##(Add) 💎 React.js
[I even tweeted](https://twitter.com/zJhMFG8401Edt9c/status/1572329009266171904)
He wrote it as clean code, but it also resolve opened principle problem 😎

---

Some people says open-closed principle is a bit exaggerated, because it makes code more complicate than **bad code**.
Actually I think so too, and it depends on situation.

But I'm sure it's important that you know this knowledge aside from whether you will use it or not.
And I highly recommend you to implement some code by yourself

sayonara👋