SOLID : Открытый закрытый принцип, объясните просто

Открытый закрытый принцип определяет следующим образом

Элементы программного обеспечения (классы, модули, функции…) должны быть открыты для расширения, но закрыты для модификации

😦? ← если вы сейчас так реагируете, продолжайте читать эту статью👍

👎 Плохой код

Это супер маленькое приложение, с помощью которого вы можете узнать, как сказать «Доброе утро» в каждой стране.

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

Вход в полноэкранный режим Выйти из полноэкранного режима

😅 Как может быть плохой код?

Ну, если вы хотите добавить «Испанию» сейчас, вы бы изменили код следующим образом

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')
]
Войти в полноэкранный режим Выйти из полноэкранного режима

Это как раз против принципа open-closed, потому что greetingList() должен быть закрыт, мы не хотим, чтобы он был открыт.
Другими словами, мы не должны модифицировать greetingList() при добавлении/расширении.
Кто-то даже допускает ошибку при модификации кода.

👍 Хороший код

Так как же мы пишем код?

// 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)
Войти в полноэкранный режим Выйти из полноэкранного режима

Важной частью хорошего кода является создание класса каждой страны, который зависит от интерфейса ICountry.
Затем, когда вы добавляете «spain», просто вот так ↓

// 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)
Войти в полноэкранный режим Выйти из полноэкранного режима

Теперь, как вы видите, просто добавьте класс Spain. Вам не нужно изменять greetingList(), так что вы можете не ошибиться при добавлении страны 👍.


Некоторые люди говорят, что принцип «открыто-закрыто» немного преувеличен, потому что он делает код более сложным, чем плохой код.
На самом деле я тоже так думаю, и это зависит от ситуации.

Но я уверен, что вам важно знать эти знания, помимо того, будете ли вы их использовать или нет.
И я очень рекомендую вам реализовать какой-нибудь код самостоятельно

sayonara👋

Оцените статью
devanswers.ru
Добавить комментарий