객체지향 원칙 - Head First Design Pattern
프로그래밍???2010. 7. 1. 09:55
내용 출처 : Head First Design Pattern - O'REILLY / 한빛미디어 - 서환수 역
* 바뀌는 부분을 캡슐화 한다
- 달라지는 부분을 찾아서 나머지 코드에 영향을 주지 않도록 "캡슐화" 한다
- 코드를 변경하는 과정에서 의도하지 않은 일이 일어나는 것을 줄이면서 시스템의 유연성은 향상 시킬 수 있다
- 모든 패턴은 '시스템의 일부분을 다른 부분과 독립적으로 변화시킬 수 있는' 방법을 제공하기 위한 것이다
* 구현이 아닌 인터페이스에 맞춰서 프로그래밍 한다
- Duck의 행동은 특정 행동 인터페이스를 구현한 별도의 클래스안에 있다
- Duck 클래스에서는 그 행동을 구체적으로 구현하는 방법에 대해서 더 이상 알고 있을 필요가 없다
- 특정 인터페이스를 통해 행동을 구현하게 되는데 이것은 여러 클래스에 사용될 수 있다
- 어떤 상위 형식(super type)에 맞춰서 프로그래밍 함으로써 다형성을 활용하는 것이다
- code A의 경우 가장 기초적인 코딩 방식이고 code C의 경우 인터페이스를 활용하여 구현하는 방식이다
ex)
- code A ==>>> Dog d = new Dog(); d.bark();
- code B ==>>> Animal animal = new Dog(); animal.makeSound();
- Code C ==>>> Animal a = getAnimal("dog"); a.makeSound();
* 상속보다 구성을 활용한다
- "A는 B이다"보다 "A에는 B가 있다"가 나을 수 있습니다
- 특정 Behavior를 구현하여 클래스의 Behavior 변수에 FlyBehavior나 QuackBehavior를 제공하는 것이 구성(composition)이다
- 이 Behavior들은 추후 다른 용도의 프로젝트에서도 사용할 수 있다
* 상호작용하는 객체간에는 느슨한 결합을 사용해야 한다
- 느슨하게 결합하는 디자인을 사용하면 변경사항이 생겨도 무난히 처리할 수 있는 유연한 객체지향 시스템을 구축할 수 있습니다. 객체 사이의 상호 의존성을 최소화할 수 있기 때문입니다.
- 특정 클래스나 객체가 다수의 클래스나 객체와 상호작용해야 하는 경우 다수의 객체를 관통하는 인터페이스를 찾아내 공통 인터페이스와 관계를 맺도록 한다
- 위와 같은 방식으로 인터페이스와 관계를 맺게 되면 1:n의 관계에서 1:1의 관계가 된다
* OCP ( Open-Closed Principle)
- 클래스는 확장에 대해서는 열려 있어야 하지만 코드 변경에 대해서는 닫혀 있어야 한다
- 기존 코드를 변경하는 것은 좋은 방법이 아니다
- 기존 코드의 변경 없이 추가적인 클래스의 기능을 확충할 수 있는 디자인이 좋은 디자인이다
* 의존성 뒤집기 원칙 ( Dependency Inversion Principle )
- 추상화된 것에 의존하도록 만들어라.
- 구상 클래스에 의존하도록 만들지 않도록 한다.
- 고수준의 구성요소가 저수준의 구성요소에 의존하면 안된다는 것을 의미합니다.
- PizzaStore는 고수준의 구성요소이며 Pizza 객체는 저수준의 구성요소이다.
- PizzaSrore가 Pizza에 의존하게 되면 구상 Pizza가 늘어날때마다 의존하는 클래스나 객체가 많아지게 된다.
- PizzaStore는 추상화된 Pizza 클래스에만 의존하게 하며, 다른 다수의 피자들은 Pizza에 의존하도록 하면 의존도가 역순이 된다.
- 가이드라인1 : 어떤 변수에도 구상 클래스에 대한 레퍼런스를 저장하지 맙시다.
- 가이드라인2 : 구상 클래스에서 유도된 클래스를 만들지 맙시다.
- 가이드라인3 : 베이스 클래스에 이미 구현되어 있던 메소드를 오버라이드 하지 맙시다.
- 이 가이드라인들은 의존성 뒤집기에 관련되서 고려할 것으로 무조건 이 가이드라인을 따르기는 불가능하다.
* 바뀌는 부분을 캡슐화 한다
- 달라지는 부분을 찾아서 나머지 코드에 영향을 주지 않도록 "캡슐화" 한다
- 코드를 변경하는 과정에서 의도하지 않은 일이 일어나는 것을 줄이면서 시스템의 유연성은 향상 시킬 수 있다
- 모든 패턴은 '시스템의 일부분을 다른 부분과 독립적으로 변화시킬 수 있는' 방법을 제공하기 위한 것이다
* 구현이 아닌 인터페이스에 맞춰서 프로그래밍 한다
- Duck의 행동은 특정 행동 인터페이스를 구현한 별도의 클래스안에 있다
- Duck 클래스에서는 그 행동을 구체적으로 구현하는 방법에 대해서 더 이상 알고 있을 필요가 없다
- 특정 인터페이스를 통해 행동을 구현하게 되는데 이것은 여러 클래스에 사용될 수 있다
- 어떤 상위 형식(super type)에 맞춰서 프로그래밍 함으로써 다형성을 활용하는 것이다
- code A의 경우 가장 기초적인 코딩 방식이고 code C의 경우 인터페이스를 활용하여 구현하는 방식이다
ex)
- code A ==>>> Dog d = new Dog(); d.bark();
- code B ==>>> Animal animal = new Dog(); animal.makeSound();
- Code C ==>>> Animal a = getAnimal("dog"); a.makeSound();
* 상속보다 구성을 활용한다
- "A는 B이다"보다 "A에는 B가 있다"가 나을 수 있습니다
- 특정 Behavior를 구현하여 클래스의 Behavior 변수에 FlyBehavior나 QuackBehavior를 제공하는 것이 구성(composition)이다
- 이 Behavior들은 추후 다른 용도의 프로젝트에서도 사용할 수 있다
* 상호작용하는 객체간에는 느슨한 결합을 사용해야 한다
- 느슨하게 결합하는 디자인을 사용하면 변경사항이 생겨도 무난히 처리할 수 있는 유연한 객체지향 시스템을 구축할 수 있습니다. 객체 사이의 상호 의존성을 최소화할 수 있기 때문입니다.
- 특정 클래스나 객체가 다수의 클래스나 객체와 상호작용해야 하는 경우 다수의 객체를 관통하는 인터페이스를 찾아내 공통 인터페이스와 관계를 맺도록 한다
- 위와 같은 방식으로 인터페이스와 관계를 맺게 되면 1:n의 관계에서 1:1의 관계가 된다
* OCP ( Open-Closed Principle)
- 클래스는 확장에 대해서는 열려 있어야 하지만 코드 변경에 대해서는 닫혀 있어야 한다
- 기존 코드를 변경하는 것은 좋은 방법이 아니다
- 기존 코드의 변경 없이 추가적인 클래스의 기능을 확충할 수 있는 디자인이 좋은 디자인이다
* 의존성 뒤집기 원칙 ( Dependency Inversion Principle )
- 추상화된 것에 의존하도록 만들어라.
- 구상 클래스에 의존하도록 만들지 않도록 한다.
- 고수준의 구성요소가 저수준의 구성요소에 의존하면 안된다는 것을 의미합니다.
- PizzaStore는 고수준의 구성요소이며 Pizza 객체는 저수준의 구성요소이다.
- PizzaSrore가 Pizza에 의존하게 되면 구상 Pizza가 늘어날때마다 의존하는 클래스나 객체가 많아지게 된다.
- PizzaStore는 추상화된 Pizza 클래스에만 의존하게 하며, 다른 다수의 피자들은 Pizza에 의존하도록 하면 의존도가 역순이 된다.
- 가이드라인1 : 어떤 변수에도 구상 클래스에 대한 레퍼런스를 저장하지 맙시다.
- 가이드라인2 : 구상 클래스에서 유도된 클래스를 만들지 맙시다.
- 가이드라인3 : 베이스 클래스에 이미 구현되어 있던 메소드를 오버라이드 하지 맙시다.
- 이 가이드라인들은 의존성 뒤집기에 관련되서 고려할 것으로 무조건 이 가이드라인을 따르기는 불가능하다.
'프로그래밍???' 카테고리의 다른 글
Eclipse CDT에서 Fork 테스트하는 방법 (0) | 2011.06.09 |
---|---|
Windows에서 localhost 도메인 이름 설정 (0) | 2011.03.29 |
패턴 정리 - Head first Design Pattern (0) | 2010.07.01 |
[Fatal Error] Variants.pas(4333): F2092 Program or unit `Variants` (0) | 2009.12.01 |
디자인패턴 예제 및 데모 사이트 (758) | 2008.12.17 |