티스토리 뷰
개방 폐쇄 원칙(OCP)
소프트웨어 개체(클래스, 모듈, 함수)는 확장에 대해 열려 있어야 하고, 수정에 대해서는 닫혀 있어야한다.
개방 폐쇄 원칙을 따르는 모듈은 다음과 같은 두 가지 속성을 갖는다.
1. 확장에 대해 열려 있다.
이것은 모듈의 행위가 확장될 수 있음을 의미한다. 요구사항이 변경될 때, 이 변경에 맞춰 새로운 행위를 추가해 모듈을 확장할 수 있다. 새로운 타입을 추가함으로써 새로운 기능을 추가하는 것과 같다.
2. 수정에 대해 닫혀 있다.
어떤 모듈을 확장하는 것은 소스코드나 바이너리 코드의 변경을 초래하지 않는다. 이는 확장이 일어날 때 상위 레벨이 영향을 받지 말아야 한다는 것이다.
HOW?
이는 모순된 것처럼 보인다. 어떻게 소스 코드를 변경하지 않고도 그 모듈의 행위를 바꾸는 일이 가능한걸까? 정답은 Abstraction을 통한 inversion에 있다.
Abstraction?
Abstraction is the process by which data and programs are defined with a representation similar in form to its meaning, while hiding away the implementation details.
추상화는 추상 기반 클래스이자, 모든 가능한 파생 클래스를 대표하는 가능한 행위의 묶음이기도 하다.상위 모듈을 고정된 추상화에 의존하면 상위 모듈은 수정에 대해 닫혀 있는 것이 가능하게 된다. 그리고 그 모듈의 행위는 추상화의 새 파생 클래스를 만듦으로써 확장에 대해서는 열려 있게 된다.
위 그림은 OCP를 위반한 예시이다. 만일 Client
객체가 새로운 Server
객체를 사용하도록 바꾸고 싶다면 Client
클래스를 수정하여 다른 Server
클래스를 사용하도록 바꿔야하므로 수정에 대해 닫혀있지 않게 된다. 즉 OCP를 위반하게 된다.
위에서 제시된 문제점을 스트레티지 패턴을 사용함으로써 해결했다. 확장이 필요한 부분에 Abstraction을 적용하여 상위모듈이 고정된 추상화에 의존하도록 했다. 만일 새로운 server
객체를 사용하고 싶다면 Client Interface
를 구현한 새로운 클래스를 추가하도록 하면 된다.
장점?
이렇게 수정하면 경직성의 문제가 사라진다. 경직성이란 단순한 방법으로도 소프트웨어를 변경하기 어려운 것을 의미한다. 한 군데의 변경이 다른 의존적인 모듈의 변경을 일으킬 때 경직성의 문제가 있다고 한다. Client
가 고정된 추상화에 의존하므로 하위 모듈의 변경이 상위 모듈에 영향을 미치지 않는다.
또한 부동성이 없다. 부동성이란 원하는 부분을 모듈로부터 분리해내어 다른 곳에서 사용할수 있는 것을 의미한다. 추상화를 구현한 서브 클래스는 재활용이 가능하므로 부동성 문제도 해결할 수 있다.
단점?
그렇다면 우리는 변경될 부분을 미리 예측하여 추상화를 해놓아야 하는걸까? 변경될 부분이 무엇인지 미리 안다면 우리는 해당 부분을 추상화 하면 되지만 실제로 서비스하기 전까지는 어느 부분에 변경이 필요한지 예측하기 어렵다. 또한 미리 추상화를 다 했다 하더라도 이는 불필요한 복잡성만 증가할 뿐이다.
Solution
Agile Design에서는 아래와 같은 해결책을 제시한다.
- 아주 짧은 주기로 개발한다.
- 소프트웨어를 빨리 그리고 자주 릴리즈한다.
지레 겁 먹고 모든 부분을 추상화하는 대신, 빠르게 개발하여 변화가 필요한 부분을 체감한 뒤 해당 부분을 추상화하도록 하면 필요한 부분에 대해 추상화를 할 수 있다.
'Design Patterns' 카테고리의 다른 글
[디자인패턴] 인터페이스 분리 원칙(ISP) (0) | 2021.10.27 |
---|---|
[디자인패턴] 의존 관계 역전 원칙(DIP) (0) | 2021.10.27 |
[디자인패턴] 리스코프 치환 원칙(LSP) (0) | 2021.10.27 |
- Total
- Today
- Yesterday
- sweeping
- string
- hld
- sorting
- 2-SAT
- bfs
- 이분매칭
- 이분탐색
- 세그먼트트리
- kmp
- Fenwick
- 트라이
- 스위핑
- implementation
- Suffix Array
- Oracle
- dfs
- dijkstra
- 정렬
- 펜윅트리
- spring
- spring boot
- Segment tree
- union find
- 동적계획법
- DP
- greedy
- SCC
- 좌표압축
- knapsack
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |