D. 지뢰찾기 분석 설계 예제

169
D1 D. 지지지지 지지 지지 지지

description

D. 지뢰찾기 분석 설계 예제. 0. 지뢰찾기 분석. 분석의 목적. 시스템과 사용자 사이의 인터페이스를 정의 사용자 관점에서 인식할 수 있는 것만 정의한다 시스템 내부는 언급하지 않는다 사용자는 몰라도 되고 개발자만 알면 되는 것은 언급하지 않는다 여기서 언급한 사용자는 꼭 사람만을 의미하는 것은 아님 시스템과 명령이나 데이터를 주고 받는 것 시스템 내부가 아니고 외부 환경에 속하는 것. 분석 단계의 산출물 ( 중요도 순서로 나열됨 ). 1. Use-case 모델 - PowerPoint PPT Presentation

Transcript of D. 지뢰찾기 분석 설계 예제

Page 1: D.  지뢰찾기 분석 설계 예제

D1

D. 지뢰찾기 분석 설계 예제

Page 2: D.  지뢰찾기 분석 설계 예제

D2

0. 지뢰찾기 분석

Page 3: D.  지뢰찾기 분석 설계 예제

D3

분석의 목적• 시스템과 사용자 사이의 인터페이스를 정의

• 사용자 관점에서 인식할 수 있는 것만 정의한다

• 시스템 내부는 언급하지 않는다

• 사용자는 몰라도 되고 개발자만 알면 되는 것은 언급하지 않는다

• 여기서 언급한 사용자는 – 꼭 사람만을 의미하는 것은 아님– 시스템과 명령이나 데이터를 주고 받는 것– 시스템 내부가 아니고 외부 환경에 속하는 것

Page 4: D.  지뢰찾기 분석 설계 예제

D4

분석 단계의 산출물 ( 중요도 순서로 나열됨 )

1. Use-case 모델(Use-case Diagram + Use-case Specification)

2. 보충 요구사항 명세서 (Supplementary Requirement Specification)

3. 개념 모델 (Conceptual Level Class Diagram)

4. 화면 / 메뉴 설계

5. 개발계획

6. 기타 : 용어사전 , 사용자 메뉴얼

Page 5: D.  지뢰찾기 분석 설계 예제

D5

0-1. Use-case Model

Page 6: D.  지뢰찾기 분석 설계 예제

D6

Use-case Diagram

플레이어

지뢰찾기

닫힌 칸을 열기

지뢰를 표시

닫힌 칸들을 열기

Page 7: D.  지뢰찾기 분석 설계 예제

D7

앞의 Use-case 모델은 적절한가 ?• 무엇을 기준으로 판단할 것인가 ?

• 좋은 모델의 기준은 무엇인가 ?

Page 8: D.  지뢰찾기 분석 설계 예제

D8

좋은 모델의 기준은 ?• 좋은 모델은 정보의 전달이라는 목적에 충실해야 한다

– Use-case 모델이 고객에게 전달하는 정보 : 시스템을 이렇게 만들면 되나 ?

– Use-case 모델이 개발자에게 전달하는 정보 :이러한 시스템을 만들어라

• 전달해야 하는 정보를 빠짐 없이 포함해야 한다

• 이해하기 쉽고 간결해야 한다

Page 9: D.  지뢰찾기 분석 설계 예제

D9

빠진 Use-case 는 ?• 새 게임 시작하기 시나리오

• 초급 중급 고급 선택

• 색깔 소리 같은 옵션 지정

• 최고 기록 보기

• 위와 같은 것도 포함해야 하나 ?

Page 10: D.  지뢰찾기 분석 설계 예제

D10

Use-case Diagram 의 목적• Use-case Diagram -> 조감도 (Bird’s Eye View)

– 시스템이 제공하는 기능을 큰 단위로 표현한 것– 모든 세세한 기능을 Use-case Diagram 으로 표현하지 말라

• 세밀한 묘사는 다른 적당한 다이어그램에서 표현하면 된다

Page 11: D.  지뢰찾기 분석 설계 예제

D11

지뢰찾기의 Use-case ?• 지뢰찾기 게임이 사용자에게 제공하는 기능을 크게 분류하면 ?

Page 12: D.  지뢰찾기 분석 설계 예제

D12

Use-case Diagram

플레이어

지뢰찾기

닫힌 칸을 열기

지뢰를 표시

닫힌 칸들을 열기

Page 13: D.  지뢰찾기 분석 설계 예제

D13

Use-case Specification• 자세한 내용은 Use-case Specification 에서 설명한다

Page 14: D.  지뢰찾기 분석 설계 예제

D14

Use-case Specification• Name : 닫힌 칸을 열기

• Description:– 지뢰가 없을 것으로 짐작되는 칸을 연다

• Actor: 플레이어

• Precondition: – 칸은 닫혀있어야 한다– 지뢰 표시가 없는 칸이어야 한다

Page 15: D.  지뢰찾기 분석 설계 예제

D15

닫힌 칸을 열기• Main Flow

1. 지뢰가 없을 것으로 짐작되는 칸을 플레이어가 마우스 왼쪽 버튼으로 클릭한다

2. 칸은 열려진 상태로 표시되며 , 주변의 지뢰의 수가 칸 안에 표시된다

3. 주변의 지뢰의 수가 0 이면 • 지뢰 수 0 은 표시되지 않고• 주변의 닫힌 칸들이 모두 열려지며• 각 칸 안에 그 주변의 지뢰의 수가 표시된다 . • 이 과정은 재귀적으로 반복된다

Page 16: D.  지뢰찾기 분석 설계 예제

D16

닫힌 칸을 열기• Alternative Flow

A2. 지뢰가 있는 칸이었으면 지뢰가 폭발하여 게임은 실패로 종료된다

A2. 모든 칸이 열려졌으면 게임은 성공으로 종료된다

Page 17: D.  지뢰찾기 분석 설계 예제

D17

Use-case Specification• Name : 지뢰를 표시

• Description:– 지뢰가 있을 것으로 짐작되는 칸에 지뢰 표시를 한다

• Actor: 플레이어

• Precondition: – 칸은 닫혀있어야 한다

Page 18: D.  지뢰찾기 분석 설계 예제

D18

지뢰를 표시• Main Flow:

1. 지뢰가 있을 것으로 짐작되는 칸을 플레이어가 마우스 오른쪽 버튼으로 클릭한다

2. 칸에 지뢰 표시가 되고 , 남은 지뢰 수 표시가 1 감소한다 .

3. 지뢰 표시가 된 칸을 마우스 오른쪽 버튼으로 클릭한다

4. 칸에서 지뢰 표시가 제거되고 , 남은 지뢰 수 표시가 1 증가한다

Page 19: D.  지뢰찾기 분석 설계 예제

D19

지뢰를 표시• Notes:

– 지뢰 표시가 된 칸은 열 수가 없다" 닫힌 칸 열기 " 의 Precondition 참고

Page 20: D.  지뢰찾기 분석 설계 예제

D20

Use-case Specification• Name : 닫힌 칸들을 열기• Description:

– 인접한 지뢰가 모두 표시되었을 경우 , 지뢰가 없는 인접한 빈 칸을 모두 동시에 연다

• Actor: 플레이어

• Precondition: – 클릭하는 칸은 열려 있어야 한다– 열려진 칸에 표시된 주변 지뢰 수 만큼

주변 칸들에 지뢰 표시들이 있어야 한다

Page 21: D.  지뢰찾기 분석 설계 예제

D21

닫힌 칸들을 열기• Main Flow

1. 열려진 칸에서 마우스 왼쪽과 오른쪽 버튼을 동시에 클릭한다

