Skip to content

Instantly share code, notes, and snippets.

@btseytlin
Created August 28, 2017 08:29
Show Gist options
  • Save btseytlin/7dce15520c40c46821cdb8d3f4e0f603 to your computer and use it in GitHub Desktop.
Save btseytlin/7dce15520c40c46821cdb8d3f4e0f603 to your computer and use it in GitHub Desktop.
#Open/closed пинцип.
#Формулируется: Классы открыты для расширения, но закрыты для модификации.
#Пример (абсолютно непрактичный). Пусть у нас есть игра, типа веселая ферма для задротов.
#Есть животные, наследующиеся от базового класса Animal. Например Dog, Cat, Horse.
#Животных надо кормить. Поэтому есть кормушка класса Feeder, которая отвечает за кормление животных.
#Каждое животное кормится отдельным видом корма.
#Пример когда принцип не соблюдается
class Animal:
food_type = ''
def feed(self, food):
if not food == self.food_type:
raise(Exception('Не удалось покормить животину')
class Dog(Animal):
food_type = 'dog_food'
class Cat(Animal):
food_type = 'cat_food'
class Horse(Animal):
food_type = 'horse_food'
class Feeder:
def feed_dog(self, dog):
dog.feed('dog_food')
def feed_cat(self, cat):
cat.feed('cat_food')
def feed_horse(self, horse):
horse.feed('horse_food')
#Создаем животин и кормим их
dog, cat, horse = Dog(), Cat(), Horse()
feeder = Feeder()
feeder.feed_dog(dog)
feeder.feed_cat(cat)
feeder.feed_horse(horse)
#Выводы:
#Класс Feeder закрыт для расширения, потому что он вообще не расширяется, добавление новой животины возможно только модификацией класса, значит он открыт для модифиукации.
#Переделаем чтобы принцип соблюдался.
classs Feeder:
def __init__(self, available_food=None):
self.available_food = available_food or []
def feed_animals(self, animals):
for animal in animals:
animal.feed(self.available_food)
class Animal:
food_type = ''
def feed(self, feeder_food):
if not self.food_type in feeder_food: #если в списке еды, которая есть в кормушке, нет нужной еды...
raise(Exception('Не удалось покормить животину')
class Dog(Animal):
food_type = 'dog_food'
class Cat(Animal):
food_type = 'cat_food'
class Horse(Animal):
food_type = 'horse_food'
#Используем
animals = [Dog(), Cat(), Horse()]
feeder = Feeder(['dog_food', 'cat_food', 'horse_food'])
feeder.feed_animals(animals)
#Выводы:
#Feeder принимает на вход сколько угодно животных. Он очень просто расширяется: для создания новой животины просто создаём новый класс животины (ну и надо для неё насыпать новый корм в кормушку). Feeder вообще не знает как именно кормится животное, его не надо изменять при изменении функционала животины.
#Таким образом Feeder открыт для расширения и закрыт для модификации.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment