2013년 2월 25일 월요일

헤드퍼스트 OOAD - 10강 - 종합하기

드디어 마지막 강 10강이다. (씹강이다 -_-)

이번 강은 처음부터 끝까지 프로그램을 만드는 과정이 담긴 종합하는 강이다

OOAD 프로젝트의 생명주기를 살펴보자.

특징리스트 -> 유스케이스 다이어그램 -> 문제점 분해하기

-> 요구사항 -> 도메인분석 -> 사전 설계 -> 구현 -> 완성

빨강 부분은 반복적으로 하는 부분이다.

위대한 프로그램을 만들기 위해선 3단계를 거쳐야 했다

3단계를 복습하자면.

1. 여러분의 소프트웨어가 고객이 원하는 기능을 하도록 만드는 것
2. 객체지향의 기본 원리를 적용해서 소프트웨어를 유연하게 하는 것
3. 유지보수와 재사용이 쉬운 디자인을 위해 노력하는 것

당신이 만약 지하철 노선도를 만드는 프로젝트를 맡았다고 해보자.
위의 생명주기를 토대로 시작해보자.

1. 특징 리스트 작성


  • 지하철 노선과 노선의 역들을 표시
  • 겹쳐진 노선을 포함하여 다수의 지하철 노선을 저장할 수 있어야 함
  • 모든 노선에서는 임의의 두 역 사이의 유요한 경로를 찾을 수 있어야 함
  • 일련의 방향 표시로, 두 역 사이의 경로를 출력할 수 있어야 함

2. 유스케이스 다이어그램 작성



관리자 - 지하철 노선과 노선들의 역을 표시, 겹쳐진 노선을 포함하여 다수의 지하철 노선을 저장

사용자 - 두 역 사이의 유요한 경로를 찾기, 두 역 사이에 있는 특정 경로의 방향 표시 출력

유스케이스는 사용법을 반영하고, 특징은 기능을 반영한다.


3. 문제점 분해하기


별개의 기능 조각을 분리하는 것이다. 먼저 크게 분리해보자.

지하철, 리더, 프린터, 테스트

로 분리해봤다.
문제점을 분해 하다 보니 이해가 안가는 부분이 있다.
지하철 시스템이 뭐지??
지하철 역과 노선을 저장할 때 관리자가 갖고 있어야할 정보가 뭐지?

요구 사항을 하기 전에 문제를 이해하는 단계가 있어야 한다.
지하철 노선 적재하기에 대한 유스케이스를 작성해 보자.
---------------------------------------------------------------------------------
지하철 노선 적재하기 (유스케이스)

  1. 관리자가 역과 노선이 담긴 파일을 공급한다.
  2. 시스템은 역의 이름을 읽는다.
  3. 시스템은 역이 이미 존재하지 않는지 검증한다.
  4. 시스템은 지하철에 새로운 역을 추가한다
  5. 시스템은 모든 역이 추가될 때까지 단계 2~4를 반복한다
  6. 시스템은 추가할 노선의 이름을 읽는다
  7. 시스템은 연결되어 있는 두 역을 읽는다.
  8. 시스템은 역들이 존재하는지 검증한다
  9. 시스템은 현재 노선의 두 역 사이에, 양방향으로 진행 가능한 새로운 연결을 생성한다
  10. 시스템은 노선이 완성될 때까지 단계 7~9를 반복한다.
  11. 시스템은 모든 노선이 입력될 때까지 단게 6~10을 반복한다.
---------------------------------------------------------------------------------

4. 도메인 분석 


위의 유스케이스를 기반으로 분석을 하는 것이다. 먼저 명사와 동사를 나누어 적어보자.

명사(클래스 후보) - 관리자, , 파일, 시스템, 노선, 연결, 지하철

동사(오퍼레이션 후보) - 파일 제공한다, 역을 검증한다, 반복한다, 읽는다, 역을 추가한다, 연결을 추가한다.

5. 사전 설계


주황색으로 표시한 부분을 기반으로 클래스 다이어그램을 작성했다.


6. 구현하기

관리자 부분을 먼저 구현하고 테스트해보고 잘 구동되면
사용자 부분을 구현하고 테스트 해보면서 반복하는 것이다.

이 프로그램은 역의 추가, 삭제, 수정/노선의 추가, 삭제, 수정 이 용의해야하며
관리자 모드와 사용자 모드를 철저히 분리해야한다.

지금 위의 클래스 다이어그램에는 없는 출력 부분도 추가해줘야한다.
해당 소스 코드는 여기에서 다운 받길 바란다.

모든 것을 하나하나 구현할 필요는 없다. 공개 소스가 있다면 재사용하는 것도 프로그래머의  실력인 것이다. 

구현하면서 누구나 코드를 알아볼수 있게 주석과 이름을 잘 짓는 것이 중요하다.
유지보수가 쉽게 만드는 것도 프로그래머의 자질이다.

이로써 기나긴 OOAD에 대한 강좌(누가 본다고?!! ㅠㅠ)가 끝났다.
3월10일에 자격증 시험이 있어서 당분간 연재를 쉬고자 한다.
다음 강좌는 델파이, 자바, 자료구조, tcp/ip, 아이폰 개발 중 하나를 하겠다.
말이 강좌지 내가 공부하면서 까먹을까봐 다시 복습 차원에서 정리해서 올리는 거다 ㅡ.ㅡ;
그럼 그때까지 모두 수고염~~ >.<

2013년 2월 22일 금요일

헤드퍼스트 OOAD - 9강 -

9강의 내용은 어떤 방식으로 코딩을 할 것인가이다.

앞서 말했듯이 고객은 프로그래밍에 대해 전혀 모른다고 가정하는 것이 좋다.
그리고 눈으로 직접 보여줘야 안심을 할 것이다.
이때 3가지의 방식으로 나뉜다.

특징 주도 개발 - 기능을 위주로 만드는 것이다.

유스케이스 주도 개발 - 큰 시나리오를 토대로 개발하는 것이다.

테스트 주도 개발 - 실수를 없애기 위해 상상 가능한 모든 테스트를 통과해야 다음 단계를 진행하는 개발

스타3를 만든다고 가정을 하자면

특징 주도 개발은 마린의 총쏘는 모습, 이동 속도, 방법, 체력, 방어력을 만들어서 보여주는 것이다.

유스케이스 주도 개발은 스타 에피소드 1을 하나 통짜로 만드는 것이다.

적절한 비유인지는 모르겠으나.... 난 그리 이해했다 ㅡㅡ;;

그리고 또 다른 방법은 테스트 주도 개발이다.

한가지 기능의 테스트 시나리오를 작성하고 , 그 다음에 그 기능에 대한 코드를 작성한다.
그리고 가능한 모든 테스트를 통과할 때까지 소프트웨어를 수정하는 것이다.

책은 훨씬 긴 내용이지만 내가 지금 몹시 졸려서 이정도만 쓸란다 ㅡㅡ;;(어차피 보는 사람도 없는듯 ㅡㅜ)

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개로 또 나뉘어서 있다 이것을 정리해보겠다.

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


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

그럼 이번 강도 끝!~

2013년 2월 19일 화요일

헤드퍼스트 OOAD -7강

7강의 주제는 아키텍처다.

아키텍처란??
시스템의 분할, 나뉜 부분들 사이의 연결과 상호 작용 메커니즘, 그리고 시스템의 디자인에 사용된 원리와 결정 사항들을 담고 있는 시스템의 구조

아키텍처가 해야할 일은 수많은 요구사항과 특징들을 잘 정리해서 설계를 하는 것이다.

예를 들어 스타크래프트3를 만든다고 해보자.
수많은 요구사항이 있을 것이다.
그럼 아키텍처는 가장 먼저 해야할일이 뭘까???
아래와 같이 요구사항이 있다고 해보자.
---------------------------------------------------------------------------------
스타크래프트 3
(특징 리스트)

1. 다양한 타입의 지형을 지원한다
2. 공상 과학 소설이나 판타지 소설에 등장하는 가상의 시대를 포함한 다양한 시대를 지원한다
3. 게임의 특성에 맞는 여러 타입의 부대들 또는 유닛들을 지원한다
4. 새로운 작전 수행이나 전쟁 시나리오를 위한 추가 모듈을 지원한다
5. 사각형의 타일들로 구성된 보드를 제공하고 각 타일은 지형 타입을 가지고 있다
6. 기본적인 이동을 관장한다
--------------------------------------------------------------------------------
아키텍처는 위와 같은 요구 사항에서 우선순위를 정하여 프로젝트를 진행해야한다.
그럼 어디서부터 시작을 해야할까?
이렇게 생각하면서 추적을 해야한다.

1. 시스템의 본질이 되는 부분은 무엇인가?
2. 이것은 도대체 무슨 의미인가?
3. 도대체 어떻게 해야하나?

이게 뭔 x소리냐고 한다면 책을 탓해라 ㅡ.ㅡ책에 그리 쓰여있다
위와 같은 요구사항에서는 가장 기본이 되는건 보드다.
보드가 있어야 뭔 유닛을 이동하고 싸우고 난리 부르스를 출 수 있는 것이다.
일단 보드를 만들자(빨리 만들어라 찰싹찰싹)

이번 스타3는 다양한 유닛이 필요하다. 유닛을 살펴보자
마법사, 검사, 저격수, 비행기, 배, 탱크, 벌레, 인부, 벙커, 잠수함 등등

아악 이것을 하나하나 구현하는것은 개발자가 할일이고 아키텍처는 유닛이라는 것을 어찌해놔야 확장성과 재사용성이 좋아지는지 고민해야한다.

1. 공통점은 무엇인가?
2. 차이점은 무엇인가?

먼저 공통점을 생각해보자.
모든 유닛은 각자의 무기가 있다, 즉, 싸울수 있다는 것이다.(심지어 scv도 싸운다)
차이점은 무기의 종류와 거리, 데미지, 방어력, 인구수 등이 다르다

스타3는 최대 8명이서 각자 200개까지의 유닛을 컨트롤하여 싸우는 게임이다
만약 공통점과 차이점을 분리하여 상속을 받아 쓰는 개념으로 만든다면
서버에 꽤 큰 부담을 줄 것이다. 그리고 밸런스 조정할 때도 꽤 힘든 작업이 될 것이다.

그래서 이번 같은 경우는 한 클래스에 전부 때려 박아서 만들 예정이다(뭐라?!!!)

과연 이게 좋은 일인가?? 물론 상속을 이용해서 만들어보고, 속도가 안나오면, 한 클래스로 묶어도 보고 그러면 얼마나 좋겠냐만......
고객과 사장은 결코 그런걸 원하지 않는다.

그럼 아키텍처는 "선택"을 해야한다. 확장성과 효율성을 선택해야하는 것이다.
확장을 하려는 것은 코드를 기능별로 나눠 놓는 것이 좋다.
효율성은 너무 많은 객체를 생성 안하는 것이 좋다.
그것을 결정하는 것은 당신의 몫이다 ( --);; ㅌㅌㅌㅌ

위험 요소를 줄이는 것이 위대한 소프트웨어를 만드는데 도움이 된다.

-핵심 정리(응? 뭘 했다고?)-


  • 아키텍처는 모든 다이어그램, 계획, 특징 리스트 들을 잘 정돈된 애플리케이션으로 만드는데  도움을 줍니다
  • 프로젝트에 매우 중요한 시스템의 특징들은 아키텍처적으로 중요합니다.
  • 시스템의 본질인 특징, 의미가 명확하지 않은 특징, 또는 처음에 어떻게 구현해야할지 명확하지 않은 특징에 초점을 맞추세요
  • 프로젝트의 아키텍처 설계 단계에서 하는 모든 일은 프로젝트 실패의 위험을 줄여야합니다.
  • 유스케이스의 세부 사항이 필요하지 않을 경우, 소프트웨어가 어떻게 이용될 수 있는지를 설명하는 시나리오를 작성하면 요구사항을 빠르게 수집하는데 도움이 됩니다
  • 특징이 무엇인지 확실히 모를 때, 고객에게 묻고, 그런 후 얻은 답을 일반화하여 특징을 잘 이해하도록 합니다
  • 공통점 분석을 사용해서 유연한 소프트웨어 솔루션을 만드세요
  • 고객은 여러분 생각에 정말 멋지게 자여진 코드에 관심이 있기보다는 그들이 원하는 일을 하고, 시간에 맞게 만들어지는 소프으웨어에 관심이 많습니다.
이번 강도 이렇게 마친다 -_-v
우왕이제 3강 남았다 >.< OOAD가 끝나면 자격증 시험 때문에 당분간 업데이트를 못할 것이다....;;;
OOAD가 끝나면 디자인 패턴, 자료구조, TCP/IP, 리눅스, 델파이 중 하나를 연재할까한다~

2013년 2월 18일 월요일

헤드퍼스트 OOAD - 6강

이번 강은 큰 프로그램을 만들려면 어찌해야 하는지에 대한 강좌다.

일단 기본적인 것은 같다.

1. 나의 소프트웨어가 고객이 원하는 기능을 하도록
2. 객체지향의 기본 원리를 적용해서 소프트웨어를 유연하게 만들기
3. 유지보수와 재사용이 쉬운 디자인을 위해 노력하기

