1. 개요

 이 사용방법(예제)에서는 객체 지향 프로그래밍의 SOLID 원칙 중 하나인 OCP(Open/Closed Principle)에 대해 설명합니다 .

전반적으로 이 원칙이 무엇이며 소프트웨어를 설계할 때 이를 구현하는 방법에 대해 자세히 설명합니다.

2. 개방/폐쇄 원리

이름에서 알 수 있듯이 이 원칙은 소프트웨어 엔터티가 확장에는 열려 있어야 하지만 수정에는 닫혀 있어야 한다고 명시합니다. 결과적으로 비즈니스 요구 사항이 변경되면 엔터티를 확장할 수 있지만 수정할 수는 없습니다.

아래 그림에서는 인터페이스가 OCP를 따르는 한 가지 방법에 초점을 맞출 것입니다.

2.1. 미준수

덧셈과 뺄셈과 같은 여러 연산이 있는 계산기 앱을 구축한다고 가정해 보겠습니다.

먼저 최상위 인터페이스인 CalculatorOperation을 정의합니다 .

public interface CalculatorOperation {}

두 개의 숫자를 추가하고 C alculatorOperation을 구현하는 Addition 클래스를 정의해 보겠습니다 .

public class Addition implements CalculatorOperation {
    private double left;
    private double right;
    private double result = 0.0;

    public Addition(double left, double right) {
        this.left = left;
        this.right = right;
    }

    // getters and setters

}

지금은 Addition 클래스가 하나뿐이므로 Subtraction 이라는 다른 클래스를 정의해야 합니다 .

public class Subtraction implements CalculatorOperation {
    private double left;
    private double right;
    private double result = 0.0;

    public Subtraction(double left, double right) {
        this.left = left;
        this.right = right;
    }

    // getters and setters
}

이제 계산기 작업을 수행할 기본 클래스를 정의해 보겠습니다. 

public class Calculator {

    public void calculate(CalculatorOperation operation) {
        if (operation == null) {
            throw new InvalidParameterException("Can not perform operation");
        }

        if (operation instanceof Addition) {
            Addition addition = (Addition) operation;
            addition.setResult(addition.getLeft() + addition.getRight());
        } else if (operation instanceof Subtraction) {
            Subtraction subtraction = (Subtraction) operation;
            subtraction.setResult(subtraction.getLeft() - subtraction.getRight());
        }
    }
}

괜찮아 보일지 모르지만 OCP의 좋은 예는 아닙니다. 곱하기 또는 나누기 기능을 추가해야 하는 새로운 요구 사항이 발생하면 Calculator 클래스 의 계산 메서드 를 변경하는 것 외에는 방법이 없습니다 .

따라서 이 코드는 OCP를 준수하지 않는다고 말할 수 있습니다.

2.2. OCP 준수

우리가 본 계산기 앱은 아직 OCP와 호환되지 않습니다. 계산 메서드 의 코드는 들어오는 모든 새 작업 지원 요청에 따라 변경됩니다. 따라서 이 코드를 추출하여 추상화 계층에 넣어야 합니다.

한 가지 해결책은 각 작업을 해당 클래스에 Delegation하는 것입니다.

public interface CalculatorOperation {
    void perform();
}

결과적으로 Addition 클래스는 두 개의 숫자를 더하는 논리를 구현할 수 있습니다.

public class Addition implements CalculatorOperation {
    private double left;
    private double right;
    private double result;

    // constructor, getters and setters

    @Override
    public void perform() {
        result = left + right;
    }
}

마찬가지로 업데이트된 Subtraction 클래스도 유사한 논리를 갖습니다. 그리고 Addition and Subtraction 과 유사하게 새로운 변경 요청으로 나누기 로직을 ​​구현할 수 있습니다.

public class Division implements CalculatorOperation {
    private double left;
    private double right;
    private double result;

    // constructor, getters and setters
    @Override
    public void perform() {
        if (right != 0) {
            result = left / right;
        }
    }
}

마지막으로 Calculator 클래스는 새로운 연산자를 도입할 때 새로운 논리를 구현할 필요가 없습니다.

public class Calculator {

    public void calculate(CalculatorOperation operation) {
        if (operation == null) {
            throw new InvalidParameterException("Cannot perform operation");
        }
        operation.perform();
    }
}

그런 식으로 클래스는 수정을 위해 닫혀 있지만 확장을 위해 열려 있습니다 .

3. 결론

이 사용방법(예제)에서는 정의에 따라 OCP가 무엇인지 배운 다음 해당 정의에 대해 자세히 설명했습니다. 그런 다음 디자인에 결함이 있는 간단한 계산기 응용 프로그램의 예를 보았습니다. 마지막으로 OCP를 준수하게 하여 디자인을 좋게 만들었습니다.

항상 그렇듯이 코드는  GitHub에서 사용할 수 있습니다 .

Generic footer banner