4장. 여러분의 소프트웨어를 실제 세상으로...

  1. 4장. 여러분의 소프트웨어를 실제 세상으로...
    1. 4.1 프로그램은 동작환경이 있습니다.
    2. 4.2 분석을 하면 여러분의 시스템이 실세계에서 잘 동작하게 만들수 있습니다.
    3. 4.3 코딩
    4. 4.4 나의 정의는 무엇일까요?
    5. 문서에 대하여

4.1 프로그램은 동작환경이 있습니다.

  • 덕의 강아지문 사업
    • 홀리는 덕의 강아지문을 구입하였습니다.
    • 홀리는 강아지 소리 인식기가 부착된 새 모델이 마음에 들었습니다.
    • 하지만.. 문제가 생겼습니다.\!
    • 옆집 강아지가 짖을 때에도 열립니다.

      프로그램은 동작환경을 고려하여 소프트웨어를 개발해야합니다. 우리가 만든 소프트웨어는 완벽한 세상이 아닌, 실제세상에서도 동작하여야 합니다.

4.2 분석을 하면 여러분의 시스템이 실세계에서 잘 동작하게 만들수 있습니다.

  • 문제 찾기
    • 옆집에 강아지가 많이 있으면 문제가 생깁니다.
  • 해결방안 계획
    • 대체경로 (정상)
      • 1. 부르스가 밖에 나가려고 짖습니다.
      • 2. 홀리가 브루스가 짖는 소리를 듣습니다.
      • 3. 홀리가 리모콘의 버튼을 누릅니다.
      • 4. 강아지 문이 열립니다.
      • 5. 브루스가 밖에 나갑니다.
    • 주경로
      • 1. 부르스가 밖에 나가려고 짖습니다.
      • 2. 강아지 소리 인식기가 강아지 소리를 "듣습니다"
      • 3. 강아지 소리 인식기가 강아지문을 여는 신호를 보냅니다.(문제발생\!\!)
      • 4. 강아지 문이 열립니다.
      • 5. 브루스가 밖에 나갑니다.
    • 주경로
      • 1. 부르스가 밖에 나가려고 짖습니다.
      • 2. 강아지 소리 인식기가 강아지 소리를 "듣습니다"
      • 3. 브루스가 짖고 있으면, 여는 신호를 문에 보냅니다.
        (듣는 소리를 판단하여 부르스인지 아닌지 판단합니다.)
      • 4. 강아지 문이 열립니다.
      • 5. 브루스가 밖에 나갑니다.
    • 바보같은질문은 없습니다.
      • 대개 문제 해결방법은 여러 개 있고, "정답"이 하나만 있는경우는 없습니다. 당신의 생각도 옳습니다.
      • 문제만 해결된다면, 유스케이스도 여러해결방법이 있습니다.

        유스케이스 작성하기
        1. 유스케이스를 여러분과 여러분의 상사, 그리고 여러분의 고객들이 이해 하기
        쉬운방식으로 작성하세요.
        2. 분석과 유스케이스들은 고객들, 관리자들, 그리고 동료 개발자들에게 여러분이 만드는
        시스템이 실세계에서 어떻게 동작 할지를 보여줍니다.

    • 잘만들어진 유스케이스는 시스템이 하는 일을 {+}명확히{+} 그리고 {+}정확히{+} 이해하기 쉬운 언어로 설명합니다.
  • 유스케이스 업데이트
    • 주경로(최종 강아지문 버전3.0)
      • 1. 주인 강아지가 밖에 나가려고 짖습니다.
      • 2. 강아지 소리 인식기가 강아지 소리를 "듣습니다."
      • 3. 주인 강아지가 짖으면, 강아지 소리 인식기가 여는 요청을 강아지 문에 보냅니다.
      • 4. 강아지 문이 열립니다.
      • 5. 주인 강아지가 밖으로 나갑니다.
      • 6. 주인 강아지가 화장실을 이용합니다.
        • 6.1 문이 자동으로 닫힙니다.
        • 6.2 주인 강아지가 안에 들어보내 달라고 짖습니다.
        • 6.3 강아지 소리 인식기가 강아지 소리를 "듣습니다."
        • 6.4 주인 강아지가 짖으면, 강아지 소리 인식기가 여는 요청을 문에 보냅니다.
        • 6.5 강아지 문이 열립니다.
      • 7. 주인강아지는 안으로 들어옵니다.
      • 8. 문이 자동으로 닫힙니다.
    • 주인강아지의 소리를 저장하는 유스케이스가 필요합니다.

      주인강아지의 소리를 저장하려면 정말 하나의 유스케이스가 필요할까요?
      예.
      각 유스케이스는 하나의 특정한 사용자 목표를 가지고 있어야 합니다.
      원래 목표: 강아지를 밖에 내보내 화장실을 이용하게 하고 안으로 들이는 것.
      새 목표 : 강아지 소리를 저장하는 것.
      두개가 틀리가 때문에 새로운 유스케이스가 필요합니다.

  • 본문분석
    • 클래스와 메소드를 찾아내기 위해 유스케이스에서 명사(와 동사)를 분석하는 것.
    • 단, 본문분석은 집중해야 할 것을 알려주는 것이지, 무슨 클래스를 만들어야 하는지를 알려주지는 않습니다.

