티스토리 뷰

 

현대 소프트웨어 아키텍처에서 **객체지향 프로그래밍(Object-Oriented Programming, OOP)**은 단순히 코드를 작성하는 방법론을 넘어, 복잡한 비즈니스 로직을 관리 가능한 형태로 구조화하는 필수적인 철학입니다. 절차지향 프로그래밍이 "무엇을 어떤 순서로 실행할 것인가"에 집중했다면, OOP는 "누구(객체)가 어떤 책임(역할)을 가질 것인가"에 초점을 맞춥니다. 이는 대규모 시스템에서 유지보수성과 확장성을 확보하기 위한 필연적인 선택이었습니다.


1. 캡슐화 (Encapsulation): 데이터의 안전한 울타리

캡슐화는 데이터(상태)와 그 데이터를 조작하는 메서드(행위)를 하나의 단위로 묶고, 내부 구현의 상세 내용을 외부로부터 숨기는 것을 의미합니다.

💡 비유로 이해하기: 캡슐 알약

우리는 감기약 캡슐 안에 어떤 성분의 가루가 어떤 비율로 섞여 있는지 알 필요가 없습니다. 그저 '복용한다'는 행위만 수행하면 되죠. 만약 캡슐이 없고 가루가 노출되어 있다면, 외부 오염에 취약해지고 사용자가 성분을 임의로 조절하다 사고가 날 수도 있습니다.

💻 실전 예제: 이커머스 장바구니 시스템

사용자의 장바구니 금액은 외부에서 직접 수정되어서는 안 됩니다. 반드시 검증된 메서드를 통해서만 변경되어야 합니다.

JavaScript
 
class ShoppingCart {
    #items = []; // Private field: 외부 접근 차단

    /**
     * 상품 추가 시 유효성 검사 및 총액 계산 로직을 내부에서 관리
     * @param {Object} item - { name: string, price: number }
     */
    addItem(item) {
        if (item.price < 0) {
            throw new Error("상품 가격은 음수일 수 없습니다.");
        }
        this.#items.push(item);
        console.log(`${item.name}이(가) 장바구니에 담겼습니다.`);
    }

    getTotalPrice() {
        // 내부 로직을 통해 합계를 계산하여 반환 (읽기 전용 인터페이스)
        return this.#items.reduce((acc, current) => acc + current.price, 0);
    }
}

const myCart = new ShoppingCart();
myCart.addItem({ name: "M3 MacBook Pro", price: 3500000 });
// myCart.#items = []; // Error: Private field 접근 불가 (무결성 보장)

2. 상속 (Inheritance): 코드의 재사용과 계층화

상속은 이미 정의된 클래스의 특성을 다른 클래스가 물려받아 기능을 확장하거나 재정의하는 것입니다. 이를 통해 중복 코드를 제거하고 논리적인 계층 구조를 형성합니다.

💡 비유로 이해하기: 스마트폰의 진화

'스마트폰'이라는 기본 설계도에는 통화, 문자 기능이 정의되어 있습니다. 아이폰이나 갤럭시 같은 구체적인 모델들은 이 설계를 물려받으면서 각자만의 카메라 필터나 생체 인식 기능을 추가로 구현하는 것과 같습니다.

💻 실전 예제: 알림 서비스 엔진

TypeScript
 
// 공통 기능을 가진 부모 클래스
class NotificationService {
    protected sender: string;

    constructor(sender: string) {
        this.sender = sender;
    }

    send(message: string): void {
        console.log(`[${this.sender}] 메시지 전송 시작...`);
    }
}

// 부모의 기능을 물려받아 확장한 자식 클래스
class EmailNotification extends NotificationService {
    private emailAddress: string;

    constructor(sender: string, email: string) {
        super(sender); // 부모 생성자 호출
        this.emailAddress = email;
    }

    // 오버라이딩(Overriding): 전송 로직 구체화
    send(message: string): void {
        super.send(message); 
        console.log(`Email: ${this.emailAddress}로 "${message}"를 발송했습니다.`);
    }
}