큰 프로그램을 만들려면 일단 기능별로 나누어서 각 조각들을 개별적으로 풀어가며 해결한다.

변하는 것을 캡슐화하여 프로그램을 더 유연하고 변경하기 쉽게 만단다.

구현에 맞추어 코딩하는 것보다 인터페이스에 맞추어 코딩하면 소프트웨어 확장이 더 쉽다

변경과 확장이 쉽고 고객이 원하는 일을 한다.
--------------------------------------------------------------------------------
큰 프로그램은 많은 정보가 필요하다.
고객과 많은 미팅을 통해 많은 정보를 얻어내야 한다.
그러기 위해선 특징을 먼저 찾아야 한다.

하지만 고객은 프로그래머가 아니다.
서로 소통을 하기 위해서는 유스케이스 다이어그램을 쓴다.

유스케이스 다이어그램은 특별히 다른 것이 아니다

프로그램을 잘 모르는 사람들에게 프로그램을 설명하기 위한 그림이다.

그림으로 설명하는 것이 글씨로 설명하는 것보다 가독성도 좋고 빠르게 이해되기 때문이다.

그림으로 설명 뒤에는 도메인 분석을 해서 고객이 실제로 이해를 했는지 설명하는 것이다.

이쯤에서 도메인 분석이란?
기존 시스템과 개발 이력, 도메인 전문가들로부터 얻은 지식, 기반 이론, 그리고 도메인에서 새로 등장하는 기술을 기반으로 도메인 관련 정보를 찾아내고, 모으고, 구조화하고, 나타내는 프로세스

라고 한다 ㅡㅡ (뭔 소리여 이게)

고객들은 객체가 어쩌구 클래스가 어쩌구는 뭔소린지 모른다.
그리고 큰 프로그램은 너무 크기에 기능별로 나누어서 설명하는 것이다.

예를 들면 스타크래프트3를 만든다고 하면

유닛, 종족, 기능, 배경, 스토리, 컨트롤, UI 등등으로 나누어서 설명을 한다는 것이다.

스타크래프트3라는 게임이 있고 그 안에 각 특성이 있는 것을 나누어 설명하는 것이다.

이렇게 나누는 것은 프로그래밍을 모르는 디자이너나 영업사원들에게도 설명할 때 유용하다.

MVC 패턴은 유명한 패턴이다.

모델 뷰 컨트롤러를 나누어 구현하는 것인데.

스타크래프트3로 설명하자면.....(아직 나오지도 않은걸??)

뷰는 종족, 배경을 그래픽으로 보여주는 부분이고

모델은 각 유닛의 기능들(마린이 총쏘고, 뮤탈이 변신하는 등등)

컨트롤러는 게임 전체를 제어하고(200개의 유닛이상 못만들게 한다던가, 지도 밖을 못나간게 한다던지....)

해서 각자 자신의 일만 하면 되는 분업이라고 할 수 있겠다.

각자 다른 분야에서 협업하려면 공통된 자료가 있어야 하는데 그것이 바로 아까 말한 도메인 분석이다.


이번 강은 이게 다다 ㅡㅡ;;;(때리지마)

이게 뭐야!!! (미안 ㅌㅌㅌㅌ)

2013년 2월 14일 목요일

헤드퍼스트 OOAD 5강 - part 2

먼저 5강 파트1에서 만들었던 클래스 다이어그램을 보자.


이 다이어그램은 무엇이 문제인지 알겠는가?
1. 악기가 추가 될 때마다 빈 클래스를 추가해줘야 한다.
2. search 가 늘어나야 한다.
3. 각 악기의 고유 특성을 추가해야한다.

지금 이 프로그램은 악기의 공통 속성은 하나로 묶고 고유 속성은 상속 받아서 쓰고 있다.

이것은 지나치게 많은 클래스를 유발한다.

잘 만들어진 클래스는 하나의 일을 잘하고 그 외의 일은 하려고 하지 않는 것이다.

지금 위의 클래스 다이어그램은 클래스가 값의 역할을 하고 있다.

이것을 수정한 클래스 다이어그램이다.


악기의 모든 값을 Map에 저장하였고 각 특성을 열거형으로 분리하여 저장하였다.
이렇게 되면 악기가 추가되어도 편리해진다.
선이 이어지지 않은 클래스들이 열거형이다.
프로그램을 유연하게 만드는 것이 재사용과 수정할 때 용의하다.
값이 변경되는 부분은 따로 분리하고
어떤 일을 하는 부분은 캡슐화하여 연결시키는 것이 좋은 프로그램이라고 할 수 있다.

