본문 바로가기

카테고리 없음

객체 지향 설계의 5가지 원칙 - SOLID (예시코드)

Single Responsibility(단일 책임원칙)

*클래스는 단하나의 기만 가져야한다

 

(예시1)

원칙을 어긴 코드

def addPrint(num1,num2):
	num = num1 + num2
    print(num)
    return num

 

원칙을 지킨 코드

def add(num1,num2):
	return num1+num2
def numPring(num):
	print(num)

 

한개의 함수에서는 한가능 기능만 하여야한다

 

예시(2)

원칙을 어긴코드

class cat:
	def __init__(self,age,name):
    	self.age = age
        self.name = name
    
    def eat(self,eat):
    	pass
    def speak(self):
    	pass
    def walk(self):
    	pass
    def print(self):
    	print(f'age:{self.age} name:{self.name}')
    def log(self,logger):
    	logger.log(f'age:{self.age} name:{self.name}')
        logger.log(datetime.now())

 

고양이 는 먹거나 말하거나 걸을수는 있지만 프린트하기,로그남기기는 하지못한다 즉 원칙을 어긴코드이다

 

원칙을 지킨 코드

class cat:
	def __init__(self,age,name):
    	self.age = age
        self.name = name
    
    def eat(self,eat):
    	pass
    def speak(self):
    	pass
    def walk(self):
    	pass
    def repr(self):
    	return f"age:{self.age} name:{self.name}"
        
#고양이를 사용하는 클라이언트 코드에서는
kitty = cat()
print(kitty.repr())
logger.log(kitty.repr())

고양이 클래스에 고양이의 상태를 확인하는 함수를 넣은다음

클라이언트 코드에서 함수를 호출해주면 원칙을 지킬수있다

 

O

Open Closed principles(개방 폐쇄 원칙)

*확장에 열려있어야하고 수정에는 닫혀있어야한다

원칙을 어긴코드

class Animal():
  def __init__(self,type):
    self.type = type


def hey(animal):
  if animal.type == 'Cat':
    print('meow')
  elif animal.type == 'Dog':
    print('bark')

bingo = Animal('Dog')
kitty = Animal('Cat')

#Cow와 Sheep을 추가하기위해 hey함수의 수정이 필요하다.

hey(bingo)
hey(kitty)

 

원칙을 지킨 코드

#상속을 이용한 Animal class. 추가되는 동물에 대해 hey함수의 수정을 필요로 하지 않는다
class Animal: 
  def speak(self):  #interface method
    pass

class Cat(Animal):
  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")

def hey(animal):
  animal.speak();


bingo = Dog()
kitty = Cat()
sheep = Sheep()
cow = Cow()

hey(bingo)
hey(kitty)
hey(sheep)
hey(cow)

 

L

Liskov Substitution principle(리스코프 치환 법칙)

*서브타입은 언제나 부모타입으로 교체할수 있어야한다

 

I

Interface segregation(인터페이스 분리 원칙)

*인터페이스를 각각 사용에맞게 잘 분리해야한다는 원칙이다

 

만약 수륙양용차라는 인터페이스가있다

이 인터페이스에는 차에있는기능과 배에있는기능이 같이들어가있다

 

만약 아반떼라는 클래스를 만들때 수륙양용차인터페이스를 참조하게되는데

이경우 배에 있는기능들은 사용하지않게된다 즉 쓸모없는 코드가된다는뜻이다

 

좋은코드를 짜기위해서는 수륙양용차 인터페이스를만들지말고 

자동차 인터페이스,보트 인터페이스 두개로 나누어 인터페이스를 만들자

 

D

Dependency inversion(의존관계 역전원칙)

*어떤 Class를 참조해서 사용해야하는 상황이 생긴다면, 그 Class를 직접 참조하는 것이 아니라 그 대상의 상위 요소(추상 클래스 or 인터페이스)로 참조하라는 원칙

 

원칙을어긴코드

class Cat:
  def speak(self):
    print("meow")

class Dog:
  def speak(self):
    print("bark")


#Zoo depdns on Cat and Dog
class Zoo:
  def __init__(self):
    self.dog = Dog()
    self.cat = Cat()

  def speakAll(self):
    self.cat.speak()
    self.dog.speak()


zoo = Zoo()
zoo.speakAll()

 

원칙을 지킨 코드

class Animal: #abstract module
  def speak(self): #interface method
    pass

class Cat(Animal):
  def speak(self):
    print("meow")

class Dog(Animal):
  def speak(self):
    print("bark")


#Zoo depends on Animal.   (Not Cat, Not Dog)
class Zoo:
  def __init__(self):
    self.animals = []

  def addAnimal(self,animal):
    self.animals.append(animal)
  
  def speakAll(self):
    for animal in self.animals:
      animal.speak()

zoo = Zoo()
zoo.addAnimal(Cat())
zoo.addAnimal(Dog())
zoo.speakAll()