2. 인접한 8개의 칸들 중 지뢰 표시가 되어 있지 않은 칸들 이 열려진다 . 열려진 각 칸들에는 인접한 지뢰의 수가 표시된다 .

3. 열려진 칸의 주변 지뢰의 수가 0 이면• 지뢰 수 0 은 표시되지 않고• 주변의 칸 모두 열려지며• 각 칸 안에 그 주변의 지뢰의 수가 표시된다 . • 이 과정은 재귀적으로 반복된다

Page 22: D.  지뢰찾기 분석 설계 예제

D22

닫힌 칸들을 열기• Alternative Flow

A2. 지뢰가 있는 칸이었으면 지뢰가 폭발하여 게임은 실패로 종료된다

A2. 모든 칸이 열려졌으면 게임은 성공으로 종료된다

Page 23: D.  지뢰찾기 분석 설계 예제

D23

0-2. 보충 요구사항

Page 24: D.  지뢰찾기 분석 설계 예제

D24

보충 요구사항• 모든 것을 Use-case 형태에 맞춰서 표현할 필요없다

• 사용자와 시스템 사이의 작업 시나리오 절차들은 Use-case 형태로 표현하는 것이 적당하다

• 기타 요구사항으로 표현하는 편이 더 단순한 것들도 있다

Page 25: D.  지뢰찾기 분석 설계 예제

D25

보충 요구사항

• 난이도– 초급 : 9 행 9 열의 칸 , 10 개의 지뢰– 중급 : 16 행 16 열의 칸 , 40 개의 지뢰– 고급 : 16 행 30 열의 칸 , 99개의 지뢰

• 화면에 남은 지뢰수가 표시된다– 남은 지뢰수 = 전체 지뢰 수 – 지뢰 표시의 수

• 화면에 초시계가 표시된다– 첫 칸을 연 때부터 초시계가 시작하고– 성공하거나 실패한 순간 초시계가 정지한다

• 난이도 별로 최단시간 성공 기록을 유지한다

Page 26: D.  지뢰찾기 분석 설계 예제

D26

0-3. 개념모델 (Conceptual Model)

Page 27: D.  지뢰찾기 분석 설계 예제

D27

개념모델• Use-case 모델의 이해를 돕기 위해 작성

• Use-case 모델에 등장하는 개념들의 관계를 표현한다

• 용어 사전과 비슷한 역할을 한다

Page 28: D.  지뢰찾기 분석 설계 예제

D28

지뢰찾기의 개념모델• 개념모델의 목적은 시스템 설계가 아니고 관련 개념의 이해이다

– 모듈 설계와 다르다

• 다음의 개념들을 이해하기 쉽게 표현하기 위한 모델이다– 지뢰 , 이웃칸 , 지뢰표시 , 칸의 상태 …

• 사용자와 개발자들이 위 개념들을 잘 알고 있다면 , 개념모델은 생략 가능하다– 지뢰 찾기의 경우 사실 개념 모델은 필요없다

• 금융 정보시스템을 개발하는 경우라면 , 관련 개념들이 이해하기 매우 어려울 것이므로 개념모델이 꼭 필요할 것이다 .

Page 29: D.  지뢰찾기 분석 설계 예제

D29

지뢰찾기의 개념모델

+cellState : CellState+/nearbyMineCount : int

Cell+rowCount : int+columnCount : int

Minefield

1 *

Mine

1

0..1

Flag

1

0..1

+CLOSED+OPENED

<<enumeration>>CellState

3,5,8

+neighbor

3,5,8

Page 30: D.  지뢰찾기 분석 설계 예제

D30

0-4. 화면 / 메뉴 설계

Page 31: D.  지뢰찾기 분석 설계 예제

D31

화면설계

진행화면 성공 실패

Page 32: D.  지뢰찾기 분석 설계 예제

D32

메뉴설계

Page 33: D.  지뢰찾기 분석 설계 예제

D33

0-5. 개발 계획

Page 34: D.  지뢰찾기 분석 설계 예제

D34

점진적 개발• 크고 복잡한 시스템을 한 번에 완성하는 것은 매우 어렵다

– 작게 쪼개어 하나씩 만들어 가는 것이 좋다

• Use-case 단위로 만들어 나간다– 중요한 Use-case 를 먼저 선택하여 – 설계 , 구현 , 테스트하여 완성하고 – 그 다음 Use-case 를 선택하여 만들어 나간다

Page 35: D.  지뢰찾기 분석 설계 예제

D35

Use-case 단위로 점진적 개발 • Use-case 의 우선순위 별로 점진적 개발

1. 닫힌 칸을 열기 2. 지뢰를 표시3. 닫힌 칸들을 열기

• 1차 개발– 닫힌 칸을 열기

• 2차 개발– 지뢰를 표시– 닫힌 칸들을 열기

Page 36: D.  지뢰찾기 분석 설계 예제

D36

1-1. 1차개발 : 분석

Page 37: D.  지뢰찾기 분석 설계 예제

D37

1차개발 개요• 가장 중요한 use-case 인 " 닫힌 칸을 열기 " 를 구현한다

• 1차개발의 완료는 빠르면 빠를 수록 좋다– 실행하고 테스트 해 볼 수 있는 1차 버전은 , 고객으로부터

요구사항 수집하는데 , 개발자가 시스템을 이해하고 개발하는데 , 아주 큰 도움이 된다

• 1차개발을 빠르게 완료하기 위하여 , use-case 를 단순하게 수정하고 구현하는 것도 좋다 .– 단순하게 수정된 내용은 2차 개발에서 보충 구현한다 .

Page 38: D.  지뢰찾기 분석 설계 예제

D38

1-1-1. Use-case 모델

Page 39: D.  지뢰찾기 분석 설계 예제

D39

Use Case Diagram

플레이어

지뢰찾기

닫힌 칸을 열기

지뢰를 표시

닫힌 칸들을 열기

Page 40: D.  지뢰찾기 분석 설계 예제

D40

Use Case Specification ( 단순화됨 )• Name : 닫힌 칸을 열기

• Description:– 지뢰가 없을 것으로 짐작되는 칸을 연다

• Actor: 플레이어

• Precondition: – 칸은 닫혀있어야 한다

Page 41: D.  지뢰찾기 분석 설계 예제

D41

닫힌 칸을 열기• Main Flow

1. 지뢰가 없을 것으로 짐작되는 칸을 플레이어가 마우스 왼쪽 버튼으로 클릭한다

2. 칸은 열려진 상태로 표시되며 , 주변의 지뢰의 수가 칸 안에 표시된다

Page 42: D.  지뢰찾기 분석 설계 예제

D42

닫힌 칸을 열기• Alternative Flow

A2. 지뢰가 있는 칸이었으면 지뢰가 폭발하여 게임은 실패로 종료된다

A2. 모든 칸이 열려졌으면 게임은 성공으로 종료된다

Page 43: D.  지뢰찾기 분석 설계 예제

D43

1-1-2. 보충 요구사항

Page 44: D.  지뢰찾기 분석 설계 예제

D44

보충 요구사항

• 난이도– 초급 : 9 행 9 열의 칸 , 10 개의 지뢰

Page 45: D.  지뢰찾기 분석 설계 예제

D45

1-1-3. 화면 설계

Page 46: D.  지뢰찾기 분석 설계 예제

D46

화면설계

진행화면

성공하거나 실패했을 경우위와 같은 대화상자가 출력된다

Page 47: D.  지뢰찾기 분석 설계 예제

D47

메뉴설계

Page 48: D.  지뢰찾기 분석 설계 예제

D48

1-2. 1차개발 : 아키텍처 설계

Page 49: D.  지뢰찾기 분석 설계 예제

D49

아키텍처 설계의 목적• 주요 클래스 사이의 인터페이스를 정의

