[Design Principle] Open-Closed Principle

ErroredPasta·2022년 5월 17일
0

Design Principles

목록 보기
2/5

정의

A software artifact should be open for extension but closed for modification.

소프트웨어의 artifact(class, module, function, etc.)는 확장에 대해 open되어 있어야 하지만 수정에 대해서는 closed되어 있어야 하는 것이 open-closed principle(이하 OCP)의 정의 입니다.

Open과 Closed

정의에서 나온 open과 closed의 의미는 각각 아래와 같습니다.

  • Open for extension
    요구 사항의 변경을 만족시키기 위해 module의 동작을 확장할 수 있어야 합니다. 즉, module의 동작을 알맞게 변경할 수 있어야 합니다.

  • Closed for modification
    Module의 동작을 확장하는 것은 소스 코드 혹은 바이너리 코드를 변경시키지 않습니다.

Open과 closed의 의미가 모순적으로 보입니다. 동작을 수정하기 위해서 소스 코드를 수정하면 closed for modification을 어기게 되고, 소스 코드를 수정하지 못하게 되면 open for extension을 할 수 없게 되어 보입니다.
그렇다면 어떻게 소스 코드 혹은 바이너리 코드를 건드리지 않고 module의 동작을 확장할 수 있을까요?

Abstraction

Abstraction을 이용하여 open for extension과 closed for modification을 지키면서 OCP를 만족할 수 있습니다.

Abstraction을 이용하여 base 클래스를 생성하고 해당 base 클래스를 상속받은 자식 클래스에서 상세 동작들을 구현해줄 수 있습니다. 그래서 기존에 존재하는 구현체 클래스의 소스 코드를 수정하지 않고 새로운 구현체 클래스를 생성하여 손쉽게 module의 동작을 확장시킬수 있게 됩니다.

Strategy Pattern

위와 같이 Client와 Server의 관계가 있다고 가정하겠습니다. 이럴경우 Client가 concrete한 Server 클래스에 dependency를 가지므로 Server가 변경될 때, Client도 변경될 확률이 높습니다.

이를 OCP를 이용하여 해결할 수 있습니다. Client Interface를 생성하여 Server가 해당 interface를 구현하도록 하고 Server의 동작을 변경해야 할 경우 Client Interface를 구현하는 다른 구현체 클래스를 생성하여 변경할 수 있습니다. 이와 같은 design pattern을 strategy pattern이라 합니다.

Template Pattern

만약 base 클래스가 위와 같이 interface가 아니라 동작의 기본적인 흐름을 가지고 있는 클래스인 경우에도 OCP를 이용하여 상세 동작은 해당 클래스를 상속받는 구현체 클래스에서 구현하도록 하는 template pattern을 사용할 수도 있습니다.

OCP는 object-oriented의 polymorphism, design pattern 중 strategy pattern, template pattern과 연관이 있는 것을 알 수 있습니다.

적용 범위

OCP는 안전하게 구현체를 변경할 수 있도록 해주므로 많은 곳에 적용하는 것이 좋다고 생각할 수도 있습니다. 하지만 이는 바람직하지 않은 생각입니다.

  • 적절한 abstraction을 생성하기에 비용이 든다.
    OCP를 적용하기 위해서는 적절한 abstraction을 생성하여야 합니다. Abstraction은 생성 및 수정 시 구현체의 생성 및 수정도 이루어져야 하므로 잘못된 abstraction을 생성하여 잦은 수정이 발생할 경우 더 많은 비용이 들게 됩니다. 그러므로 적절한 abstraction을 생성하여야 하는데 이 또한 비용이 드는 작업입니다.

  • Abstraction은 코드의 복잡성을 증가시킨다.
    Abstraction는 구현체를 캡슐화하므로 구현체가 어떻게 되어있는지 알 수 없는 경우가 존재하여 복잡성을 증가시키게 됩니다. 그러므로 OCP를 필요하지 않은 곳까지 적용하게 되면 코드의 복잡성이 감당하지 못하게 높이질 수 있습니다.

Uncle Bob은 이런 쓸모없는 복잡성을 줄이기 위해 우선 OCP를 적용하지 않고 추후 변화가 발생 시 적절한 abstraction을 생성하여 같은 변화에 대해 유연하게 처리할 수 있도록 하여야 한다고 했습니다.

Reference

[1] Robert Martin, Agile software development: principles, patterns, and practices (n.p.: Pearson, 2013), 99-110.

[2] Robert Martin, Clean Architecture: A Craftsman’s Guide to Software Structure and Design (n.p.: Prentice Hall, 2017), 69-75.

profile
Hola, Mundo

0개의 댓글