** 본 포스팅은 '면접을 위한 CS 전공지식 노트'를 바탕으로 공부한 내용을 정리한 것입니다.
프로그래밍 패러다임이란?
: 프로그래밍의 관점을 갖게 해주는 역할을 하는 개발 방법론
일급 객체
-> 함수형 프로그래밍 방식이 선호됨: 고차 함수를 쓰기 위해 해당 언어가 일급 객체라는 특징(아래)을 가져야한다.
변수나 메서드를 함수에 할당할 수 있다.
함수 안에 함수를 매개변수로 담을 수 있다.
함수가 함수를 반환할 수 있다.
: 같은 이름을 가진 메서드를 여러 개 두는 것 -> '정적 다형성'
: 주로 메서드 오버라이딩, 상위 클래스로부터 상속받은 메서드를 하위 클래스가 재정의하는 것 -> '동적 다형성'
: SOLID 원칙
(Single Responsibility Principle)
모든 클래스는 각각 하나의 책임만 가져야한다.
GOD Object
라고 하기도 한다.아래와 같이 한 메소드가 두가지 기능을 동시에 한다면 작업을 분리해야한다.
class BookService:
def findBookById(query):
# DB에서 찾아오기
# Log 파일에서 찾은 정보 쓰기
단일 책임 원칙에 맞게 아래와 같이 수정할 수 있다.
class BookService:
def findBookById(query):
# DB에서 찾아오기
def wirteLog(log):
# Log 파일에서 찾은 정보 쓰기
(Open Closed Principle)
유지 보수 사항이 생기다면 코드를 쉽게 확장할 수 있도록 하고, 수정할 때는 닫혀 있어야 한다.
= 기능 확장에는 열려있지만, 기능 수정에는 닫혀있어야 한다.
= 기존의 코드는 잘 변경하지 않으면서도, 확장은 쉽게 할 수 있어야 한다.
(Liskov Substitution Principle)
프로그램의 객체는 프로그램의 정확성을 깨뜨리지 않으면서 하위 타입의 인스턴스로 바꿀 수 있어야 하는 것
자식 클래스가 부모 클래스의 변수타입을 바꾸거나, 메소드의 파라미터 또는 리턴값이 타입 혹은 개수를 바꾸는 경우
raise_pay
메서드는 파라미터 수가 다르다.wage
메서드는 리턴값이 다르다.class Employee:
raise_percentage = 1.03
def __init__(self, name, wage):
self.name = name
self.wage = wage
def raise_pay(self):
self._wage *= self.raise_percentage
@property
def wage(self):
return self._wage
class Cashier(Employee):
def __init__(self, name, wage, number_sold=0):
super().__init__(name, wage)
self.number_sold = number_sold
def raise_pay(self, raise_amount): # 파라미터 한개 더
self.wate += self.raise_amount
@property
def wage(self):
return "시급 정보를 알려줄 수 없습니다" # 리턴 값이 부모 클래스와 다르다.
자식 클래스가 부모 클래스의 의도와 다르게 메소드를 오버라이딩 하는 경우
class Rectangle:
"""직사각형 클래스"""
def __init__(self, width, height):
"""세로와 가로"""
self.width = width
self.height = height
def area(self):
"""넓이 계산 메소드"""
return self.width * self.height
@property
def width(self):
"""가로 변수 getter 메소드"""
return self._width
@width.setter
def width(self, value):
"""가로 변수 setter 메소드"""
self._width = value if value > 0 else 1
@property
def height(self):
"""세로 변수 getter 메소드"""
return self._height
@height.setter
def height(self, value):
"""세로 변수 setter 메소드"""
self._height = value if value > 0 else 1
class Square(Rectangle):
def __init__(self, side):
super().__init__(side, side)
@property
def width(self):
"""가로 변수 getter 메소드"""
return self._width
@width.setter
def width(self, value):
"""가로 변수 setter 메소드"""
self._width = value if value > 0 else 1
self._height = value if value > 0 else 1
@property
def height(self):
"""세로 변수 getter 메소드"""
return self._height
@height.setter
def height(self, value):
"""세로 변수 setter 메소드"""
self._width = value if value > 0 else 1
self._height = value if value > 0 else 1
(Interface Segregation Principle)
하나의 일반적인 인터페이스보다 구체적인 여러 개의 인터페이스를 만들어야 한다.
** 파이썬엔 없는 개념!
: 추상 클래스 중에서 추상 메소드만 있고 일반 메소드는 없는 것
(Dependency Inversion Principle)
추상화된 인터페이스나 상위 클래스를 두어 변하기 쉬운 것의 변화에 영향받지 않게 하는 원칙
= 상위 계층은 하위 계층의 변화에 대한 구현으로부터 독립해야한다.
상위 모듈에서 하위 모듈의 메소드를 사용하는데, 해당 메소드의 이름이 바뀌거나 하면 상위 모듈의 내용도 똑같이 바꿔야한다.
상위 모듈과 하위 모듈 사이에 추상화 레이어를 만들어서 해결할 수 있다.