2024. 3. 4. 22:29ㆍDevelopment
오늘은 객체 지향 프로그래밍에 대해 이야기 해 보려고 해요.
1. 객체 지향 프로그래밍이란?
2. 객체 지향 프로그래밍의 예
3. 객체 지향 프로그래밍의 특징
4. 객체 지향 프로그래밍을 이용하여 간단한 API 작성하기
1. 객체 지향 프로그래밍이란? - What is OOP?
오늘은 객체 지향 프로그래밍(Object Oriented Programming)이라는 개념을 들어보셨나요?
프로그래밍을 하고 있다면 한 번 쯤은 들어본 용어일테지만, 상당히 추상적이어서 단번에 이해하기 어렵습니다.
서비스의 규모가 커지면서, 프로젝트는 점점 복잡해졌고, 이를 체계적으로 설계하고 관리할 필요성이 생겼습니다.
객체 지향 프로그래밍은 특히 규모가 큰 프로젝트에 적합하며, 개발 생산성에 큰 도움을 주었습니다.
그러면 객체 지향 프로그래밍이 무엇일까요?
제가 이해하는 객체 지향 프로그래밍은 모든 데이터를 객체로 표현하고, 이 객체들의 상호작용으로 프로그램을 실행하는 것이라고 생각합니다.
객체 지향 프로그래밍은 프로그램을 어떻게 구현할 것인가에 초점을 두기 보단, 객체들이 어떻게 상호작용하는가에 초점을 맞춥니다.
즉 "돌아가면 그만이지"라는 사고 방식에서 벗어나, 어떻게 하면 체계적으로 잘 돌아가게 할 지 고민해야 합니다.
각 객체는 독립적인 역할을 갖고, 본인의 역할만 처리하면 되며, 나머지 역할은 다른 객체에게 넘겨버립니다.
따라서 객체 지향 프로그래밍의 원칙에 따라 잘 설계 되었다면, 문제가 생겼을 때 문제가 생긴 하나의 객체만 수정하면 쉽게 유지보수를 할 수 있습니다.
2. 객체 지향 프로그래밍의 예 - Simple Example
예를 들어, 사용자의 로그인 요청을 처리해야 한다고 가정해봅시다.
로그인을 하기 위해 어떤 정보가 필요할까요?
기본적으로 아이디와 비밀번호가 필요하겠죠?
사용자의 요청을 받는 login 함수와 사용자 정보 확인, 비밀번호 확인 등 여러 로직을 담고 있는 process_login 함수가 있다고 가정해볼게요. 그러면 아래와 같이 함수를 작성해볼 수 있어요.
def login(username: str, password: str):
return process_login(username, password)
def process_login(username: str, password: str):
user = check_user(username)
return check_password(user, password)
(실제로 로그인 로직은 더욱 복잡하니 이해 용도로만 봐주세요!)
여기서 추가 요청으로 인해, MFA(Multi Factor Authentication)를 적용하게 됐어요.
따라서 휴대폰으로 받은 인증 번호도 인증 로직에 추가해야 해요.
def login(username: str, password: str, code: str):
return process_login(username, password)
def process_login(username: str, password: str, code: str):
check_code(username, code)
user = check_user(username)
return check_password(user, password)
인증을 위해 필요한 데이터가 변경된다면 이와 관련된 함수의 인자를 모두 수정해줘야 해요.
지금은 간단한 예시이기 때문에 두 개의 함수만 수정해도 됐지만, 실제로는 더 많은 함수가 상호작용하기 때문에 프로젝트의 규모가 커질 수록 문제가 되겠죠?
그러면 로그인 요청을 담고 있는 데이터를 객체로 만들어 두 함수를 다시 작성해볼게요.
class loginRequestDto:
username: str
password: str
code: str
def login(login_request_dto: loginRequestDto):
return process_login(login_request_dto)
def process_login(login_request_dto: loginRequestDto):
check_code(login_request_dto.username, login_request_dto.code)
user = check_user(login_request_dto.username)
return check_password(user, login_request_dto.password)
참고로 데이터를 주고 받을 때 이를 담는 객체를 DTO(Data Transfer Object)라고 해요.
DTO는 데이터 필드와 접근 메소드로만 구성되어 있는 가벼운 객체예요.
위와 같이 작성하면, DTO의 구조만 바꿔주면 로그인 로직을 바꿀 수 있어요.
위 예시는 객체 지향 프로그래밍을 보여드리기 위해 다소 억지로 상황을 만든 감은 있지만, 객체 지향을 사용해야 하는 이유에 대해선 설명이 된 것 같아요.
다른 예시로, 객체 지향 프로그래밍의 특징을 이용하여 정다각형(Shape) 객체를 만들어볼게요.
class Shape:
color: str
perimeter: int
def length(self):
raise NotImplementedError()
class Triangle(Shape):
def length(self):
return super().perimeter // 3
class Rectangle(Shape):
def length(self):
return super().perimeter // 4
Shape 클래스는 색깔과 둘레라는 공통 데이터를 가지고 있고, length 함수로 한 변의 길이를 반환하는 함수가 있어요.
삼각형(Triangle)과 (Rectangle)에서 Shape 클래스를 상속받아 도형이 가지는 특징인 색깔과 둘레 데이터를 가질 수 있도록 했어요.
하지만 정다각형마다 한 변의 길이를 구하는 방식이 다르기 때문에 length 함수는 각 도형에서 구현해주었어요.
객체의 공통 성질을 추출하여 한 클래스로 만들고, 이를 상속하게 만들면 후에 도형에 대한 정보가 수정되어도 부모 클래스(Shape)만 수정하면 이를 상속하는 클래스에도 모두 적용이 돼요.
따라서 별 수고를 들이지 않고 데이터를 수정할 수 있겠죠?
위 두 예시에서 볼 수 있는 공통점은 확장에 유리하게 설계를 한다는 거예요.
확장에 용이하다는 장점 뿐만 아니라 더 많은 장점이 있기 때문에 다음 글에는 객체 지향의 특징을 통해 왜 객체 지향 프로그래밍을 해야 하는지 알아볼게요.
제 글이 많은 도움이 되었길 바라며,
긴 글 봐주셔서 감사합니다!
멋진 개발자가 되기 위해 더 열심히 달리겠습니다!
- 달맹 -
'Development' 카테고리의 다른 글
| 비동기 프로그래밍 2편 - 간단한 예제 (0) | 2024.03.05 |
|---|---|
| 비동기 프로그래밍 1편 - 개념 (0) | 2024.03.05 |
| JWT 기반 인증 8편 [끝] - 리팩토링 (0) | 2023.09.09 |
| JWT 기반 인증 7편 - Refresh Token 도입 (2) (0) | 2023.09.08 |
| JWT 기반 인증 6편 - Refresh Token 도입 (1) (0) | 2023.09.08 |