CS

OCP 원칙 (Open-Closed Principle)

baek-dev 2025. 2. 17. 18:45

**OCP(Open-Closed Principle, 개방-폐쇄 원칙)**은 SOLID 원칙 중 하나로,

**“확장에는 열려 있고, 변경에는 닫혀 있어야 한다.”**라는 개념을 의미함.

 

즉, 새로운 기능을 추가할 때 기존 코드를 수정하지 않고 확장할 수 있어야 함.

이 원칙을 잘 지키면 코드의 유지보수성과 확장성이 증가하고, 버그 발생 가능성이 줄어듦.

📌 1. OCP 원칙이란?

✅ OCP(Open-Closed Principle)의 정의

 

“소프트웨어 요소(클래스, 모듈, 함수 등)는 확장에는 열려 있어야 하지만, 변경에는 닫혀 있어야 한다.”

 

확장(Open) → 새로운 기능 추가 가능해야 함.

변경(Closed) → 기존 코드 수정 없이 기능을 추가해야 함.

 

✅ 왜 OCP가 중요할까?

기존 코드를 수정하면 새로운 버그가 발생할 가능성이 있음 🚨

여러 사람이 함께 개발하는 경우, 변경이 많아지면 충돌 가능성이 커짐

유지보수가 어렵고, 코드 수정이 많아질수록 테스트 비용 증가 🏗️

OCP를 지키면 유지보수와 확장이 쉬운 코드를 작성할 수 있음 ✅

 

📌 2. OCP를 지키지 않은 코드 (문제점)

아래 코드를 보면 기능을 추가할 때 기존 코드 수정이 필요하므로 OCP를 위반함.

class PaymentProcessor {
    public void processPayment(String paymentType) {
        if (paymentType.equals("creditCard")) {
            System.out.println("Processing credit card payment...");
        } else if (paymentType.equals("paypal")) {
            System.out.println("Processing PayPal payment...");
        } else {
            throw new IllegalArgumentException("Unsupported payment type");
        }
    }
}

 

❌ 문제점

새로운 결제 수단(bitcoin)을 추가하려면 processPayment() 메서드를 수정해야 함.

OCP 원칙을 위반하여 코드 수정이 계속 발생 → 버그 발생 가능성 증가 🚨

클래스가 닫혀 있지 않음 → 유지보수가 어려움 😭

📌 3. OCP를 지키는 코드 (해결 방법)

 

OCP를 준수하려면 “새로운 기능을 추가할 때 기존 코드를 수정하지 않도록” 설계해야 함.

이를 위해 **인터페이스(Interface)나 추상 클래스(Abstract Class)**를 활용하면 됨.

// 1. 결제 수단 인터페이스 정의
interface Payment {
    void pay();
}

// 2. 각 결제 수단을 별도 클래스로 분리
class CreditCardPayment implements Payment {
    public void pay() {
        System.out.println("Processing credit card payment...");
    }
}

class PayPalPayment implements Payment {
    public void pay() {
        System.out.println("Processing PayPal payment...");
    }
}

// 3. 확장 가능한 결제 처리 클래스
class PaymentProcessor {
    public void processPayment(Payment payment) {
        payment.pay();
    }
}

// 4. 새로운 결제 수단 추가 (OCP 원칙 준수)
class BitcoinPayment implements Payment {
    public void pay() {
        System.out.println("Processing Bitcoin payment...");
    }
}

// 5. 실행 코드
public class Main {
    public static void main(String[] args) {
        PaymentProcessor processor = new PaymentProcessor();

        processor.processPayment(new CreditCardPayment());  // 기존 코드 수정 없음
        processor.processPayment(new PayPalPayment());
        processor.processPayment(new BitcoinPayment());  // 새로운 결제 수단 추가 가능!
    }
}

 

✅ OCP 원칙을 적용한 코드의 특징

1. **새로운 기능(결제 방식 추가)**이 필요하면 새로운 클래스를 만들면 됨 (기존 코드 수정 X)

2. OCP 원칙을 준수하여 코드 확장 가능성이 높아짐

3. 코드 수정 없이 새로운 기능을 추가 가능유지보수성이 뛰어남

4. 인터페이스를 활용하여 유연한 설계 가능

 

📌 4. OCP 원칙을 적용하는 방법

✅ (1) 인터페이스와 추상 클래스 활용

기능 확장이 필요하면 새로운 클래스를 만들어 추가하는 방식

위의 Payment 예제처럼 인터페이스를 정의하고, 구현 클래스를 확장하면 됨.

 

✅ (2) 전략 패턴(Strategy Pattern) 적용

실행 중에 원하는 기능을 동적으로 변경할 수 있도록 설계하는 패턴

OCP 원칙을 준수하면서 유연하게 기능 추가 가능

class PaymentProcessor {
    private Payment payment;

    public PaymentProcessor(Payment payment) {
        this.payment = payment;
    }

    public void process() {
        payment.pay();
    }
}

public class Main {
    public static void main(String[] args) {
        PaymentProcessor processor = new PaymentProcessor(new CreditCardPayment());
        processor.process(); // 신용카드 결제

        processor = new PaymentProcessor(new BitcoinPayment());
        processor.process(); // 비트코인 결제
    }
}

 

✅ (3) 의존성 주입(DI, Dependency Injection)

Spring 프레임워크에서 OCP 원칙을 실천하는 대표적인 방법

인터페이스를 주입하여 변경 없이 새로운 기능 추가 가능

@Service
class PaymentService {
    private final Payment payment;

    @Autowired
    public PaymentService(Payment payment) {
        this.payment = payment;
    }

    public void processPayment() {
        payment.pay();
    }
}

 

새로운 결제 수단이 추가되더라도 기존 PaymentService 코드를 수정할 필요 없음

 

📌 5. OCP 원칙을 따르지 않으면 생기는 문제점

OCP를 준수하지 않으면? 발생 문제
기능 추가 시 기존 코드 수정이 필요함 기존 코드 수정 중 버그 발생 가능 🚨
클래스가 너무 커지고 복잡해짐 코드 유지보수 어려움 😭
새로운 기능 추가 시 테스트 필요 코드 수정 없이 기능 추가 가능해야 함

 

🚀 결론

OCP 원칙을 따르면 기존 코드를 수정하지 않고도 새로운 기능을 쉽게 추가 가능함.

인터페이스, 추상 클래스, 전략 패턴, DI(의존성 주입) 등을 활용하면 OCP를 쉽게 적용할 수 있음.

유지보수성과 확장성이 뛰어난 코드 작성 가능버그 발생 가능성 줄이고 개발 속도 증가 🚀

 

 

 

 

출처 : ChatGPT

'CS' 카테고리의 다른 글

SSE (Server-Sent Events)  (0) 2025.02.19
락(Lock)과 동시성  (0) 2025.02.18
다형성  (1) 2025.02.16
DFS, BFS  (0) 2025.02.14
git branch 별 차이 (dev, origin dev, origin/dev)  (0) 2025.02.11