4.3 코딩

DogDoorSimulator.java


/**
 * 
 * 강아지 문 시뮬레이터
 * 
 * @author 장선웅
 *
 */
public class DogDoorSimulator {
	
	@SuppressWarnings("static-access")
	public static void main(String[] args) {
		DogDoor door = new DogDoor();
		door.addAllowedBark(new Bark("멍")); // 브루스의 음성들
		door.addAllowedBark(new Bark("멍멍"));
		door.addAllowedBark(new Bark("왈왈"));
		door.addAllowedBark(new Bark("bowbow"));		
		BarkRecognizer recognizer = new BarkRecognizer(door);		
		Remote remote = new Remote(door);
		
		System.out.println("브루스가 짖기 시작합니다.");
		recognizer.recognize(new Bark("왈왈")); // 안에서 급할때(?) 브루스가 짖는 음성
		System.out.println("브루스가 밖으로 나갔습니다.");
				
		try {
			System.out.println("");
			Thread.currentThread().sleep(1000);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		
		Bark smallDog = new Bark("워리워리");
		System.out.println("옆집의 작은개가 짖기 시작합니다.");
		recognizer.recognize(smallDog);
		
		try {
			System.out.println("");
			Thread.currentThread().sleep(5000);
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		System.out.println("브루스가 짖기 시작합니다.");
		recognizer.recognize(new Bark("멍멍")); // 밖에서 들어오고 싶을때 브루가 짖는 음성
		System.out.println("브루스가 안으로 들어갑니다..");
				
	}
}

DogDoor.java


import java.util.ArrayList;
import java.util.List;
import java.util.Timer;
import java.util.TimerTask;

/**
 * 
 * 강아지 문
 * 
 * @author 장선웅
 *
 */
public class DogDoor {
	boolean open;
	List<Bark> barkLst;
	
	public DogDoor() {
		barkLst = new ArrayList<Bark>();
		close();
	}
	
	public void open() {
		System.out.println("강아지문이 열렸습니다.");
		open = true;
		
		// 5초뒤 자동으로 닫힙니다.
		final Timer timer = new Timer();
		timer.schedule(new TimerTask() {
			public void run() {
				close();
				timer.cancel();
			}
		}, 5000);
	}
	
	public void close() {
		System.out.println("강아지문이 닫혔습니다.");
		open = false;
	}
	
	public boolean isOpen() {
		return open;
	}
	
	public void addAllowedBark(Bark b) {
		barkLst.add(b);
	}
	
	List<Bark> getAllowedBarks() {
		return barkLst;
	}
}

Bark.java


/**
 * 
 * 강아지 소리
 * 
 * @author 장선웅
 *
 */
public class Bark {
	String sound;
	
	public Bark(String sound) {
		this.sound = sound;
	}
	String getSound() {
		return sound;
	}
	
	public boolean equal(Bark b) {
		// 음성을 비교합니다.
		return this.getSound().equalsIgnoreCase(b.getSound());
	}
}

BarkRecognizer.java


import java.util.Iterator;
import java.util.List;

/**
 * 
 * 음성인식기
 * 
 * @author 장선웅
 *
 */
public class BarkRecognizer {
	DogDoor door;
	
	public BarkRecognizer(DogDoor door) {
		this.door = door;
	}
	
	public void recognize(Bark bark) {
		System.out.println("음성인식기에서 \"" + bark.getSound() + "\"를 인식합니다.");
		List<Bark> lst = door.getAllowedBarks();
		Iterator<Bark> iter = lst.iterator();
		
		boolean isTrue = false;
		while(iter.hasNext()) {
			if(iter.next().equal(bark)) {
				isTrue = true;
				break;
			}
		}
		
		if(isTrue && !door.isOpen()) {
			System.out.println("등록되어있는 음성입니다.");
			door.open();
		} 
		else {
			System.out.println("등록되어있지 않은  음성입니다.");			
		}
	}
}

Remote.java


/**
 * 
 * 강아지문 리모콘
 * 
 * @author 장선웅
 *
 */
public class Remote {
	DogDoor door;
	
	public Remote(DogDoor door) {
		this.door = door;
	}
	public void pressButton() {
		System.out.println("리모콘 버튼을 누릅니다.");
		if(door.isOpen())
			door.close();
		else
			door.open();
	}
}

4.4 나의 정의는 무엇일까요?

명사 분석7코드 수준의 모든 구성 요소들을 속성들과 오퍼레이션들과 함께 나열합니다.
다중도6이것은 보통 클래스의 메소드를 나타내는 UML용어 입니다.
속성5클래스에서 멤버 변수와 같습니다.
클래스 다이어그램1한 클래스가 다른 클래스와 관련이 있음을 시각적으로 보여줍니다. 보통은 속성을 사용해서 보여줍니다.
오퍼레이션2클래스에서의 멤버변수와 같습니다.
연관4클래스의 속성에 특정 타입 객체가 몇 개나 저장되는지를 나타냅니다.
동사 분석3시스템에 필요한 클래스를 찾기 위해 유스케이스에 이것을 시행합니다.

문서에 대하여