이런 프로그램을 응집도가 높은 프로그램이라고 하는데

응집도란? 
하나의 모듈, 클래스, 또는 객체들을 이루는 원소들 사이에 연결의 정도를 나타낸다. 소프트웨어의 응집도가 높을수록 프로그램에서 각 클래스의 역할들이 잘 정의되어 있고 잘 연결되어 있는 것이다. 각 클래스는 밀접하게 연결되어 있는 하나의 매우 특정한 집합의 일들을 수행한다. 

이라고 정의 되어 있는데 참 말 어렵게 해놨다 ㅡㅡ
한마디로 세세하게 연결이 잘되어 있고 확장하기 쉬운게 좋다는거다.
연결이 잘되어 있다는 것은 분리도 쉽다는 뜻이다.

좋은 프로그램은 변경이 쉽고, 재사용성이 좋고, 연결과 분리가 쉬운 것이다.
이것이 바로 객체 지향적인 프로그래밍이다.

속도는......... 아무래도  절차지향적인 것보단 느리다... 그래도 워낙 하드웨어가 좋아서 상관 읍다.

2013년 2월 13일 수요일

헤드퍼스트 OOAD 5강 - part 1

먼저 아래 클래스 다이어그램을 보자.
아래 클래스 다이어그램은 기타 검색 프로그램이다.

이 프로그램에 요구사항이 들어왔다.
만돌라를 추가해서 검색해달라고.....
만돌라는 기타와 유사한 점이 많다. 이것을 이제 추가해보자.
비슷한 사항은 상속을 통해 물려 받을 것이다.

Instrument 를 통해 공통부분은 합치고 특이점만 나눠놨다.
빈 삼각형이 있는 실선은 상속을 의미한다.
이제 기타스펙으로 되어 있는것을 스펙으로 분리해보겠다.


얼핏 보기엔 드럽게 복잡해 보이지만 결국은 공통된 곳은 상속 받고
나머지는 죄다 나눠 놓은 것이다. 
클래스 다이어그램을 통해서 복잡성을 오히려 낮출수 있고 코딩에도 도움이 된다.

해당 코드를 이곳에 써봐야 길어지기만 하니깐 링크에서 소스를 다운 받아서 해보길 바란다.
요구사항이 바뀔 때 어찌 수정을 해야 쉽고 간단하게 수정이 가능할지 생각해보자

소스는 이곳에서 다운 받는다.














2013년 2월 12일 화요일

헤드퍼스트 OOAD 4강

4강 제목은 "분석"이다.

뭘 분석을 하냐고?? 당연히 소녀시대의 모든 것을....
은 농담이고 유스케이스를 분석하는 것이다.
먼저 아래 클래스 다이어그램을 보자.


이게 뭐다냐??
강아지 문이라는 프로그램인데.
리모컨으로 문을 열어주거나 개가 짖으면 자동으로 문이 열리는 간지 폭발 프로그램이다!!

화살표는 참조를 표시한다. 화살표 옆에 있는 door은 door을 보낸다는 뜻이다.

위의 것을 유스케이스로 작성해 보자
---------------------------------------------------------------------------------
강아지문 버전 3.0
문이 하는 일 
주 경로
1. 주인 강아지가 밖에 나가려고 짖습니다.
2. 강아지 소리 인식기가 강아지 소리를 "듣습니다".
3. 주인 강아지가 짖으면, 강아지 소리 인식기가 여는 요청을 강아지 문에 보냅니다.
4. 강아지 문이 열립니다.
5. 주인 강아지가 밖으로 나갑니다.
6. 주인 강아지가 화장실을 이용합니다.
    6.1 문이 자동으로 닫힙니다.
    6.2 주인 강아지가 안에 들어보내 달라고 짖습니다.
    6.3 강아지 소리 인식기가 강아지 소리를 "듣습니다"(다시)
    6.4 주인 강아지가 짖으면, 강아지 소리 인식기가 여는 요청을 문에 보냅니다.
    6.5 강아지 문이 열립니다.(다시)
7. 주인 강아지는 안으로 들어 옵니다.
8. 문이 자동으로 닫힙니다.

대체 경로들
2.1 주인이 강아지가 짖는 것을 듣습니다.
3.1 주인이 리모콘의 버튼을 누릅니다.

