Open- closed principle 개방 폐쇄 원칙
개방폐쇄법칙에 대해 알아보면 extension에 대해서는 open
modification에 대해서는 closed라고 써있다.
확장에 대해서는 개방
수정에 대해서는 페쇄라는 뜻인데 전혀 감이 오지않습니다.
이게 코드에 대한 제안이 아니라 코드에 behaviour에 대한
principle이기 때문에 이해가 바로 와닿진 않는다.
예제코드를 써보면서 감을 잡도록하겠다.
먼저 open- closed를 준수하지않은 코드를 먼저 보자.
# Animal 클래스 하나를 생성
class Animal:
#내부에 그 동물의 그 타입 프로퍼티를 가지고 있는다.
# a_type에는 코양이 혹은 강아지와 같은 동물의 종류를 넣는 것이다.
def __inti__(self, a_type):
self.a_type
# 각 동물들의 이름을 지정하고 이어서 이 동물들을 부르면
# 강아지인 경우에는 Bark 라고 대답해주는 함수를 만들건데 그 함수는 hey인데,
#argument로는 animal을 받고
def hey(animal:Animal):
# 그 animal 타입이 고양이라면 meow
if animal.a_type == 'Cat':
print('meoe)
# 그 animal 타입이 강아지라면 bark
elif animal.a_type == 'Dog':
print('Bark)
# 둘다 아니면 에러라 던저주고 클라리언트 코드로 넘어간다.
else:
raise Error('wrong a_type')
#클라이어트 코드
****
#고양이인 Kiity는 'Cat'
Kitty = Animal('Cat')
#강아지인 bingo는 'dog'
bingo = Animal('Dog')
hey(Kiity)
hey(bingo)
#콘솔창에는 meow
#bark가 나온다.
이렇게 코드가 마무리가 되지만 누군가
기능상 동물, 개, 소 , 낙타, 양을 추가해달라고 할 수있다.
그러면 클라이언트 코드에서는
#클라이어트 코드
****
#고양이인 Kiity는 'Cat'
Kitty = Animal('Cat')
#강아지인 bingo는 'dog'
bingo = Animal('Dog')
#소를 추가
cow = Animal('Cow')
#양을 추가
sheep = Animal('Sheep')
hey(Kiity)
hey(bingo)
hey(cow)
hey(sheep)
#콘솔창결과
#meow
#bark
#Cow
#Sheep 나오는 줄 알겠지만 나오지 않는다.
왜?
그를 사용하는 hey함수에서 소와 양에 대한 정의가 내려지지 않았기 떄문이다.
아까 위 설명에서 open == extension, closed == modification 가 되어야한다고 했다 .
지금 위의 코드들은 동물의 범주안에 고양이와 강아지가 있는데 이를 양과 소에 대해
확장을 하려고하니까 hey함수까지 수정해줘야되는것이다.
당연히 동물을 확장하는데 제한이 있을 수 밖에 없고 ,
이러한 코드 구조는 open- closed principle에 위배되는 것이다 .
그렇다면 open- closed principle 코드는?
바로 interface class 혹은 abstract class를 사용하는 것이다.
이번 코드에서는 확장에 대해서 오픈이 되어있고
그러니깐 소, 양, 다른 동물들이 와도 사이좋게 extension이 가능하고
modifcation에 대해서는 closed가 되어있는
위에 잘못된 코드처럼 hey함수에서 수정하지않아도되는 closed가 되어있는
open- closed principle 준수하는 코드를 만들자.
# 똑같이 Animal 클래스 생성
class Animaml:
# speak 함수 생성
# animal에 대한 speak함수는 아무것도 implementation하지않는다.
def speak(slef):
pass
#이제 Aniaml함수를 상속받은 Cat하나
class Cat(Animal):
#Cat의 경우 speak함수에 meow라고 대답을 해준다.
def speak(self):
print("meow")
class Dog(Animal):
def speak(self):
print("bark")
class Sheep(Animal):
def speak(self):
print("meh")
class Cow(Animal):
def speak(self):
print("moo")
# hey함수에는 animal을 argument로 받고
def hey(animal:Animal):
# 그 안에서는 animal에 speak함수를 호출
animal.speak()
#동물에 object를 만들어준다.
Kitty = Animal('Cat')
bingo = Animal('Dog')
cow = Animal('Cow')
sheep = Animal('Sheep')
#hey함수 수정없이 cow와 sheep을 호출!
cow = Cow()
sheep = Sheep()
hey(cow)
hey(Sheep)
#콘솔창결과 meow bark Cow Sheep
이렇게 나온다!!!
이렇게 코드를 마무리할 수 가 있는데 누군가와서 토끼나 사자를 추가한다..?
만약 바로 위에서 작성한 코드가 open-closed를 준수를 한다면
소와 양에 대한 확장은 자유롭게 할 수 있다.
hey함수는 modification에 대해서 closed가 되어있으니까 수정할 필요가없다!
클래스구조를 animal을 인터페이스로 가지고 그를 상속받는 고양이 강아지 소 양등을
가짐으로서 확장에 대해서 열려있고 수정에 대해서 닫혀있는 코드구조를 가질 수 있다.
이러한 클래스 구조를 가지게되면 소와 양 토끼. 사자 뿐만 아니라 100개의 동물을 확장할 수있다.
이것이 바로 개방폐쇄의 원칙이다.
'DesignPattern' 카테고리의 다른 글
Architecture EDA(Event Driven Architecture) 마틴 파울러의 4가지 구현 패턴에 대해 (0) | 2023.05.08 |
---|---|
AOP 입문자를 위한 기초 개념 : Spring을 사용하지 않는 AOP 구현 방법 (0) | 2022.12.29 |
MSA 아키텍쳐 (0) | 2022.10.05 |
SOLID 디자인 패턴 : 단일 책임 원칙 (Single Responsibility) (0) | 2022.10.03 |