비전(秘傳), 비급(秘笈) 이란 무엇일까?
고수들만의 '특별한' 기술을 두루마리, 책 등으로 적어 전하는 것을 의미하는데
낮은 레벨의 경우 알아보지도 못하기도 하고 알아보더라도 '깊은'의미를 이해하지 못하기도 한다.
'이해'하더라도 '활용'하지 못하는 경우가 많다. '몸'으로 채득해야 모든 것을 자기 것으로 만들지 모르겠다.
비전[秘傳]
객체지향 개발 5원칙(客體指向 發展 五原則: "SOLID" )
- 로버트 R 마틴(Robert Reinhold Martin: 羅伯特 R 馬丁), 마이클 페더스(Michael Feathers: 麥可 費瑟斯)
서문(序文)
우리가 프로그래밍을 하면서 이런 원칙들이 왜 필요한건지 생각해 볼 필요가 있다.
'원칙(原則: Principle)'이라고 썼지만 지키지 않아도 처벌받거나 하지 않는다.
원칙은 왜 탄생했을까?
프로그래머들이 겪는 공통적인 문제를 해결 내지는 최소화 하기 위해 이른바 프로그래밍을 잘하기 위해 태어났다.
'잘' 한다는 어떤것인가?
'오류'가 없고(또는 적고),
'변화'에 유연하며,
'재사용성'이 높아야 한다.
그리고 부가적으로 '알아보기 쉬워야' 한다.
이러한 특성은 개발자들이 반복작업을 줄이고 유지보수 작업을 진행하더라도 편리하게 할 수 있도록 도와준다.
그러기 위해 객체지향의 선배 고수들이 5가지로 원칙을 정해서 후대에 전달한 것이다.
이미 이전에 다른 프로그래밍 언어들에서도 유사한 비전들이 전해졌으며, 현재에도 여러 언어들의 비전들이 유사하게 전해지고 있다.
이런 비전들은 '계명(誡命: commandment)' 형태(ex: The Ten Commandments for C Programmers - C 프로그래머의 10 계명)
또는 '철학(哲學: philosophy)' 형태(ex: The Zen of Python-파이썬의 禪)로 전해지거나
이른바 '방법론(方法論: methodology)'으로 진화(ex: TDD: Test Driven Development - 테스트 주도 개발방법론)해서 전달 혹은 연구되고 있다.
1. 단일책임 원칙(單一責任 原則 - SRP: Single Responsibility Principle)
There should never be more then one reason for a class to change.
작성된 클래스는 하나의 기능만 가지며 클래스가 제공하는 모든 서비스는 그 하나의 책임(변화의 축: axis of change)을 수행하는데 집중되어 있어야 한다는 원칙.
객체지향의 특징 중에는 추상화(abstraction)와 캡슐화(encapsulation)가 있는데
이는 기능 구성의 레이어(layer) 혹은 단계(level)에 대해 단순화되어 있다는 이야기이다.
기능 자체가 1가지로만 단순화되어 있어야 한다는 이야기는 '단순'하기 때문에 '오류'가 발생할 여지가 줄고
'변화'에 유연하며, '재사용'을 많이 할 수 있고, 더욱더 '가독성'이 증가한다.
레고 블록을 보면 블럭 하나는 단순하게 만들어진 것을 알 수 있다.
"단순하게 단일기능만 수행하도록 개발하라"
2. 개방폐쇄 원칙(開放閉鎖 原則 - OCP: Open Close Principle)
You should be able to extend a class behavior, without modifying it.
소프트웨어 구성요소는 확장에는 열려있고, 변경에는 닫혀있어야 한다는 원칙.
비전 최고의 원칙이라고 생각한다. 나머지 원칙들은 이 원칙을 위해서 구현하는 방법이라고 본다.
하나의 기능을 구현하되 '변경(확장)' 될 부분과 '변경되지 않을' 부분을 구분하고,
실제 구현된 것보다는 정의된 인터페이스를 이용해서 구성하도록 코드를 작성하는 것이 이 원칙을 지키는 방법이다.
이 원칙을 위해서는 전달받은 파라미터가 기능 내부에서 '재정의' 되어서는 안 된다.
"확장에는 열려있고, 변경에는 닫혀있도록 개발하라"
3. 리스코프 치환 원칙(利斯科夫 置換 原則 - LSP: The Liskov Substitution Principle)
Functions that use pointers or references to base classes must be able to use objects of derived classes without knowing it.
바바라 리스코프(Barbara Liskov: 芭芭拉 利斯科夫 - 미국 여성 컴퓨터 과학 박사)가 개발한 원칙으로
"서브 타입은 언제나 기반 타입으로 교체할 수 있어야 한다."라는 원칙.
객체지향의 특징 중 하나인 '상속'에 대해서 '구현상속(extends)'든 '인터페이스상속(implements)'든 궁극적으로 다형성을 통한 확장성 획득을 목표로 하는 원칙.
개방폐쇄 원칙을 구현할 때도 이야기한 것처럼 구현된 것보다는 인터페이스를 이용하고 이용할 때는 최상위 것을 이용해서 호환성을 높이 도록 구현하는 방법이다.
리스코프 치환원칙을 지키면 개방폐쇄원칙을 지키면서 확장성을 가지게 된다.
"하위 유형은 언제든 상위 유형으로 교체할 수 있어야 한다."
또는 "상위유형 호환성을 유지하도록 개발하라"
4. 인터페이스 분리 원칙(介面 分離 原則 - ISP: Interface Segergation Principle)
Clients should not be forced to depend upon interfaces that they do not use.
한 클래스는 자신이 사용하지 않는 인터페이스는 구현하지 말아야 한다는 원칙.
가능한 최소 인터페이스만을 사용해야 하며 하나의 일반적인 인터페이스보다는 여러 개의 구체적인 인터페이스가 낫다는 원칙.
하나의 기능을 구현하는데 개방폐쇄원칙이나 리스코프 치환원칙을 유지하려 할 때 단지 부모 객체를 상속하는 것에 치중하지 말고
불필요한 기능을 가지면 안 된다는 단일 책임의 원칙을 준수해야 하기 위해 불필요한 기능은 제거해야 한다는 원칙.
상속을 이용하거나 위임(Delegation)을 이용해서 이 원칙을 지킬 수 있다.
이는 단일 책임의 원칙과도 연관된 이야기 이기도 하며, 리스코프 치환 원칙을 적용할 때 고려해야 하는 원칙이고 역시 개방폐쇄원칙을 위해서 인터페이스 분리 원칙이 적용되어야 하는 것이다.
"불필요한 기능은 구현하지 않도록 개발하라"
5. 의존성역전 원칙(依存性逆轉 原則 - DIP: Dependency Inversion Principle)
A. High level modules should not depend upon low level modules. Both should depend upon abstractions.
B. Abstractions should not depend upon details. Details should depend upon abstractions.
개방패쇄원칙을 지켜서 클래스를 만들었다면 이 클래스들 간의 구성 역시 개방패쇄원칙을 지키기 위해 구성해야 하는 방법을 정의한 원칙.
인터페이스 분리의 원칙과 더불어 기능 및 구성원칙으로 확장과 변화에 대응이 좋은 이른바 '느슨한' 연결을 위해서 지켜야 하는 원칙.
IOC(Inversion Of control), Callback 등을 활용해서 전략적으로 레이어 혹은 단계를 나눠 처리하는 방법.
"구성과 구성사이 제어가 넘어가도록 개발하라"
[참고: 주옥같은 글이다 반드시 읽어보자]
객체지향 개발 5대 원리:SOLID https://www.nextree.co.kr/p6960/