6.3.1 주인이 강아지가 짖는 것을 듣습니다.
6.4.1 주인이 리모콘의 버튼을 누릅니다.
---------------------------------------------------------------------------------
라고 표현을 했다.
자~ 이제 이것을 분석해 보자. 분석을 하는 법은 먼저 명사들을 적어보는 거다.

명사 - 강아지, 강아지 소리 인식기, 강아지 문, 주인, 요청, 리모콘, 버튼. 안/밖, 강아지 소리, 화장실

명사를 왜 적었냐고 난리 부르스를 추기 전에 이것들을 한 이유가 있다.
명사들은 클래스의 유력한 후보들이다!!!

물론 후보들이기 때문에 전부가 클래스가 되는건 아니다.
이 프로그램에서는 강아지 소리 인식기, 리모콘, 강아지 소리, 강아지 문 이 클래스가 되었다.

그럼 동사들도 적어보자.

동사 - 짖는다, 듣는다, 열린다, 나간다, 이용한다, 닫힌다, 누른다
그럼 동사는 뭐다냐?!
동사들은 메소드의 유력한 후보다!!

이것을 바탕으로 만든 것이 바로 아까 보았던 위의 다이어 그램이다.
스크롤 올리기 귀찮아 할 꺼 같아서 다시 보여준다.


물론 유스케이스나, 클래스 다이어그램은 프로그램의 세세한 모습을 보여주지는 않는다.
전체적인 설계를 하고 서로 공통으로 작업을 할 때 의사소통이 잘 되기 위해 만드는 것이다.
이제 이것을 바탕으로 코딩을 하는 것은 바로 당신의 몫이다~



2013년 2월 8일 금요일

헤드퍼스트 OOAD 3강

이번 강은 요구 사항 변경이다.

고객들의 요구사항은 끊임 없이 늘어난다.(무료 업그레이드인 경우는 더 심하다)

2강에서 만들었던(?) 프로그램의 유스케이스를 보자.

고객만 통과 가능한 문, 버전 3.0 
이 문이 하는 일
1. 누군가가 문을 통과하고 싶다.
2. 이 쇼키가 고객인지 확인한다 (확인법은 안구 + 음성)
    2.1 고객이면 문을 열어준다
    2.2 고객이 아니면 한번 경고를 한다
3. 상황에 따라 행동한다.
    3.1 고객인 경우 - 문을 통과하면 문을 닫고 잠근다
    3.2 고객이 아닌 경우 - 한번 경고를 준다.
         3.2.1 - 걍 가면 상황 해제
         3.2.2 - 또 시도하면 전기 충격
         3.2.3 - 전기 충격에도 계속 시도하면 기관총 발사, 시체 처리반에게 연락


위와 같은 프로그램에서 고객 불만 사항이 접수되었다.
1. 감기 걸려서 문이 안열린다.
2. 눈병 걸렸더니 문이 안열린다.
3. 정전이 되니 문이 안열린다.
4. 시체 처리반이 시체만 가져가고 청소는 하지 않는다

위와 같은 불만이 접수되었을 때 개발자가 수용해야 하고 하지 말아야 할 사항은 무엇일까?

1,2 번은 대체 방법으로 문을 열수 있게 할 수 있다
3번은 하드웨어 업체가 해야할 일이다.
4번은....... 시체 처리반에게 추가로 요구 해야할 사항이다.

개발자는 1,2 번에 대해서만 접수해서 업그레이드 하면 된다.
업그레이드가 될 때마다 유스케이스를 새로 작성해야한다.

----------------------------------------------------------------------------------------------------------------------------------

고객만 통과 가능한 문, 버전 4.0 
이 문이 하는 일
1. 누군가가 문을 통과하고 싶다.
2. 이 쇼키가 고객인지 확인한다 (확인법은 안구 + 음성)
          2.1.1 고객 확인이 어려운 경우는 비밀번호를 입력하도록 한다. 
            2.1.2 비밀번호가 맞으면 2.1로 틀리면 2.2 로 
    2.1 고객이면 문을 열어준다
    2.2 고객이 아니면 한번 경고를 한다
3. 상황에 따라 행동한다.
    3.1 고객인 경우 - 문을 통과하면 문을 닫고 잠근다
    3.2 고객이 아닌 경우 - 한번 경고를 준다.
         3.2.1 - 걍 가면 상황 해제
         3.2.2 - 또 시도하면 전기 충격
         3.2.3 - 전기 충격에도 계속 시도하면 기관총 발사, 시체 처리반에게 연락

