Study Programming/Design Pattern

[SOLID] OCP (=Open-Closed Principle, 개방 폐쇄 원칙)

네모메모 2022. 6. 28. 22:36
반응형

 

SOLID 원칙 중 두번째인

1.  OCP (=Open-Closed Principle, 개방 폐쇄 원칙)

            "확장에는 열려 있어야 하고, 변경에는 닫혀 있어야 한다."

 

-  다른 말로 "기능변경하거나 확장할 수 있으면서 그 기능을 사용하는 코드는 수정하지 않는다."를 의미

 



- 적용방법 (2가지)
  => 변화하는 부분을 추상화함으로써 기존 코드를 수정하지 않고도, 확장을 할 수 있게 만들어 줍니다. 
   #1) 변화하는 부분을 추상화하는 것 -> 주로, 인터페이스를 통해서 구현을 합니다.
   #2) 상속을 이용하는 것

더보기

- ex) 상속을 사용
ⓐ HTTP 응답 프로토콜에 맞춰 데이터를 전송해 주는 ResponseSender 클래스가 존재한다.
ⓑ 이때, 기존 기능에 압축 기능을 추가 필요한 상황 발생
ⓒ ResponseSender를 상속받은 ZippedResponseSender 클래스를 생성하여 Override를 통해 기존 기능에 압축 기능을 추가하면 
(ResponseSender 클래스는 변경 없으므로 확장에는 열려 있으면서 변경에는 닫혀있으므로) OCP를 준수하게 된다.

 


 

- 개방 폐쇄 원칙을 지키지 않았을 때의 문제사례 2가지
  ㄴ> 1) 다운 캐스팅을 하는 경우, 클래스에서 변경이 일어날 때마다 해당 메소드를 수정이 필요해진다.

>>  instanceof와 같은 타입 확인 연산자가 사용된다면 해당 코드는 개방 폐쇄 원칙을 위반할 가능성이 높으므로 타입 캐스팅 후 실행되는 메소드가 변화 대상인지 확인해야 합니다. 
Ex) drawSpecific(Character character) 메소드에서  Character를 상속받은 Player, Enemy, Missile 클래스 중 Missile만 'if(character instanceof Missile)'로 체크하여 다르게 동작하도록 개발한 경우

=> Character클래스에서 변경이 일어날 때마다 해당 메소드를 수정이 필요해진다.
=> 차라리 drawSpecific() 메소드가 다른 객체들에서도 적용할 만한 메소드라면, Character 타입에 추가하라는 것입니다.

  ㄴ> 2) 비슷한 if~else 블록이 계속 필요해진다.

Ex)  Enemy 클래스에서 정해진 패턴에 따라 경로를 이동하는 코드가 필요하다면
public void draw() {
    if(pathPattern == 1) {
      x += 4;

    } else if(pathPattern == 2) {
      y += 10;

    } else if(pathPattern == 4) {
      x += 4;
      y += 10;

    }

    ...;  // 그려 주는 코드

  }
=> Enemy 클래스에 새로운 경로 패턴을 추가할 때마다 draw() 메소드에는 새로운 if문이 생깁니다. 
즉, 경로를 추가하는데 Enemy 클래스는 변경에 닫혀있지 않은 것입니다.
=> 따라서, (x, y)와 같은 경로 패턴을 추상화 해야합니다.

 



 

 

- OCP원리를 적용하면 좋은 점

더보기

- 하나의 변화가 다른 곳에도 연쇄적으로 변화를 일으키는 것을 방지

- 유연성

 


[출처]

- 위키 : https://ko.wikipedia.org/wiki/%EA%B0%9C%EB%B0%A9-%ED%8F%90%EC%87%84_%EC%9B%90%EC%B9%99

- SRP

-> https://steady-coding.tistory.com/370

- https://www.nextree.co.kr/p6960/

 

- 개발자가 반드시 정복해야 할 객체 지향과 디자인 패턴 - 최범균

 

 

 

 

반응형