객체 지향 프로그래밍(OOP)
개념 : 현실 세계의 개념을 코드 구조로 옮겨, 복잡한 시스템을 관리하기 쉽게 만드는 것
1. 캡슐화
2. 상속
3. 다형성
4. 추상화
● 캡슐화
설명
: 데이터(변수)와 그 데이터를 다루는 로직(메서드)을 하나로 묶고 외부에서 직접 접근하지 못하게 보호하는 설계 방식
주로 쓰이는 기능
- 로그인 상태, 잔액, 토큰 값
웹 코드 예시 (적용 전)
const user = {
password: "1234"
};
function login(input) {
if (user.password === input) {
console.log("Login success");
}
}
적용 전 문제
- password가 외부에서 직접 접근 가능
- 어디서든 값 변경 가능 -> 보안, 추적 불가
웹 코드 예시 (적용 후)
class User {
#password;
constructor(password) {
this.#password = password;
}
checkPassword(input) {
return this.#password === input;
}
}
const user = new User("1234");
if (user.checkPassword("1234")) {
console.log("Login success");
}
적용 후
- 상태(#password)가 완전히 보호
- 검증 규칙이 한곳에 고정
- 내부 구현 변경이 외부에 영향 X
● 상속
설명
: 여러 객체가 공통으로 가지는 속성과 동작을 부모 클래스에 정의하고 이를 하위 클래스가 물려받아 확장함으로써 중복을 줄이고 계층적인 구조를 표현하는 설계 방식
주로 쓰이는 기능
- 사용자 권한 분리
웹 코드 예시 (적용 전)
function normalUserLogin() {
console.log("User logged in");
}
function adminUserLogin() {
console.log("User logged in");
console.log("Admin dashboard access");
}
적용 전 문제
- 공통 로직 중복
- 수정 시 모든 함수 동시 수정 필요
- 사용자 타입 증가 시 폭발
웹 코드 예시 (적용 후)
class User {
login() {
console.log("User logged in");
}
}
class Admin extends User {
login() {
super.login();
console.log("Admin dashboard access");
}
}
적용 후
- 공통 오직을 부모로 집중
- 역할 차이만 자식에서 확장
- 구조적으로 사용자 타입 표현 가능
● 다형성
설명
: 동일한 인터페이스나 메서드 호출을 유지하면서도 객체의 실제 타입에 따라 서로 다른 동작을 수행하게 만들어 조건문 없이도 유연한 확장과 변경이 가능하게 하는 설계 방식
주로 쓰이는 기능
- 알림, 결제, 인증 방식 분기
웹 코드 예시 (적용 전)
function sendNotification(type) {
if (type === "email") {
console.log("Send email");
} else if (type === "sms") {
console.log("Send SMS");
}
}
적용 전 문제
- 타입이 늘어날수록 if 증가
- 기존 코드 수정이 필요
- 실수로 분기 누락 가능
웹 코드 예시 (적용 후)
class Notification {
send() {}
}
class EmailNotification extends Notification {
send() {
console.log("Send email");
}
}
class SmsNotification extends Notification {
send() {
console.log("Send SMS");
}
}
function notify(notification) {
notification.send();
}
notify(new EmailNotification());
notify(new SmsNotification());
적용 후
- 분기 제거
- 확장 시 기존 코드 수정 X
- 호출부는 타입을 몰라도 됨
● 추상화
설명
: 구현 방법은 감추고 반드시 지켜야 할 동작 규칙과 역할만 정의함으로써 시스템 전체를 일관된 계약(contract) 기반으로 설계하고 구현체 교체와 확장을 안전하게 만드는 설계 방식
주로 쓰이는 기능
- 결제, 저장소, 네크워크 계층 설계
웹 코드 예시 (적용 전)
function saveData(type, data) {
if (type === "local") {
console.log("Save to local storage");
} else if (type === "server") {
console.log("Save to server");
}
}
적용 전 문제
- 저장 방식 변경 시 전체 수정
- 규칙이 함수 내부에 숨겨짐
- 테스트, 교체 어려움
웹 코드 예시 (적용 후)
class Storage {
save(data) {
throw new Error("save() must be implemented");
}
}
class LocalStorage extends Storage {
save(data) {
console.log("Save to local storage");
}
}
class ServerStorage extends Storage {
save(data) {
console.log("Save to server");
}
}
function save(storage, data) {
storage.save(data);
}
적용 후
- 저장 규칙이 명확히 고정
- 구현체 자유 교체
- 테스트용 가짜 구현 가능
개념적용 전 느낌적용 후 느낌
| 개념 | 적용 전 | 적용 후 |
| 캡슐화 | 어디서 값이 바뀌는지 모름 | 상태 변경 지점이 명확 |
| 상속 | 복붙 지옥 | 구조로 의미 표현 |
| 다형성 | if 지옥 | 확장 중심 설계 |
| 추상화 | 함수가 모든 걸 앎 | 역할이 분리됨 |
'국비' 카테고리의 다른 글
| ESM (ES Modules) vs CJS (CommonJS) (0) | 2026.01.26 |
|---|---|
| IntersectionObserver로 스크롤 기반 렌더링 최적화하기 (0) | 2026.01.19 |
| Generator로 렌더링 작업을 나눠서 빠르게 보이게 만들기 (0) | 2026.01.19 |