– 시스템을 몇 개의 주요 클래스로 나누고 – 그들 사이의 인터페이스를 정의한다

• 주요 클래스 사이의 상호작용만 정의한다

• 주요 클래스 내부는 언급하지 않는다– 주요 클래스 내부는 상세 설계 단계에서

• 설계에서 아키텍처 설계 단계가 가장 중요하다

Page 50: D.  지뢰찾기 분석 설계 예제

D50

아키텍처 설계의 산출물 ( 중요도 순서로 나열됨 )

1. Class Diagram– 주요 클래스를 그린 클래스 다이어그램 – Specification Level Class Diagram

2. Sequence Diagram– 주요 클래스 사이의 상호 작용을 설계– Specification Level Sequence Diagram– Use-case specification 에서 주요 이벤트 각각에 대하여 seque

nce diagram 이 그려져야 한다

3. Activity Diagram or Statechart Diagram

Page 51: D.  지뢰찾기 분석 설계 예제

D51

작업 1: 주요 클래스 식별• 시스템을 주요 클래스로 나눈다

• 시스템을 주요 클래스로 잘 나누는 것은 설계자의 경험과 능력에 의존한다

• 클래스는 단순하게 요약 설명될 수 있는 분명한 역할이 있어야 한다

• 클래스들 사이의 관계는 상호 의존성이 낮을 수록 좋다

• 개념 설계의 클래스가 아키텍처 설계의 주요 클래스가 되어야 하는 것은 아니다– 그럴 수도 있고 아닐 수도 있다

Page 52: D.  지뢰찾기 분석 설계 예제

D52

아키텍처• MVC 구조

– 문서 중심 어플리케이션의 설계에 적합함 예 : 워드프레세서 , 그래픽 에디터

– Model : 어플리케이션의 주요 데이터를 담당– View : 사용자 인터페이스를 담당– Controller : 처리 절차를 담당

• 3 계층 구조– 데이터베이스 기반 정보 시스템 설계에 적합함– Presentation 계층 : 사용자 인터페이스를 담당– Business Logic 계층 : 업무 로직을 담당– Data 계층 : 데이터를 담당

Page 53: D.  지뢰찾기 분석 설계 예제

D53

주요 클래스와 모듈• 주요 클래스는 모듈을 대표한다

• 모듈 내부에서만 접근되는 여러 클래스들이 있을 것이다

주요 클래스 1

내부 클래스 1

내부 클래스 2

주요 클래스 2 내부 클래스 3

내부 클래스 4

모듈

Page 54: D.  지뢰찾기 분석 설계 예제

D54

모듈간 상호의존성• 여러 모듈이 공통으로 접근하는 자료구조가 있으면 안됨

자료구조

모듈 1주요 로직자료구조 처리 로직

모듈 3주요 로직자료구조 처리 로직

모듈 2주요 로직자료구조 처리 로직

Page 55: D.  지뢰찾기 분석 설계 예제

D55

Abstract Data Type• 바람직한 구조

모듈 1주요 로직

모듈 3주요 로직

모듈 2주요 로직

자료구조

ADT자료구조 처리로직

Page 56: D.  지뢰찾기 분석 설계 예제

D56

Abstract Data Type• 자료구조 + 함수

• 함수는 자료구조에 직접 접근해야 하는 처리 로직을 구현 한 것

• 외부에서는 자료구조에 직접 접근할 수 없고 이 함수만 호출할 수 있다

• 외부에 자료구조는 노출되지 않는다 (encapsulation)

• ADT 개념을 확장한 것이 객체지향 언어의 Class

Page 57: D.  지뢰찾기 분석 설계 예제

D57

주요 모듈의 크기• 주요 모듈이란 일종의 서브시스템 (subsystem) 을 말한다

• 주요 모듈의 크기는 한 사람이 상세 설계 및 구현을 담당하기에 적당한 크기

• 너무 작고 세밀하게 나누지 말라

• 자세한 것은 상세설계 단계에서 설계한다

Page 58: D.  지뢰찾기 분석 설계 예제

D58

작업 1: 주요 클래스 식별• 지뢰찾기는 비교적 단순한 로직이므로 주요 클래스도 단순하다

• Minesweeper : 게임 로직을 담당

• UI : 사용자 인터페이스를 담당

Minesweeper UI

Page 59: D.  지뢰찾기 분석 설계 예제

D59

작업 2: 시스템 내부 절차 식별• Use-case specification 의 절차를 수행하기 위해 시스템 내부에서

수행해야 하는 일을 순서대로 적는다

• 너무 자세하면 안되고 주요 아키텍처 수준의 절차이어야 한다

Page 60: D.  지뢰찾기 분석 설계 예제

D60

닫힌 칸을 열기 use-case• Main Flow

1. 지뢰가 없을 것으로 짐작되는 칸을 플레이어가 마우스 왼쪽 버튼으로 클릭한다

2. 칸은 열려진 상태로 표시되며 , 주변의 지뢰의 수가 칸 안에 표시된다

Page 61: D.  지뢰찾기 분석 설계 예제

D61

닫힌 칸을 열기 use-case• Alternative Flow

A2. 지뢰가 있는 칸이었으면 지뢰가 폭발하여 게임은 실패로 종료된다

A2. 모든 칸이 열려졌으면 게임은 성공으로 종료된다

Page 62: D.  지뢰찾기 분석 설계 예제

D62

닫힌 칸을 열기 절차1. 지뢰가 없을 것으로 짐작되는 칸을 플레이어가 마우스 왼쪽

버튼으로 클릭한다a. 마우스 입력을 받는다b. 눌려진 칸을 찾는다

2. 칸은 열려진 상태로 표시되며 , 주변의 지뢰의 수가 칸 안에 표시된다c. 칸을 열린 상태로 바꾼다d. 주변 지뢰 수를 계산한다e. 주변 지뢰수와 칸의 상태를 그린다

Page 63: D.  지뢰찾기 분석 설계 예제

D63

닫힌 칸을 열기 절차• Alternative Flow

A2. 지뢰가 있는 칸이었으면 지뢰가 폭발하여 게임은 실패로 종료된다

c-1. 지뢰가 있는 칸이면 게임 실패c-2. 게임실패 메시지를 출력하고 게임종료

A2. 모든 칸이 열려졌으면 게임은 성공으로 종료된다e-1. 모든 칸이 열려졌으면 게임성공e-2. 게임성공 메시지를 출력하고 게임종료

Page 64: D.  지뢰찾기 분석 설계 예제

D64

작업 3: 클래스에 역할 할당• UI

a. 마우스 입력을 받는다b. 눌려진 칸을 찾는다e. 주변 지뢰수와 칸의 상태를 그린다c-2. 게임실패 메시지를 출력하고 게임종료e-2. 게임성공 메시지를 출력하고 게임종료

• Minesweeper c. 칸을 열린 상태로 바꾼다d. 주변 지뢰 수를 계산한다c-1. 지뢰가 있는 칸이면 게임 실패e-1. 모든 칸이 열려졌으면 게임성공

Page 65: D.  지뢰찾기 분석 설계 예제

D65

작업 4: 역할을 메소드에 할당• UI

– OnLBottonDowna. 마우스 입력을 받는다b. 눌려진 칸을 찾는다

– DrawGamee. 주변 지뢰수와 칸의 상태를 그린다

– GameFailurec-2. 게임실패 메시지를 출력하고 게임종료

– GameSuccesse-2. 게임성공 메시지를 출력하고 게임종료

Page 66: D.  지뢰찾기 분석 설계 예제

D66

작업 4: 역할을 메소드에 할당• Minesweeper

