ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • SOLID - Open-Closed 개방폐쇄원칙 파헤치기
    Java/디자인패턴 2024. 10. 22. 14:41
    반응형

    Open-Closed 개방폐쇄원칙

    **Open-Closed Principle (OCP)**는 SOLID 원칙 중 하나로, 소프트웨어 개체(클래스, 모듈, 함수 등)는 확장에는 열려 있어야 하고, 수정에는 닫혀 있어야 한다는 개념입니다. 즉, 새로운 기능이나 요구사항이 생기더라도 기존 코드를 수정하지 않고 확장하는 방식으로 처리해야 한다는 뜻입니다.

     

     

    적절하지 못한 코드

    public class ReportGenerator {
        public void generateReport(String type) {
            if (type.equals("PDF")) {
                System.out.println("Generating PDF report...");
            } else if (type.equals("HTML")) {
                System.out.println("Generating HTML report...");
            }
            // If we need to add another format, we have to modify this method.
        }
    }

     

     

    위 코드에서 OCP 위반 요소

    위의 ReportGenerator 클래스는 새로운 리포트 형식(예: XML, CSV 등)을 추가할 때마다 generateReport 메서드에 새로운 if-else 블록을 추가해야 합니다. 이렇게 하면 기존 메서드를 계속 수정하게 되어 OCP에 위배됩니다. 또한, 조건문이 많아질수록 코드가 복잡해지고 유지 보수가 어려워집니다.

    Open-Closed Principle에 대한 설명

    OCP의 목적은 기존 코드를 변경하지 않고, 기능을 쉽게 확장할 수 있도록 하는 것입니다. 이 원칙을 따르면:

    • 새로운 기능을 추가할 때 기존 코드에 영향을 주지 않아야 하고,
    • 기존 기능에 결함이 생길 위험도 줄어듭니다.

    OCP를 지키기 위해서는 기존 코드를 변경하는 대신, 새로운 기능을 쉽게 추가할 수 있도록 추상화다형성을 이용해야 합니다.

     


    개선된 코드

    // 리포트 생성 전략을 정의하는 인터페이스
    interface Report {
        void generate();
    }
    
    // PDF 리포트를 생성하는 클래스
    class PDFReport implements Report {
        public void generate() {
            System.out.println("Generating PDF report...");
        }
    }
    
    // HTML 리포트를 생성하는 클래스
    class HTMLReport implements Report {
        public void generate() {
            System.out.println("Generating HTML report...");
        }
    }
    
    // ReportGenerator 클래스는 확장 가능하도록 수정됨
    class ReportGenerator {
        private Report report;
    
        public ReportGenerator(Report report) {
            this.report = report;
        }
    
        public void generateReport() {
            report.generate();
        }
    }

    새로운 리포트 형식을 추가할 경우

    만약 새로운 리포트 형식, 예를 들어 XML 리포트를 추가하고 싶다면, 기존의 ReportGenerator 클래스를 전혀 수정할 필요가 없습니다. 단지 Report 인터페이스를 구현하는 새로운 클래스를 만들면 됩니다.

    // XML 리포트를 생성하는 클래스
    class XMLReport implements Report {
        public void generate() {
            System.out.println("Generating XML report...");
        }
    }

     

    사용 예시:

    public class Main {
        public static void main(String[] args) {
            Report pdfReport = new PDFReport();
            ReportGenerator pdfGenerator = new ReportGenerator(pdfReport);
            pdfGenerator.generateReport();
    
            Report htmlReport = new HTMLReport();
            ReportGenerator htmlGenerator = new ReportGenerator(htmlReport);
            htmlGenerator.generateReport();
    
            // 새로운 형식 추가
            Report xmlReport = new XMLReport();
            ReportGenerator xmlGenerator = new ReportGenerator(xmlReport);
            xmlGenerator.generateReport();
        }
    }

    개선된 코드 설명

    • Report 인터페이스: 리포트 생성 전략을 정의하는 추상적인 타입입니다. 모든 리포트 형식은 이 인터페이스를 구현해야 합니다.
    • PDFReport, HTMLReport, XMLReport: 각 리포트 형식을 담당하는 클래스들입니다. 각각 Report 인터페이스를 구현하며, 새로운 리포트 형식을 추가할 때 이 클래스들만 새로 정의하면 됩니다.
    • ReportGenerator: 리포트를 생성하는 역할을 수행하며, Report 인터페이스를 통해 구체적인 리포트 형식에 의존하지 않고 확장 가능하도록 설계되었습니다.

    이렇게 개선된 코드는 새로운 리포트 형식을 추가할 때 기존 코드를 수정하지 않고, 새로운 클래스를 만들어 확장할 수 있으므로 OCP 원칙을 준수합니다.

    반응형

    댓글

Designed by Tistory.