개방 폐쇄 원칙 (OCP: Open-Closed Principle)

단일 책임 원칙보다는 조금 애매하고 추상적인 원칙이다.

단일 책임 원칙은 '클래스가 한 동작만 하게 쪼개라!'라는 명확한 방향성이 있지만, 개방 폐쇄 원칙은 조금 다르기 때문이다.

 

일단, 어떤 원칙이냐에 대해 설명하자면, 이론적으로는 '확장에 대해서는 개방적이되, 수정에는 폐쇄적이여야 한다'이다.

이 원칙을 돌직구로 해석하면, 이렇다. '확장(상속)할 수 있는 구조를 잡아서, 기존 코드를 수정할 일이 없도록 만들어라.'이다.

그냥 알아서 나중까지 생각해서 구조와 코딩을 잘 해라이다.

 

참 꼰대 같은 원칙이 아닐 수 없다. 마치, 실력 없는 개발자가 아는 게 별로 없을 때, 애매하게 하는 말 같다.

정확한 행동 지침도 없다. 어떻게, 어느 정도로, 잘하냐는 온전히 개발자의 몫이기 때문이다.

 

C#을 기준으로 이 원칙에 대해 좀 더 포인트를 넣어 하나씩 설명하자면 이렇다.

  • 기존 코드는 되도록 수정이 되어선 안된다.
  • 코드를 수정하면 안 되므로 항상 코드는 확장을 있는 여지를 남길 수 있게 구현해야 한다.
  • 확장성을 위해, 다형성과 추상화를 이용한다. 이를 위해 클래스 상속과 인터페이스 상속 사용한다.
  • 클래스의 상속은 자식이 상위 부모들에게 의존적이게 만드는 단점이 있다. 부모가 수정되면, 자식도 수정될 가능성이 크다.
    때문에 되도록 상속 단계는 낮게 (1, 2 단계 정도만) 해야 한다.
  • 인터페이스 상속이 클래스 상속보다, 더 구조의 유연함을 가져다준다. 하지만, 인터페이스 정의 시, 모든 상속 클래스가 수정을 해야 하므로 수정이 되지 않도록 잘 선언해야 한다.
  • 어떻게 상속 구조를 짤지, 어떤 걸 추상 멤버(메소드, 속성)로 할지는 개발자의 몫이다.
    미래의 변화에 대해 예측을 잘해서 추상화를 해야 하며.
    너무 과하게 예상해서 추상시켜도 안되고, 아무것도 확장할 수 없게 다 폐쇄적으로 숨기면 안 된다. 적당히 알아서 잘해야 한다.
  • 확장할 수 있는 것과 없는 것을 명확하기 위해, 상속해서는 안 되는 클래스는 sealed 키워드를 사용하라.

볼드체 한 부분이 문제다. abtract class, interface, virtual, sealed 키워드 같은 것을 이용해 확장의 여지를 고려해야 하는데,

어떻게, 어느 정도로 해야 하는지는 기준이 없기 때문이다.

이 부분은 순전히 경험으로 극복하는 수밖에 없다. 많은 경험을 해서, 개방해야 될 것과 감춰야 할 것을 구별할 수 있어야 한다.

 

리팩토링에 있어서, 조심해야 할 적은 바로 과한 수정과 예측이 아닐까 싶다.

어떤 코드를 수정하기 전에, 해당 코드가 정말 리팩토링이 필요한지 고려를 잘해야 한다. 시간과 돈, 인력 자원은 한정적이다.

 

한정된 자원으로 적절하게 시간을 투자해야 하는데, 구조적으로 투박하고 문제가 많아 보이는 코드라도 작동에 문제가 없고,

미래에 수정의 여지가 없는 코드이면, 무리하게 시간을 써가면서까지 수정을 할 필요가 없다.

리팩토링이라는게 의존성을 없애기 위해 하는 작업이기에,

클래스와 코드가 많아지고 파일이 분산돼서 구조가 이전보다 복잡해질 수 있기 때문이다.

 

반대로, 너무 심하게 미래에 미래에 미래까지 예측해서, '이건 한 5년 뒤면 필요할 거야' 하면서 구현하거나

'이 구조는 이런 게 문제고 저 구조는 이런게 문제고...' 하면서 추상화 디자인에 너무 시간을 많이 소비하는 것 경우도 있는데.

이 또한 조심해야 한다. 코드 구조가 알아볼 수 없게 이전보다 복잡해지거나, 기획만 하다가 시간이 다 지날 수 있기 때문이다.

 

항상 개발할 때, 주어진 시간을 적절히 고려해서 어느 게 최선인지를 적절히 생각하며 적절히 작업하는 게 중요하다.

(근데, 솔직히 이런 거 잘할 줄 알면, 다 프로그래밍 초고수였을 거다.)

+ Recent posts