– OpenCellc. 칸을 열린 상태로 바꾼다c-1. 지뢰가 있는 칸이면 게임 실패e-1. 모든 칸이 열려졌으면 게임성공

– GetAdjacentMineCountd. 주변 지뢰 수를 계산한다

Page 67: D.  지뢰찾기 분석 설계 예제

D67

작업 5: 메소드 보완• 필요한 메소드를 추가한다

• Sequence diagram 을 그려보는 것이 바람직하다

• 상호작용을 가능한 단순하게 만든다

Page 68: D.  지뢰찾기 분석 설계 예제

D68

Player

:Minesweeper:UI

OnLButtonDown(x,y)OpenCell(row,col)

GameFailure()[지뢰가 있는 칸이면]

GameSuccess()[모든 칸이 열려졌으면]

DrawGame()

GetAdjacentMineCount(row,col)

Page 69: D.  지뢰찾기 분석 설계 예제

D69

작업 5: 메소드 보완• 꼭 필요한 절차가 빠졌다

• 무엇이 빠졌는가 ?– 구현해 볼 때까지는 알 수 없나 ?

• 시퀀스 다이어그램으로 꼼꼼히 시뮬레이션 하면서 빠진 절차를 밝혀 내야 한다

Page 70: D.  지뢰찾기 분석 설계 예제

D70

+OnLButtonDown(in x : int, in y : int)+DrawGame()+GameFailure()+GameSuccess()

UI

+OpenCell(in row : int, in col : int)+GetAdjacentMineCount(in row : int, in col : int) : int

Minesweeper

Page 71: D.  지뢰찾기 분석 설계 예제

D71

작업 5: 메소드 보완• UI 가 칸의 상태를 그리려면 Minesweeper 로부터 상태값을

받아와야 한다

• Minesweeper 가 UI 의 DrawGame() 을 호출할 필요가 없다– 칸을 연 후 다시 그려야 하는 것은 당연하다– UI 가 Minesweeper 의 OpenCell() 을 호출한 후

스스로 DrawGame() 을 호출하면 된다

• 성공과 실패 여부를 UI 가 Minesweeper 로부터 얻어가도록 수정– 호출이 단방향일 수 있다면 구조가 더 단순해진다

Page 72: D.  지뢰찾기 분석 설계 예제

D72

: UI : Minesweeper

OnLButtonDown(x, y)OpenCell(row, col)

IsSuccess()

IsFailure()

DrawGame()

GetCellState(row, col)

GetAdjacentMineCount(row, col)

Page 73: D.  지뢰찾기 분석 설계 예제

D73

작업 5: 메소드 보완• 초기화 / 마무리 메소드를 추가한다

Page 74: D.  지뢰찾기 분석 설계 예제

D74

: UI : Minesweeper

OnNewGame()InitGame(rowCnt, colCnt, mineCnt)

DrawGame()

Page 75: D.  지뢰찾기 분석 설계 예제

D75

작업 6: 클래스 다이어그램

+OnNewGame()+OnLButtonDown(in x : int, in y : int)+DrawGame()

UI

+InitGame(in rowCnt : int, in colCnt : int, in mineCnt : int)+OpenCell(in row : int, in col : int)+IsSuccess()+IsFailure()+GetCellState(in row : int, in col : int) : CellState+GetAdjacentMineCount(in row : int, in col : int) : int

Minesweeper

+OPENED+CLOSED

<<enumeration>>CellState

Page 76: D.  지뢰찾기 분석 설계 예제

D76

1-3. 1차개발 : 상세 설계

Page 77: D.  지뢰찾기 분석 설계 예제

D77

1-3-1. 1차개발 : Minesweeper 상세설계

Page 78: D.  지뢰찾기 분석 설계 예제

D78

상세 설계• 주요 클래스 내부 로직을 설계한다

– 아키텍처 설계에서 주요 클래스의 메소드 목록이 정의되었다– 주요 클래스의 메소드들의 내부 로직을 설계한다

• 주요 클래스 내부에서 사용될 내부 클래스들을 식별한다

• 내부 클래스에 역할을 할당한다

• 주요 클래스의 메소드 각각에 대하여 시퀀스 다이어그램이 그려져야 한다

Page 79: D.  지뢰찾기 분석 설계 예제

D79

작업 1: 내부 클래스 식별• 개념 모델을 참고하여 내부 클래스를 만든다

• 개념 모델의 클래스가 주요 클래스나 내부 클래스가 아닐 수 있다

Page 80: D.  지뢰찾기 분석 설계 예제

D80

+cellState : CellState+/nearbyMineCount : int

Cell+rowCount : int+columnCount : int

Minefield

1 *

Mine

1

0..1+CLOSED+OPENED

<<enumeration>>CellState

3,5,8

+neighbor

3,5,8

+InitGame(in rowCnt : int, in colCnt : int, in mineCnt : int)+OpenCell(in row : int, in col : int)+IsSuccess() : bool+IsFailure() : bool+GetCellState(in row : int, in col : int) : CellState+GetAdjacentMineCount(in row : int, in col : int) : int

Minesweeper

1

1

Page 81: D.  지뢰찾기 분석 설계 예제

D81

작업 2: 클래스에 역할 할당• Minesweeper : 지뢰찾기 게임의 로직을 담당

– 게임 성공과 실패를 판단– 칸을 열 수 있는 지 없는 지를 판단– 주변의 모든 칸도 저절로 열려야 하는 지 판단 ( 이 기능은 현재

반복에서 구현하지 않는다 )

• Minefield : 자료구조를 담당– 칸 , 지뢰 , 깃발의 목록 자료구조 – 게임의 로직과 자료구조를 분리

• Cell : 칸 ADT– 자료구조는 가능한 노출되지 않는 편이 좋다

• Mine: 지뢰 ADT

Page 82: D.  지뢰찾기 분석 설계 예제

D82

작업 3: 상세로직 시퀀스 다이어그램• 주요 클래스의 메소드 각각에 대하여 시퀀스 다이어그램을 그린다

– Minesweeper 모듈의 주요 클래스는 Minesweeper – Minesweeper 클래스의 메소드 각각에 대하여

상세로직 시퀀스 다이어그램을 그린다

• 상세로직 시퀀스 다이어그램을 그리면서– 내부 클래스에 할당된 역할에 따라

내부 클래스에 메소드를 만든다

Page 83: D.  지뢰찾기 분석 설계 예제

D83

: UI : Minesweeper : Minefield : Cel mine : Mine

InitGame(rowCnt, colCnt, mineCnt)

InitMinefield(rowCnt, colCnt, mineCnt)

Cell()

Mine()

PutMine(mine)

Page 84: D.  지뢰찾기 분석 설계 예제

D84

: UI : Minesweeper : Minefield cell : Cell

GetCellState(row, col)

cell:=GetCell(row, col)

state:=GetState()

state

Page 85: D.  지뢰찾기 분석 설계 예제

D85

: UI : Minesweeper : Minefield cell : Cell

OpenCell(row, col)

cell:=GetCell(row, col)

GetState()

Open()

IsMined()

AreAllMinesFound()

Page 86: D.  지뢰찾기 분석 설계 예제

D86

: UI : Minesweeper : Minefield cell : Cell

cell:=GetCell(row, col)

IsMined()

GetAdjacentMineCount(row, col)

Page 87: D.  지뢰찾기 분석 설계 예제

D87

작업 4: 클래스 다이어그램• 시퀀스 다이어그램을 그리며 만든 메소드를 클래스 다이어그램으로

정리한다

Page 88: D.  지뢰찾기 분석 설계 예제

D88

+Cell()+PutMine(in mine : Mine)+GetState() : CellState+IsMined() : bool+Open()

Cell

+InitMinefield(in rowCnt : int, in colCnt : int, in mineCnt : int)+GetCell(in row : int, in col : int) : Cell+AreAllMinesFound() : bool