3. 추상화 (Abstraction): 복잡함 속에서 본질 찾기

추상화는 불필요한 세부 사항은 제거하고 핵심적인 특징만을 골라내는 과정입니다. 사용자에게는 "무엇을(What)" 할 수 있는지만 보여주고, "어떻게(How)" 처리되는지는 감추는 인터페이스 설계의 핵심입니다.

💡 비유로 이해하기: 자동차 운전대

운전자는 핸들을 돌리면 바퀴가 회전한다는 사실만 알면 됩니다. 조향 기어의 비(Ratio)가 어떻게 계산되는지 $S = R \cdot \theta$ 같은 공식을 몰라도 운전에는 지장이 없습니다. 제어 장치(Interface)만 노출하고 구동 방식(Implementation)은 추상화한 결과입니다.


4. 다형성 (Polymorphism): 하나의 인터페이스, 다양한 행동

다형성은 동일한 요청에 대해 각 객체가 서로 다른 방식으로 응답할 수 있는 능력을 말합니다. 이는 코드의 결합도를 낮추고 유연성을 극대화하는 OOP의 꽃이라 불립니다.

💻 실전 예제: 결제 시스템 가이드

다양한 결제 수단이 존재하지만, 주문 처리 로직은 "결제한다(pay)"라는 추상적인 명령만 내립니다.

JavaScript
 
class PaymentProcessor {
    pay(amount) {
        throw new Error("결제 로직이 구현되지 않았습니다.");
    }
}

class CreditCardPayment extends PaymentProcessor {
    pay(amount) {
        console.log(`신용카드로 ${amount}원을 결제합니다. (카드사 승인 중...)`);
    }
}

class CryptoPayment extends PaymentProcessor {
    pay(amount) {
        console.log(`${amount}원 상당의 비트코인을 전송합니다. (블록체인 컨펌 중...)`);
    }
}

// 다형성 활용: 결제 수단이 무엇이든 동일한 방식으로 호출 가능
function processOrder(paymentMethod, price) {
    paymentMethod.pay(price); 
}

processOrder(new CryptoPayment(), 50000);

⚠️ 트레이드오프 (Trade-offs)

OOP는 강력하지만 만능은 아닙니다. 다음 사항을 고려해야 합니다:

  • 설계 복잡도: 초기 설계 단계에서 클래스 간의 관계를 설정하는 데 많은 시간이 소요됩니다. 과도한 상속은 오히려 코드의 흐름을 파악하기 어렵게 만드는 '상속 지옥'을 유발할 수 있습니다.
  • 성능: 추상화와 다형성 구현을 위한 동적 바인딩(Dynamic Binding)은 직접적인 절차적 호출보다 미세하게 오버헤드가 발생할 수 있습니다. (물론 현대의 컴파일러 최적화로 인해 무시할만한 수준인 경우가 많습니다.)

결론: 기술적 성장을 위한 제언

객체지향의 4대 요소인 캡슐화, 상속, 추상화, 다형성은 유기적으로 연결되어 있습니다. 캡슐화로 데이터를 보호하고, 추상화로 본질을 정의하며, 상속으로 기반을 다지고, 다형성으로 유연함을 더합니다.

좋은 개발자는 단순히 문법을 아는 사람이 아니라, "이 객체가 지금 너무 많은 책임을 지고 있지는 않은가?" 혹은 **"나중에 새로운 요구사항이 들어왔을 때 기존 코드를 수정하지 않고 확장할 수 있는가?"**를 끊임없이 질문하는 사람입니다.

여러분이 최근 진행한 프로젝트에서 가장 설계하기 까다로웠던 객체 간의 관계는 무엇이었나요? 이 4가지 원칙 중 어떤 것이 그 문제를 해결하는 실마리가 되었는지 복기해 보시길 권장합니다.

반응형
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2026/04   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30
글 보관함