----------------------------------------------------------------------------------------------------------------------------------
버전 4.0을 보면 파랑색 글씨부분이 추가 되었다. 
하지만 뭔가 가독성도 떨어지고 계속 추가 될때마다 이런식으로 추가하면 조낸 빡칠꺼 같다.
그래서 이것을 분리해서 표기하기로 한다.
----------------------------------------------------------------------------------------------------------------------------------

고객만 통과 가능한 문, 버전 4.1 
이 문이 하는 일
주경로
1. 누군가가 문을 통과하고 싶다.
2. 이 쇼키가 고객인지 확인한다 (확인법은 안구 + 음성)
    2.1 고객이면 문을 열어준다
    2.2 고객이 아니면 한번 경고를 한다
3. 상황에 따라 행동한다.
    3.1 고객인 경우 - 문을 통과하면 문을 닫고 잠근다
    3.2 고객이 아닌 경우 - 한번 경고를 준다.
         3.2.1 - 걍 가면 상황 해제
         3.2.2 - 또 시도하면 전기 충격
         3.2.3 - 전기 충격에도 계속 시도하면 기관총 발사, 시체 처리반에게 연락

대체경로
2.1.1 고객 확인이 어려운 경우는 비밀번호를 입력하도록 한다. 

2.1.2 비밀번호가 맞으면 2.1로 틀리면 2.2 로 


----------------------------------------------------------------------------------------------------------------------------------


4.1 버전은 4.0에서 주경로와 대체경로를 분리 하였다.


이런식으로 분리를 해 놓으면 추가가 되더라도 가독성을 좋아진다.


요구사항이 있을 때마다 업그레이드를 해주는 것은 심각한 인력 낭비가 될 수도 있다.


심각한 오류는 당연 즉시 해결해야하지만


그냥 기능 개선 같은 경우는 업그레이드를 할 수도 있지만

아예 새로 출시해서 수익을 얻는 것이 더 좋을 수도 있다.


그것에 대한 판단은 당신의 판단이다.

2013년 2월 7일 목요일

헤드퍼스트 OOAD 2강

이번 2강의 제목은 요구 사항 수집 이다.

프로그래밍은 너무도 당연하지만 호갱... 아닌 고객이 원하는 것을 만들어 주는 것이다.
물론 내가 만들어서 남에게 팔 수도 있다 ㅡ.ㅡ
어째든........ 고객이 원하는게 뭔지 알려면 소통이 잘 되어야 한다.
고객 앞에서 클래스가 어쩌구, UML이 어쩌구, DB가 어쩌구 백날 떠들어봐야 모.른.다.

대부분의 고객은 자신이 원하는 것을 구체적으로 말하지 않는다.

예를 들면
내가 근처에 오면 자동으로 문이 열리게 해줘!! 그런데 나만 들어갈수 있는 문이어야 해~ 이런 식이라면

개발자들은 이 사람만 인식하는 문을 만들기 위해서 개 고생을 해야할 것이다.
그런데 개발자가 이사람 인증을 지문인식으로 했다고 해보자.

그런데 알고 봤더니 고객이 손이 없는 장애우라면?.......
당연 안팔릴 것이다.

이건 고객과 개발자를 동시에 빡치게 하는 일이므로 사전에 디테일하고 꼼꼼하게 요구사항을 수집해야하는 것이다.(가카가 개발자 하면 조낸 잘할 듯)

먼저 요구 사항의 정의를 보자.

요구 사항 - 시스템이 올바르게 동작하기 위해서 수행하는 특정한 하나의 일

그럼 요구사항 리스트를 만들어보자.

2013년 2월 6일 수요일

헤드퍼스트 OOAD 1강 -3단계-

이제 3단계다.
1~3 단계가 무엇인지 복습해보자.

1. 소프트웨어가 고객이 원하는 기능을 하도록 구현
2. 객체지향의 기본 원리를 적용해서 소프트웨어를 유연하게 하기
3. 유지보수와 재사용이 쉬운 디자인으로 만들기 <-- 이걸할 차례


현재 2단계의 UML 이다.