Minefield

1

*

+Mine()

Mine

1

0..1

+CLOSED+OPENED

<<enumeration>>CellState

3,5,8

+neighbor

3,5,8

+InitGame(in rowCnt : int, in colCnt : int, in mineCnt : int)+OpenCell(in row : int, in col : int)+IsSuccess() : bool+IsFailure() : bool+GetCellState(in row : int, in col : int) : CellState+GetAdjacentMineCount(in row : int, in col : int) : int

Minesweeper

1

1

Page 89: D.  지뢰찾기 분석 설계 예제

D89

작업 5: 클래스 다이어그램 보완• Mine 클래스는 메소드가 없다 . 부여된 역할이 없다

• Cell 에 Mine 이 있는지 없는지 나타내는 bool 형의 멤버 변수 하나면 족하다

• Minefield 자료구조를 2차원 배열 자료구조로 만들면 neighbor 연관을 구현할 필요 없다

• GetAdjacentMineCount() 는 게임로직이라기 보다는 Minefield 자료구조에 대한 검색에 가깝다– Minefield 클래스에서 구현

Page 90: D.  지뢰찾기 분석 설계 예제

D90

+Cell()+PutMine(in mine : Mine)+GetState() : CellState+IsMined() : bool+Open()

Cell

+InitMinefield(in rowCnt : int, in colCnt : int, in mineCnt : int)+GetCell(in row : int, in col : int) : Cell+AreAllMinesFound() : bool+GetAdjacentMineCount(in row : int, in col : int) : int

Minefield

1

*

+CLOSED+OPENED

<<enumeration>>CellState

+InitGame(in rowCnt : int, in colCnt : int, in mineCnt : int)+OpenCell(in row : int, in col : int)+IsSuccess() : bool+IsFailure() : bool+GetCellState(in row : int, in col : int) : CellState+GetAdjacentMineCount(in row : int, in col : int) : int

Minesweeper

1

1

Page 91: D.  지뢰찾기 분석 설계 예제

D91

작업 6: 시퀀스 다이어그램 보완• 변경된 클래스 다이어그램에 따라 시퀀스 다이어그램을 보완한다

Page 92: D.  지뢰찾기 분석 설계 예제

D92

: UI : Minesweeper : Minefield : Cell

InitGame(rowCnt, colCnt, mineCnt)

InitMinefield(rowCnt, colCnt, mineCnt)

Cell()

PutMine(mine)

Page 93: D.  지뢰찾기 분석 설계 예제

D93

: UI : Minesweeper : Minefield cell : Cell

GetAdjacentMineCount(row, col)

IsMined()

GetAdjacentMineCount(row, col)

cell:=GetCell(row, col)

Page 94: D.  지뢰찾기 분석 설계 예제

D94

1-3-2. 1차개발 : UI 상세 설계

Page 95: D.  지뢰찾기 분석 설계 예제

D95

UI 상세 설계는 생략• UI 상세 설계는 구현될 플랫폼의 UI 기술에 크게 의존한다

• 여기서는 Microsoft Visual C++ MFC 로 구현한다

Page 96: D.  지뢰찾기 분석 설계 예제

D96

+OnGameNew()+DrawGame()+OnLButtonDown()

-minesweeper : MinesweeperUI

+InitGame(in rowCnt : int, in colCnt : int, in mineCnt : int)+OpenCell(in row : int, in col : int)+IsSuccess() : bool+IsFailure() : bool+GetCellState(in row : int, in col : int) : CellState+GetAdjacentMineCount(in row : int, in col : int) : int

Minesweeper

Page 97: D.  지뢰찾기 분석 설계 예제

D97

1-4. 1차개발 : 테스트 구현

Page 98: D.  지뢰찾기 분석 설계 예제

D98

UI 테스트 구현• 다음과 같은 Minefield 를 구현하여 UI 를 테스트한다

Page 99: D.  지뢰찾기 분석 설계 예제

D99

UI 테스트 데이터 구현• 지뢰

1

1

1 1

1 1

1

1 1 1

Page 100: D.  지뢰찾기 분석 설계 예제

D100

UI 테스트 데이터 구현• 주변 지뢰 수

1 2 1 0 0 0 0 0

1 2 1 0 0 0 0 0

1 1 2 2 2 1 0 0 0

0 0 2 1 1 1 1

0 0 2 3 1 1 1

0 0 1 1 1 0 1 1 1

0 1 1 1 0 0 0 0 0

1 2 1 0 1 2 2 1

1 2 1 0 1 1

Page 101: D.  지뢰찾기 분석 설계 예제

D101

model.h#ifndef MINESWEEPER_H#define MINESWEEPER_H

enum CellState {CLOSED = 0,OPENED = 1

};

class Minesweeper {public:

void InitGame(int rowCnt, int colCnt, int mineCnt);void OpenCell(int row, int col);bool IsSuccess();bool IsFailure();CellState GetCellState(int row, int col);int GetAdjacentMineCount(int row, int col);

};

#endif

Page 102: D.  지뢰찾기 분석 설계 예제

D102

model.cpp#include <stdafx.h>#include <assert.h>#include "model.h"

static char mine[9][9] = { 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 1, 0};

static char adjacentMineCnt[9][9] = { 1, 2, 0, 1, 0, 0, 0, 0, 0, 1, 0, 2, 1, 0, 0, 0, 0, 0, 1, 1, 2, 2, 2, 1, 0, 0, 0, 0, 0, 2, 0, 0, 1, 1, 1, 1, 0, 0, 2, 0, 3, 1, 1, 0, 1, 0, 0, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 0, 0, 0, 0, 0, 1, 2, 0, 1, 0, 1, 2, 2, 1, 1, 0, 2, 1, 0, 1, 0, 0, 1};

Page 103: D.  지뢰찾기 분석 설계 예제

D103

static char opened[9][9] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};

void Minesweeper::InitGame(int rowCnt, int colCnt, int mineCnt) {memset(opened, 0, sizeof(char) * 9 * 9);

}

void Minesweeper::OpenCell(int row, int col) {assert( 0 <= row && row < 9 );assert( 0 <= row && col < 9 );opened[row][col] = 1;

}

bool Minesweeper::IsSuccess() {for (int r = 0; r < 9; ++r)for (int c = 0; c < 9; ++c)

if (!opened[r][c] && !mine[r][c]) return false;return true;

}

Page 104: D.  지뢰찾기 분석 설계 예제

D104

bool Minesweeper::IsFailure() {for (int r = 0; r < 9; ++r)for (int c = 0; c < 9; ++c)

if (opened[r][c] && mine[r][c]) return true;return false;

}

CellState Minesweeper::GetCellState(int row, int col) {assert( 0 <= row && row < 9 );assert( 0 <= row && col < 9 );if (opened[row][col]) return OPENED;return CLOSED;

}

int Minesweeper::GetAdjacentMineCount(int row, int col) {assert( 0 <= row && row < 9 );assert( 0 <= row && col < 9 );return adjacentMineCnt[row][col];

}

Page 105: D.  지뢰찾기 분석 설계 예제

D105

Model 테스트 구현• UI 를 텍스트 모드로 구현한다

Page 106: D.  지뢰찾기 분석 설계 예제

D106

UI.c#include <stdio.h>#include "model.h"

Minesweeper game;

void help() { printf("o 6 3 -> 6 행 3 열의 사각형을 열기 \n"); printf("h -> 도움말 \n"); printf("x -> 게임 종료 \n"); printf("\n\n");}

