2013년 2월 21일 목요일

헤드퍼스트 OOAD -8강-

이번 8강의 제목은 디자인 원리들이다.

프로그래밍 하면서 설계할 때 어떨때 어떤 디자인을 써야하는지 4가지로 분류를 했다.
먼저 디자인 원리란?
코드를 좀 더 유지보수하기 쉽고, 유연하고, 확장하기 쉽게 만들기 위해, 코드의 작성이나 디자인에 적용되는 기본 도구 또는 기법
이라고 괜히 길고 어렵게 써놨다 ㅡㅡ

원리1 개방 - 폐쇄의 원리(Open - Closed Principle, OCP)

OCP는 기존 코드를 변경하지 않으면서 코드의 수정을 허용하는 것 이다.

이게 도대체 뭔소리당가??

만약 악기 클래스가 있고 기타 클래스가 있다고 하고 악기 클래스에서 기타 클래스가 상속을 받아서 쓴다고 해보자.

악기클래스에는 악기의 전반적인 메소드가 있고, 기타 클래스는 기타의 특정부분을 가지고 있다. 하지만 악기의 전반적인 메소드를 상속을 받았지만 악기 클래스의 메소드를 변경해야할 때가 있을것이다. 이때 오버라이드를 해서 변경을 한다.

한마디로 이 원리는 상속 + 오버라이드 이다 -_- (끝)


원리 2 반복 금지의 원리 (Don't Repeat Yourself, DRY)

DRY는 공통되는 부분을 추출하여 추상화하고 한 곳에 두어 중복 코드를 피한다
이건 솔직히 원리라기보단 거의 기본에 가까운 것이다 ㅡ.ㅡ
하지만 궃이 정의하자면 하나의 요구 사항은 한 곳에 두어야 한다는 것이다.
중복코드를 피한다는 것은 각 기능과 요구 사항을 한번만 구현하려고 노력하는 것이다.

한마디로 DRY는 시스템의 각 정보와 기능을 말이 되는 하나의 장소에 두는 것을 의미한다.(끝)


원리 3 단일 책임의 원리(Single Responsibility Principle, SRP)

SRP 단일 책임의 원리 - 시스템의 모든 객체는 하나의 책임만을 가지며, 객체가 제공하는 모든 서비스는 그 하나의 책임을 수행하는데 집중되어 있어야 한다.

위의 DRY랑 같은거 아니냐!!! 라고 할수도 있으나 관련은 있지만 좀 다르다.

dry는 하나의 기능을 한 곳에 두자는 것이고, srp는 클래스가 하나의 일만 하자는 것이다.
즉, 기능별로 세세하게 나눠서 놓자는 것이다.
만약 문을 여는 클래스가 있다고 해보자. 그럼 그건 문만 여는 거지 문을 열고 닫고 잠그고 풀고 어쩌구 저쩌구를 다 넣는것이 아닌 문을 여는 기능만 넣자는 것이다.

한 클래스에 있는 메소드가 하나의 일을 하는지 찾아내는 법을 소개한다.

아래와 같은 클래스가 있다고 해보자

Automobile 클래스에 대한 SRP 분석

Automobile 가 자신을 start 한다
Automobile 가 자신을 stop 한다
Automobile 가 자신을 changTires 한다
Automobile 가 자신을 drive 한다
Automobile 가 자신을 wash 한다
Automobile 가 자신을 checkOil 한다
Automobile 가 자신을 getOil 한다

쓰고 말이 되는 것과 안되는 것을 구분한다. 이중에서 말이 되는 것은 냅두고 안되는 것은 따로 빼는 것이다.
위와 같은 경우는 1,2,7번만 말이 된다.
나머지는 따로 빼서 클래스를 만드는 것이다. 그래서 이것도 끝 -_-v

원리 4 리스코프 치환 원리 (LSP)

LSP 의 의미는 자식 타입들은 부모 타입들이 사용되는 곳에 대체 될 수 있어야 한다.

이게 도대체 뭔 x소리냐?? 할 수도 있다.
예를 들어 2d 배경 클래스가 있는데, 이곳에 3d 배경을 하기 위해서 2d 배경 클래스를 상속 받아서 z축만 추가 한다고 해보자.
얼핏 보면 어? 맞는거 같은데? 하겠지만 어차피 2d에서 쓰는 것과 3d에서 쓰는 것은 많은 차이가 있다. 땅속에도 들어가야 하기에 - 값도 들어갈수도 있고 날기도 해야하고 상속을 받으면 3d에서는 필요 없는 부분도 있을 것이다.
그럼 이걸 어찌 하란 말인가?
상속을 하는 것이 아닌 기능을 위임하는 것이다.
위임은 특정 일의 책임을 다른 클래스나 메소드에 맡길 때 지칭하는 것이다.
3d와 2d에서 공통된 부분은 위임해서 2d에서 끌어다 쓰고, 3d 특화된 것은 3d에서 쓰는 거다.
다른 클래스의 기능을 사용해야 하지만 그 기능을 변경하고 싶지 않다면 상속 대신 위임을 사용하자.

또 다른 방법으로는 구성을 사용해서 다른 클래스들의 행동을 조합하는 방법이 있다.

fps 게임의 무기 클래스가 있다고 해보자.
무기 혼자만은 걍 객체일 뿐이다. 유저가 무기를 주워다 사용을 해야 의미가 있는 것이다.
그리고 무기는 기능도 다르고 다양하다. 이것을 연결할 때 구성을 사용하여 행동을 조합하는 것이다. 이건 클래스 다이어그램을 보면 이해가 쉬울 것이다.

구성을 통해 하나의 인터페이스를 구현한 여러 클래스들의 기능을 사용할 수 있고 실행중에 그 클래스를 바꾸어 기능을 변경할 수 있다.

구성에서는 다른 행동들로 구성된 객체는 그 행동을 소유하고 있다. 그 객레가 없어지면 소유하고 있던 모든 행동들도 없어진다. 구성에 참여한 행동들은 그 구성의 외부에서는 존재하지 않는다.

이게 뭔 소리인가 하면 ㅡㅡ
유닛이 무기를 주워다가 열라게 쓰다가 유닛이 죽으면 무기도 없어진다는 것이다.
이야~ 쉽게 설명했다~~~ 퍽퍽

만약 유닛이 죽어도 무기는 그냥 땅에 떨어지고 없어지지 않게 하고 싶다면?
그 때 써야 하는 것이 바로 집합이다.

집합은 유닛과 무기가 관계는 있지만 유닛이 없어진다고 무기도 같이 없어지는 관계는 아닌 것이다.

쓸데없이 4번째 디자인은 4개로 또 나뉘어서 있다 이것을 정리해보겠다.

상속 - 그야말로 부모꺼를 전.부 물려 받는 것
위임 - 전부 물려 받지 많고 필요한 것만 부모에게 시키는 것(호로자식?!)
구성 - 하나 또는 여러개의 클래스들, 특히 비슷한 종류의 여러 클래스들로 부터 행동을 재사용하는 법, 구성으로 연결된 객체는 객체의 외부에 독립적으로 존재할 수 없다
집합 - 구성과 비슷하지만 객체의 행동이 외부에서도 연결 될 수 있다.


이번 강의 좀 길게 썼다. 그만큼 공부하기에도 빡쎘다는 것이다 하악
어차피 복습 차원에서 올리는 것이니 나만 알아봐도 만족이다 ㅡㅡ;;;

그럼 이번 강도 끝!~

댓글 없음:

댓글 쓰기