자 이젠 이것을 어찌 바꿀까???
소스를 다운 받아서 보면 알겠지만 현재 Inventory 클래스에서 검색을 담당하고 있다.
하지만 검색을 하면서 GuitarSpec을 비교해가며 일치하는 것을 보여주고 있다.
이 중 비교하는 일을 기타 스팩에게 위임해보자.
이유는? 어차피 Inventory의 search 메소드는 GuitarSpec를 참조해서 검색을 하고, 비교하고   일치하는 것이 있으면 보여주는 일을 하고 있다.
애초에 GuitarSpec에서 비교를 하고 맞다/틀리다만 알려주고
search의 코드는 맞는 제품만 보여준다면 코드량이 많이 줄어들 것이다.
그리고 GuitarSpec이 수정되거나 추가되어도 search는 수정할 일이 없어진다.

아래는 이것을 수정한 UML 이다.
GuitarSpec에 numString: Wood 와 getNumStrings(): Wood가 추가 되었다.
여기서 Wood는 기타 목록이 들어있는 열거형이다. 헷깔릴까봐 UML에서 뺐다 ㅡ.ㅡ

헤드퍼스트 OOAD 1강 -2단계-

지난번은 내가 생각해도 너무 날로 먹은 것 같아서 보충을 한다 ㅡㅡ;;(근데 누구 보라고 ㅡ.ㅡ?)

지금은 아래 단계중 2단계다.

1. 소프트웨어가 고객이 원하는 기능을 하도록 구현
2. 객체지향의 기본 원리를 적용해서 소프트웨어를 유연하게 하기
3. 유지보수와 재사용이 쉬운 디자인으로 만들기



먼저 전에 만들었던 UML을 보자

Guitar 클래스를 보니 무지하게 많은 변수와 매소드가 가득하다.
물론 변수와 매소드가 많다고 심각한 문제가 되지 않을수는 있다.
하지만 이런 클래스는 수정과 추가를 할 때 문제가 생긴다.
이 클래스에서 잘못 사용된 객체 타입을 찾는 법이 뭘까??

1. 객체는 자신의 이름이 나타내는 일을 해야한다. 
    즉, 객체는 어떤 공통된 분야에서의 일만 해야지 다른 분야의 일까지 해서는 안된다는 것
2. 각 객체는 하나의 개념을 나타내어야 한다.
    즉, 객체는 두 개이상의 임무를 해서는 안된다는 것이다.
3. 사용되지 않는 속성은 잘못 사용 중인 것이다.
    객체가 값이 없거나 null 속성들을 가진채로 사용되면
    객체가 하나 이상의 일을 하고 있을 가능성이 있다.

위를 참조해서 클래스를 수정해보자.



기존 기타 클래스에서 기타 스팩 클래스를 만들어서 기타 고유의 값만 빼고 옮겼다.
그리고 기타 클래스에서는 기타 스팩 클래스를 참조하도록 추가하였다.
그리고 인벤토리에서 search매소드가 GuitarSpec를 참조하도록 바꾸었다.
이렇게 함으로써 기타의 스팩이 바뀌어도 기타 고유의 클래스는 건드리지 않기에
캡슐화의 효과도 볼 수 있다.
이렇게 수정함으로써 2단계인 객체지향의 기본 원리로 소프트웨어를 유연하게 만들었다.

헤드퍼스트 OOAD 1강 -1단계-

1강이긴 한데 이 책의 특성상 어찌 기재를 해야할지 모르겠다.
일단 1강의 프로그램을 살펴 보자.

아래는 기타 검색 프로그램 1.0 버전의 UML 이다.


위 화면은 UML를 쉽게 만들어주는 프로그램을 이용한 화면이다.
다운 받는 곳 : http://staruml.sourceforge.net/ko/ 이다.


소스파일을 다운 받는 것이 이곳에 기재하는 것보다 쉽겠다 ㅡㅡ;;

1강 요약은 3줄로 요약된다.

1. 소프트웨어가 고객이 원하는 기능을 하도록 구현
2. 객체지향의 기본 원리를 적용해서 소프트웨어를 유연하게 하기
3. 유지보수와 재사용이 쉬운 디자인으로 만들기

1~3 번은 우선순위다.
그리고 주의점은 1번을 하는 중에 2번, 3번을 위해 설계를 바꾸지 말라는 것이다.
각 객체는 1가지 일만 하게 하는 것이 코드 재사용성과 수정에 용의하다는 것이다.

너무 대충 설명을 해놔서 뭔소리냐 이럴려면 꺼져라고 할지도 모르지만 ㅡㅡ;;
위에 링크한 소스파일을 보면 소스 코드의 변천사(?)를 보면 어찌 수정되었고 발전했는지 알 수 있을 것이다......;;; ㅌㅌㅌㅌ