void showMinefield() { int row, col; printf(" "); for (col = 0; col < 9; ++col) printf(" %d ", col); for (row = 0; row < 9; ++row) { printf("\n %d ", row); for (col = 0; col < 9; ++col) if (game.GetCellState(row, col) == CLOSED) printf(" . "); else { int n = game.GetAdjacentMineCount(row, col); if (n == 0) printf(" "); else printf(" %d ", n); } } printf("\n\n>");}

Page 107: D.  지뢰찾기 분석 설계 예제

D107

void main() { char s[80]; int r, c;

game.InitGame(9, 9, 10); help(); for (;;) { showMinefield(); gets(s); switch(s[0]) { case 'o': case 'O': sscanf(s+1, "%d %d", &r, &c); game.OpenCell(r, c); if (game.IsSuccess()) { puts("You Win"); return; } if (game.IsFailure()) { puts("Game Over"); return; } break; case 'h': case 'H': help(); break; case 'q': case 'Q': return; }; }}

Page 108: D.  지뢰찾기 분석 설계 예제

D108

2-1. 2차개발 분석

Page 109: D.  지뢰찾기 분석 설계 예제

D109

개요• " 닫힌 칸을 열기 " 구현 보완

• " 지뢰를 표시 " 구현

Page 110: D.  지뢰찾기 분석 설계 예제

D110

2-1-1. Use-case Model

Page 111: D.  지뢰찾기 분석 설계 예제

D111

Use Case Diagram

플레이어

지뢰찾기

닫힌 칸을 열기

지뢰를 표시

닫힌 칸들을 열기

Page 112: D.  지뢰찾기 분석 설계 예제

D112

Use Case Specification• Name : 닫힌 칸을 열기

• Description:– 지뢰가 없을 것으로 짐작되는 칸을 연다

• Actor: 플레이어

• Precondition: – 칸은 닫혀있어야 한다– 지뢰 표시가 없는 칸이어야 한다

Page 113: D.  지뢰찾기 분석 설계 예제

D113

닫힌 칸을 열기• Main Flow

1. 지뢰가 없을 것으로 짐작되는 칸을 플레이어가 마우스 왼쪽 버튼으로 클릭한다

2. 칸은 열려진 상태로 표시되며 , 주변의 지뢰의 수가 칸 안에 표시된다

3. 주변의 지뢰의 수가 0 이면 • 지뢰 수 0 은 표시되지 않고• 주변의 닫힌 칸들이 모두 열려지며• 각 칸 안에 그 주변의 지뢰의 수가 표시된다 . • 이 과정은 재귀적으로 반복된다

Page 114: D.  지뢰찾기 분석 설계 예제

D114

닫힌 칸을 열기• Alternative Flow

A2. 지뢰가 있는 칸이었으면 지뢰가 폭발하여 게임은 실패로 종료된다

A2. 모든 칸이 열려졌으면 게임은 성공으로 종료된다

Page 115: D.  지뢰찾기 분석 설계 예제

D115

Use Case Specification• Name : 지뢰를 표시

• Description:– 지뢰가 있을 것으로 짐작되는 칸에 지뢰 표시를 한다

• Actor: 플레이어

• Precondition: – 칸은 닫혀있어야 한다

Page 116: D.  지뢰찾기 분석 설계 예제

D116

지뢰를 표시• Main Flow:

1. 지뢰가 있을 것으로 짐작되는 칸을 플레이어가 마우스 오른쪽 버튼으로 클릭한다

2. 칸에 지뢰 표시가 되고 , 남은 지뢰 수 표시가 1 감소한다 .

3. 지뢰 표시가 된 칸을 마우스 오른쪽 버튼으로 클릭한다

4. 칸에서 지뢰 표시가 제거되고 , 남은 지뢰 수 표시가 1 증가한다

Page 117: D.  지뢰찾기 분석 설계 예제

D117

지뢰를 표시• Notes:

– 지뢰 표시가 된 칸은 열 수가 없다" 닫힌 칸 열기 " 의 Precondition 참고

Page 118: D.  지뢰찾기 분석 설계 예제

D118

2-1-2. 보충 요구사항

Page 119: D.  지뢰찾기 분석 설계 예제

D119

보충 요구사항

• 변화 없음

Page 120: D.  지뢰찾기 분석 설계 예제

D120

2-1-3. 화면 / 메뉴 설계

Page 121: D.  지뢰찾기 분석 설계 예제

D121

화면 / 메뉴 설계

Page 122: D.  지뢰찾기 분석 설계 예제

D122

2-2. 2차개발 설계

Page 123: D.  지뢰찾기 분석 설계 예제

D123

개요• 2차 개발에서 추가된 기능을 설계 구현한다

• 1차 개발에서 설계 구현된 것을 수정한다

• 얼마나 수정되어야 하는가 ?

• 1차 개발의 설계가 우수했다면– 변경은 적을 것이고– 주로 기능 추가일 것이다

• 만약 크게 변경되어야 한다면 – 1차 개발의 설계가 무엇이 잘못되었는지 분석 반성하여야 한다– 반성의 결과는 바람직한 설계 지침으로 정리되어야 함

Page 124: D.  지뢰찾기 분석 설계 예제

D124

작업 1: 시스템 내부 절차 식별• 추가된 Use-case specification 의 절차를 수행하기 위해 시스템

내부에서 수행해야 하는 일을 순서대로 적는다

Page 125: D.  지뢰찾기 분석 설계 예제

D125

닫힌 칸을 열기 use-case• Main Flow

1. 지뢰가 없을 것으로 짐작되는 칸을 플레이어가 마우스 왼쪽 버튼으로 클릭한다

2. 칸은 열려진 상태로 표시되며 , 주변의 지뢰의 수가 칸 안에 표시된다

3. 주변의 지뢰의 수가 0 이면 • 지뢰 수 0 은 표시되지 않고• 주변의 닫힌 칸들이 모두 열려지며• 각 칸 안에 그 주변의 지뢰의 수가 표시된다 . • 이 과정은 재귀적으로 반복된다

Page 126: D.  지뢰찾기 분석 설계 예제

D126

주변 지뢰 수 0 일 때의 절차• 주변의 닫힌 칸들을 모두 연다

• 이미 구현된 Minesweeper.OpenCell(int row, int col) 메소드를 호출하여 주변의 닫힌 칸들을 모두 연다

• 재귀적으로 구현한다

Page 127: D.  지뢰찾기 분석 설계 예제

D127

지뢰를 표시 use-case• Main Flow:

1. 지뢰가 있을 것으로 짐작되는 칸을 플레이어가 마우스 오른쪽 버튼으로 클릭한다

2. 칸에 지뢰 표시가 되고 , 남은 지뢰 수 표시가 1 감소한다 .

3. 지뢰 표시가 된 칸을 마우스 오른쪽 버튼으로 클릭한다

4. 칸에서 지뢰 표시가 제거되고 , 남은 지뢰 수 표시가 1 증가한다

Page 128: D.  지뢰찾기 분석 설계 예제

D128

지뢰를 표시 절차a. 오른쪽 버튼의 입력을 받는다 (UI)b. 눌려진 칸을 찾는다 (UI)c. 칸에 지뢰 표시를 토글한다 (Minesweeper)

Page 129: D.  지뢰찾기 분석 설계 예제

D129

칸의 상태• Opened, Closed, Mined, Flaged

• Cell 의 상태 메소드 정리– bool IsOpened();– bool IsMined();– bool IsFlaged();

• Minesweeper 의 상태 메소드 정리– bool IsOpened();– bool IsMined();– bool IsFlaged();

Page 130: D.  지뢰찾기 분석 설계 예제

D130

작업 2: 시퀀스 다이어그램으로 설계 : UI : Minesweeper : Minefield cell : Cell

OpenCell(row, col)

cell:=GetCell(row, col)

IsFlaged()

IsOpened()

