Contents |
Design Principles
Open Close
Dependency Inversion
Interface Segregation
Single Responsibility
모든 클래스는 하나의 책임만을 가진다.
상속에서 다중 상속으로 넘어가면서부터 혼란은 시작된다. 여러 가지 클래스를 같이 상속받는다는 개념은 흔히 다중 인터페이스 구현이라는 개념과 혼용되어 사용되며, 특히 C++에서 그러하다. "이 클래스가 무슨 일을 하는 클래스입니까?" 라는 질문에 "이 클래스는 A라는 일을 합니다" 라고 간단히 대답할 수 있어야 한다. "이 클래스는 맑은 날엔 A라는 일을 하고 비오는 날엔 B라는 일을 하고 안개 낀 날엔 C라는 일을 합니다" 라고 대답한다면 클래스의 의미를 정확히 파악할 수 없다. 우리가 클래스를 만드는 이유가 관련된 데이터를 하나로 묶어서 이해하기 쉽도록 하는 것인데 클래스가 너무 많은 책임을 가지면 이해하기가 쉽지 않다. 만약 이렇게 여러 가지 책임을 가져야 한다면 클래스를 나눌 것을 강력 추천한다. 객체지향에서 제일 어려운 일 중 하나는 관련된 정보로만 클래스를 구성하는 일이다. 변수 하나, 함수 하나를 넣을 때 "과연 이 기능이 이 클래스에 들어가는 것이 맞을까?"에 대해 고민해야 한다. 클래스 하나가 이일 저일 다 하게 되는 클래스가 된다면 그건 그냥 거대한 코드 덩어리일 뿐 어떠한 방법론의 코드도 아니다. - 문우식, 패턴 그리고 객체지향적 코딩의 법칙
Liskov's Substitution
Fundamental Features
- Abstraction : Abstract Class, Interface, Private Methods and Variables, Encapsulation
- Inheritance : Subclasses and Superclasses, Reusability - 상속은 웬만하면 지양해야 하지 않을까. 조건적 재사용성이 유일한 장점이라고 하는데. 인터페이스를 만들어 놓고 이에 대한 구현 클래스가 여러개인 것은 상관 없지만.
- Multiple Inheritance : Interface
- Polymorphism : Overriding, Overloading
- Dynamic Binding
Quotations
- 객체지향 프로그래밍은 바로 이러한 문제에 대한 해결책을 제시했다. 함수를 아예 데이타에 묶어서 관리하면 그 이름이 짧아지게 될 뿐더러, 함수의 소스코드 또한 데이타 구조의 정리체계에 따라 관리가 가능하다는 것이 바로 객체지향 프로그래밍의 핵심이다. 객체지향 프로그래밍에서는 이렇게 데이타에 묶여진 함수를 메소드(method)라고 부른다.
물론 데이타에 묶어서 관리하는 것이 자연스럽지 못한 함수도 적지 않은게 사실이다. OOP 언어에서는 데이타(객체)에 묶어두기에 적합하지 않은 함수를 클래스나 모듈에 묶어 관리하는 방식으로 이 문제를 비켜가고 있다. 클래스는 함수 이름 관리를 위한 적절한 네임스페이스를 제공해 주기도 하기 때문에, 객체에 묶이지 않은 함수의 경우에도 함수 이름과 그 코드의 관리가 한결 수월하게 되었다.
이 글의 시작에서 언급했던 내용을 다시 한 번 살펴보도록 하자. OOP를 설명하는 일반적인 방법은 상속, 캡슐화, 다형성 등의 개념을 통해서이다. 그런데 캡슐화란 프로그래밍에서는 너무도 보편적인 개념인 추상화(Abstraction)의 또다른 표현일 뿐이고, 다형성은 함수 이름에서 접두사(Prefix)가 빠진다는 것을 어려운 용어로 표현한 것에 불과하다. 상속 조차도 객체지향 시스템을 설계하는 하나의 방식에 불과해서, 자바스크립트 같은 언어에서는 상속 대신 프로토타입(Prototype)이라는 전혀 다른 개념을 사용하고 있다.
http://beyond.daesan.com/articles/2006/08/16/misunderstanding-and-truth-about-oop
References
- [wiki:DesignPattern Design Patterns]
- http://www.oodesign.com/