Self-Dev/Design Patterns R&D

[9] 소프트웨어 디자인 원칙들 - SOLID 원칙들 - (O)

Khadra 2024. 6. 1. 23:03

출처 : 디자인 패턴에 뛰어들기 - 알렉산더 슈베츠 도서


O (Open/Closed Principle, 개방/폐쇄 원칙)

클래스는 확장에는 열려있어야 하지만 변경에는 닫혀 있어야 한다.

목적

새로운 기능을 구현할 때 기존 코드가 깨지지 않도록 해야한다.

설명

  • 확장에 개방(Open): 자식 클래스를 생성하거나, 기초 행동을 오버라이드하고 새로운 메서드나 필드를 추가할 수 있어야 한다.
  • 변경에 폐쇄(Closed): 클래스의 인터페이스가 명확하게 정의되어 있고, 미래에 변경되지 않아야 한다.

클래스는 확장을 위해 개방됨과 동시에 변경에 대해 폐쇄될 수 있다.
이미 개발, 테스트, 검토를 마친 클래스의 코드를 직접 변경하는 대신, 자식 클래스를 생성해 원래 클래스의 일부 동작을 오버라이드하면 기존 코드의 안정성을 유지하면서 새로운 기능을 추가할 수 있다.

이 원칙은 모든 변경 사항에 적용되지는 않다.
버그가 있는 경우에는 자식 클래스를 생성하지 않고 원래 클래스에서 직접 수정해야 한다.

예시

전자 상거래 앱의 Order(주문) 클래스가 모든 배송 메서드를 하드코딩하고 있으며, 새로운 배송 메서드를 추가할 때마다 Order 클래스를 변경해야 하는 문제가 있다. 이는 코드가 깨질 위험이 있다.

수정 전: 앱에 새 배송 메서드를 추가할 때마다 Order 클래스를 변경해야 한다.



전략 패턴을 적용하여 문제를 해결할 수 있다.

  • 배송 메서드들을 공통 인터페이스를 가진 별도의 클래스들로 추출한다.
  • 새로운 배송 메서드를 구현할 때 Order 클래스의 코드를 변경할 필요 없이 Shipping(배송) 인터페이스에서 새 클래스를 파생한다.
  • Order 클래스의 클라이언트 코드는 사용자가 UI에서 배송 메서드를 선택할 때마다 주문을 새 클래스의 배송 객체와 연결한다.

수정 후:기존 클래스들을 변경하지 않고 새 배송 메서드를 추가할 수 있다.



새로운 배송 메서드를 추가하려면 Shipping 인터페이스를 구현하는 새로운 클래스를 작성하면 된다.

  • Order 클래스의 코드를 건드리지 않고 Shipping(배송) 인터페이스에서 새 클래스를 파생할 수 있다.
  • Order 클래스의 클라이언트 코드는 사용자가 사용자 인터페이스에서 이 배송 메서드들을 선택할 때마다 주문을 새 클래스의 배송 객체와 연결할 것이다.

추가 이점

단일 책임 원칙에 따라 배달 시간 계산 기능을 보다 관련성 높은 클래스들로 이동할 수 있게 해준다.

결론

소프트웨어 엔티티(클래스, 모듈, 함수 등)는 확장에 대해 열려 있어야 하고, 수정에 대해서는 닫혀 있어야 한다는 것을 의미한다.
즉, 기존의 코드를 변경하지 않고도 새로운 기능을 추가할 수 있어야 한다.
이를 위해 추상화와 다형성을 활용하여 코드를 설계하고, 변경되는 부분과 변경되지 않는 부분을 명확히 분리해야 한다.
이렇게 하면 기존 코드에 영향을 주지 않고도 새로운 기능을 추가하거나 기존 기능을 수정할 수 있어 유연하고 확장 가능한 소프트웨어를 만들 수 있다.