IsMined()

OpenAdjacentCells(row, col)

AreAllMinesFound()

Open()

GetAdjacentMineCount(row, col)

Page 131: D.  지뢰찾기 분석 설계 예제

D131

: UI : Minesweeper

OpenAdjacentCells(row, col)

OpenCell(row, col)

Page 132: D.  지뢰찾기 분석 설계 예제

D132

: UI : Minesweeper : Minefield cell : Cell

FlagCell(row, col)

cell:=GetCell(row, col)

IsFlaged()

PutFlag()

RemoveFlag()

OnRButtonDown(x, y)

IsOpened()

Page 133: D.  지뢰찾기 분석 설계 예제

D133

작업 3: 클래스 다이어그램

+Cell()+PutMine(in mine : Mine)+IsOpened() : bool+IsMined() : bool+Open()+PutFlag()+RemoveFlag()+IsFlaged() : bool

Cell

+InitMinefield(in rowCnt : int, in colCnt : int, in mineCnt : int)+GetCell(in row : int, in col : int) : Cell+AreAllMinesFound() : bool+GetAdjacentMineCount(in row : int, in col : int) : int

Minefield

1

*

+InitGame(in rowCnt : int, in colCnt : int, in mineCnt : int)+OpenCell(in row : int, in col : int)+IsSuccess() : bool+IsFailure() : bool+GetAdjacentMineCount(in row : int, in col : int) : int+FlagCell(in row : int, in col : int)+IsOpened(in row : int, in col : int) : bool+IsMined(in row : int, in col : int) : bool+IsFlaged(in row : int, in col : int) : bool+OpenAdjacentCells(in row : int, in col : int)

Minesweeper

1

1

+OnGameNew()+DrawGame()+OnLButtonDown()+OnRButtonDown(in x : int, in y : int)

-minesweeper : MinesweeperUI

Page 134: D.  지뢰찾기 분석 설계 예제

D134

변경 사항• 추가되는 메소드

– UI::OnRButtonDown(int x, int y);– Minesweeper::FlagCell(int row, int col);– Minesweeper::OpenAdjacentCells(int row, int col);– Cell::PutFlag();– Cell::RemoveFlag();

• 수정되는 메소드– Minesweeper::OpenCell(int row, int col);– 주변 지뢰 수가 0일 경우 OpenAdjacentCells() 호출을 하도록

수정

Page 135: D.  지뢰찾기 분석 설계 예제

D135

변경 사항• Cell 의 GetState() 메소드를 다음으로 대체한다

– Cell::IsOpened()– Cell::IsFlaged()– Cell::IsMined()

• Minesweeper 의 GetCellState() 메소드를 다음으로 대체한다– Minesweeper::IsOpened()– Minesweeper ::IsFlaged()– Minesweeper ::IsMined()

Page 136: D.  지뢰찾기 분석 설계 예제

D136

2-3. 2차개발 테스트 계획

Page 137: D.  지뢰찾기 분석 설계 예제

D137

UI 테스트 구현• 다음과 같은 Minefield 를 구현하여 UI 를 테스트한다

Page 138: D.  지뢰찾기 분석 설계 예제

D138

UI 테스트 데이터 구현• 지뢰

1

1

1 1

1 1

1

1 1 1

Page 139: D.  지뢰찾기 분석 설계 예제

D139

UI 테스트 데이터 구현• 주변 지뢰 수

1 2 1 0 0 0 0 0

1 2 1 0 0 0 0 0

1 1 2 2 2 1 0 0 0

0 0 2 1 1 1 1

0 0 2 3 1 1 1

0 0 1 1 1 0 1 1 1

0 1 1 1 0 0 0 0 0

1 2 1 0 1 2 2 1

1 2 1 0 1 1

Page 140: D.  지뢰찾기 분석 설계 예제

D140

model.h#ifndef MINESWEEPER_H#define MINESWEEPER_H

class Minesweeper {public: void InitGame(int rowCnt, int colCnt, int mineCnt); void OpenCell(int row, int col); void FlagCell(int row, int col); bool IsSuccess(); bool IsFailure(); int GetAdjacentMineCount(int row, int col); bool IsFlaged(int row, int col); bool IsOpened(int row, int col); bool IsMined(int row, int col);};

#endif

Page 141: D.  지뢰찾기 분석 설계 예제

D141

model.cpp#include <stdafx.h>#include <assert.h>#include "model.h"

static char mine[9][9] = { 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 1, 0};

static char adjacentMineCnt[9][9] = { 1, 2, 0, 1, 0, 0, 0, 0, 0, 1, 0, 2, 1, 0, 0, 0, 0, 0, 1, 1, 2, 2, 2, 1, 0, 0, 0, 0, 0, 2, 0, 0, 1, 1, 1, 1, 0, 0, 2, 0, 3, 1, 1, 0, 1, 0, 0, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 0, 0, 0, 0, 0, 1, 2, 0, 1, 0, 1, 2, 2, 1, 1, 0, 2, 1, 0, 1, 0, 0, 1};

Page 142: D.  지뢰찾기 분석 설계 예제

D142

static char opened[9][9] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};

static char flaged[9][9] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};

Page 143: D.  지뢰찾기 분석 설계 예제

D143

void Minesweeper::InitGame(int rowCnt, int colCnt, int mineCnt) {memset(opened, 0, sizeof(char) * 9 * 9);

memset(flaged, 0, sizeof(char) * 9 * 9);}

void Minesweeper::OpenCell(int row, int col) {assert( 0 <= row && row < 9 && 0 <= row && col < 9 );

if (flaged[row][col]) return;opened[row][col] = 1;

}

bool Minesweeper::IsSuccess() {for (int r = 0; r < 9; ++r)for (int c = 0; c < 9; ++c) if (!opened[r][c] && !mine[r][c]) return false;return true;

}

bool Minesweeper::IsFailure() {for (int r = 0; r < 9; ++r)for (int c = 0; c < 9; ++c) if (opened[r][c] && mine[r][c]) return true;return false;

}

int Minesweeper::GetAdjacentMineCount(int row, int col) {assert( 0 <= row && row < 9 && 0 <= row && col < 9 );return adjacentMineCnt[row][col];

}

Page 144: D.  지뢰찾기 분석 설계 예제

D144

bool Minesweeper::IsFlaged(int row, int col) {assert( 0 <= row && row < 9 && 0 <= row && col < 9 );return flaged[row][col] == 1;

}

bool Minesweeper::IsMined(int row, int col) {assert( 0 <= row && row < 9 && 0 <= row && col < 9 );return flaged[row][col] == 1;

}

bool Minesweeper::IsOpened(int row, int col) {assert( 0 <= row && row < 9 && 0 <= row && col < 9 );return opened[row][col] == 1;

}

void Minesweeper::FlagCell(int row, int col) {assert( 0 <= row && row < 9 && 0 <= row && col < 9 );

flaged[row][col] = 1;}

Page 145: D.  지뢰찾기 분석 설계 예제

D145

Model 테스트• Model 은 UI 와 통합하여 테스트한다

Page 146: D.  지뢰찾기 분석 설계 예제

D146

3-1. 3차개발 분석

Page 147: D.  지뢰찾기 분석 설계 예제

D147

개요• " 닫힌 칸들을 열기 " 구현

Page 148: D.  지뢰찾기 분석 설계 예제

D148

3-1-1. Use-case Model

Page 149: D.  지뢰찾기 분석 설계 예제

D149

Use Case Diagram

플레이어

지뢰찾기

닫힌 칸을 열기

지뢰를 표시

닫힌 칸들을 열기

Page 150: D.  지뢰찾기 분석 설계 예제

D150

Use-case Specification• Name : 닫힌 칸들을 열기• Description:

– 인접한 지뢰가 모두 표시되었을 경우 , 지뢰가 없는 인접한 빈 칸을 모두 동시에 연다

• Actor: 플레이어

• Precondition: – 클릭하는 칸은 열려 있어야 한다– 열려진 칸에 표시된 주변 지뢰 수 만큼

주변 칸들에 지뢰 표시들이 있어야 한다

Page 151: D.  지뢰찾기 분석 설계 예제

D151

닫힌 칸들을 열기• Main Flow

1. 열려진 칸에서 마우스 왼쪽과 오른쪽 버튼을 동시에 누른다

2. 인접한 8개의 칸들 중 지뢰 표시가 되어 있지 않은 칸들 이 열려진다 . 열려진 각 칸들에는 인접한 지뢰의 수가 표시된다 .

3. 열려진 칸의 주변 지뢰의 수가 0 이면• 지뢰 수 0 은 표시되지 않고• 주변의 칸 모두 열려지며• 각 칸 안에 그 주변의 지뢰의 수가 표시된다 . • 이 과정은 재귀적으로 반복된다

Page 152: D.  지뢰찾기 분석 설계 예제

D152

닫힌 칸들을 열기• Alternative Flow

A2. 지뢰가 있는 칸이었으면 지뢰가 폭발하여 게임은 실패로 종료된다

A2. 모든 칸이 열려졌으면 게임은 성공으로 종료된다

Page 153: D.  지뢰찾기 분석 설계 예제

D153

3-1-2. 보충 요구사항

Page 154: D.  지뢰찾기 분석 설계 예제

D154

보충 요구사항

• 난이도– 초급 : 9 행 9 열의 칸 , 10 개의 지뢰– 중급 : 16 행 16 열의 칸 , 40 개의 지뢰– 고급 : 16 행 30 열의 칸 , 99개의 지뢰

• 화면에 남은 지뢰수가 표시된다– 남은 지뢰수 = 전체 지뢰 수 – 지뢰 표시의 수

Page 155: D.  지뢰찾기 분석 설계 예제

D155

3-1-3. 화면 / 메뉴 설계

Page 156: D.  지뢰찾기 분석 설계 예제

D156

화면설계

진행화면 성공 실패

Page 157: D.  지뢰찾기 분석 설계 예제

D157

3-2. 3차개발 설계

Page 158: D.  지뢰찾기 분석 설계 예제

D158

개요• 3차 개발에서 추가된 기능을 설계 구현한다

• 2차 개발에서 설계 구현된 것을 수정한다

Page 159: D.  지뢰찾기 분석 설계 예제

D159

작업 1: 시스템 내부 절차 식별• 추가된 Use-case specification 의 절차를 수행하기 위해 시스템

내부에서 수행해야 하는 일을 순서대로 적는다

Page 160: D.  지뢰찾기 분석 설계 예제

D160

닫힌 칸들을 열기 절차1. 마우스 두 버튼이 동시에 눌려진 것을 감지한다2. 열린 칸이 아니면 무시3. 주변의 지뢰 수와 주변의 지뢰표시 수를 비교한다

3-1. 주변 지뢰 수 계산3-2. 주변 지뢰표시 수 계산

4. 두 수가 같으면 주변의 지뢰표시가 없고 닫혀진 모든 칸을 연다 . 5. 주변의 칸을 여는 절차는 이미 구현한 inesweeper.AdjacentCells()

를 이용한다6. 두 수가 같지 않으면 무시

Page 161: D.  지뢰찾기 분석 설계 예제

D161

메소드에 역할 할당• UI::OnRButtonDown() 1

• Minesweeper::OpenCells() 2, 3, 4, 6

• Minefield::GetAdjacentMineCount() 3-1

• Minefield::GetAdjacentFlagCount() 3-2

• Minesweeper::OpenAdjacentCells() 5

Page 162: D.  지뢰찾기 분석 설계 예제

D162

작업 2: 시퀀스 다이어그램으로 설계

: UI

OnRButtonDown(x, y)

OnLButtonDown()

: Minesweeper

OpenCells(row, col)

: Minefield

GetAdjacentMineCount(row, col)

GetAdjacentFlagCount(row, col)

OpenAdjacentCells(row, col)

Page 163: D.  지뢰찾기 분석 설계 예제

D163

: UI : Minesweeper

GetFlagCount()

: Minefield

GetFlagCount()

DrawGame()

cell : Cell

IsFlaged()

IsSuccess()

IsFailure()

IsOpened(row, col)

IsFlaged(row, col)

IsExploded(row, col)

IsMined(row, col)

IsClosed(row, col)

cell:=GetCell(row, col)

IsFlaged()

IsMined()

Page 164: D.  지뢰찾기 분석 설계 예제

D164

작업 3: 클래스 다이어그램

+Cell()+PutMine(in mine : Mine)+IsOpened() : bool+IsMined() : bool+Open()+PutFlag()+RemoveFlag()+IsFlaged() : bool

Cell

+InitMinefield(in rowCnt : int, in colCnt : int, in mineCnt : int)+GetCell(in row : int, in col : int) : Cell+AreAllMinesFound() : bool+GetAdjacentMineCount(in row : int, in col : int) : int+GetAdjacentFlagCount(in row : int, in col : int) : int+GetFlagCount() : int+IsValidIndex(in row : int, in col : int) : bool

Minefield

1

*

+InitGame(in rowCnt : int, in colCnt : int, in mineCnt : int)+OpenCells(in row : int, in col : int)+OpenAdjacentCells(in row : int, in col : int)+OpenCell(in row : int, in col : int)+FlagCell(in row : int, in col : int)+GetAdjacentMineCount(in row : int, in col : int) : int+GetFlagCount() : int+IsSuccess() : bool+IsFailure() : bool+IsOpened(in row : int, in col : int) : bool+IsMined(in row : int, in col : int) : bool+IsFlaged(in row : int, in col : int) : bool+IsClosed(in row : int, in col : int) : bool+IsExploded(in row : int, in col : int) : bool

Minesweeper

1

1

+OnGameNew()+DrawGame()+OnLButtonDown()+OnRButtonDown(in x : int, in y : int)+OnGameBasic()+OnGameIntermediate()+OnGameExtended()

-minesweeper : MinesweeperUI

Page 165: D.  지뢰찾기 분석 설계 예제

D165

3-3. 3차개발 테스트 계획

Page 166: D.  지뢰찾기 분석 설계 예제

D166

테스트 계획• 추가되는 기능이 매우 단순한 편

• 두 모듈 각각의 테스트는 생략하고 통합하여 테스트한다

Page 167: D.  지뢰찾기 분석 설계 예제

D167

4. 4차개발

Page 168: D.  지뢰찾기 분석 설계 예제

D168

개요• 화면 깜빡거림의 개선

• 마우스 왼쪽 버튼을 누를 때– 누르고 있을 때는 칸이 눌린 상태로 그려짐– 버튼이 놓여질 때 칸이 열리도록

• 두 버튼을 동시에 누를 때– 어느 버튼이 먼저 눌려졌는지 상관 없도록– 누르고 있을 때는 주변의 지뢰표시 없는 칸들이 눌린 상태로

그려짐– 버튼이 놓여질 때 칸들이 열리도록

Page 169: D.  지뢰찾기 분석 설계 예제

D169

설계

OnLButtonDown/ ShowCellPressed

OnRButtonDown

OnRButtonDownOnLButtonDown

Init

LDownRDown

LRDown

Entry: ShowCellsPressed

OnLButtonUp/ OpenCell()

OnRButtonUp/ FlagCell() OnLButtonUp

OrOnRButtonUp/ OpenCells()

OnLButtonUpOr

OnRButtonUp