목차
NextGen POS System
프로젝트 산출물
최종 보고서
(2010.12.21)
작성자: 박은지
학번: 20090544
학과: 컴퓨터공학과
과목: 소프트웨어공학
목차목차
• 문서이력
• 분석
– 비전
– 유스케이스
• 다이어그램
• 액티비티 다이어그램
• UC1: ProcessSale
• ★ UC2: HandleReturn(2011.12.21수정)
• UC3: CashIn
• UC4: CashOut
– 보충명세서
– Operation Contracts
– 용어집
– 도메인 모델★
– 시퀀스 다이어그램★
– 설계 클래스 다이어그램 ★
– 소스코드★
– 테스트 코드★
목차문서이력
버전 일자 설명 비고
1차 과제 2011.10.08 교재의 내용을 단순 타이핑
2차 과제 2011.10.09 Handle, CashIn, CashOut 추가
3차 과제 2011.11.18. 다이어그램 , 유즈케이스1~4
수정
유즈케이스5,6 추가
SSD 추가
액티비티 다이어그램 추가
Operation Contracts 추가
4차 과제 2011.12.21 -도메인모델
-시퀀스 다이어그램
-DCD
-소스코드
추가하고,
-Handle Return SSD 수정
목차비전
개정 이력
버전 일자 설명 비고
Inception 초안 2011.10.10 최초 버전. Elaboration 단계 동안 주로
정제되어야 함
크레이그 라만
(Craig Laman)
Elaboration 2011.10.11 정제된 버전. 세부사항에 대한 수정
목차비전-계속
개요
우리는 다음 버전으로 결함 허용성을 가진 NextGen POS 애플리케이션을 계획하며 이
애플리케이션은 다양한 고객의 비즈니스 규칙, 여러 터미널과 사용자 인터페이스 매커
니즘, 제 3자에 의해 개발된 지원 시스템과의 연동 등을 지원해야 한다.
위치화(positioning)
사업적 기회
현재의 POS 제품들은 비즈니스 규칙과 네트워크 설계를 다양화하는 측면에서 고객의
업무에 적합하지 않다. 그리고 터미널과 비즈니스가 증가하는 것에 대응하지 못한다. 또
한 실패에 따라 그때그때 조정하면서 온라인과 오프라인에서 작업할 수 없고, 다른 3자
에 의해 개발된 시스템과 연동도 어렵다. 무선 PDA와 같은 새로운 터미널 기술에 적용
하기도 어렵다. 이렇게 유연하지 못한 현재의 POS 제품 상태에 시장이 만족하지 못하고,
이를 충족시키는 POS 시스템에 대한 요구가 있다.
문제 기술
기존의 POS 시스템은 유연하지 않고, 결함 허용성을 제공하지 않으며, 제 3자에 의해
개발된 시스템과 연동하기도 어렵다. 따라서 적시에 판매 처리하고, 그 소프트웨어에 맞
지 않는 개선된 프로세스를 만들며, 다른 문제들 사이에서 측정과 계획을 세우는 데 필
요한 정확한 회계 및 재고 데이터를 적시에 지원하는 것들이 어렵게 된다. 그리고 이러
한 어려움은 출납원, 매장 관리자, 시스템 관리자, 회사 관리에 영향을 준다.
제품 위치 기술
현재의 시스템은 작은 규모의 상점에서부터 대형 마트에 이르기까지 다양한 규모의 상
점을 대상으로 계획 및 작성되었다.
목차비전-계속
관련자 설명
관련자들의 중요한 상위 수준 목적 및 문제
주제 분야 전문가와 다른 관련자들이 참여한 하루 동안의 요구사항 워크숍과 여러 소
매점에서의 조사를 통해 다음과 같이 핵심 목표와 문제를 식별하였다.
상위 수준의 목
적
우선 순
위
문제 및 관심 현재 해결책
빠르고,
견고하며
통합된
판매 처리
높음 부하가 증가함에 따라 속도 감소,
컴포넌트의 기능이 실패하면 판매 처리
능력 감소,
기존의 회계, 재고, 인사 관리 시스템과
통합되지 못함으로 인해 회계나 기타 시
스템으로부터의 최근의 정확한 정보 부
족, 측정 및 계획의 어려움 초래.
비즈니스 규칙을 고유한 비즈니스 요구
사항에 맞추는 능력 부족.
새로운 유형의 터미널이나 사용자 인터
페이스(예를 들어, 모바일 PDA) 추가에
대한 어려움.
기존의 POS 제품들은
이러한 문제의 해결
없이 유스케이스 기본
적인 판매 모델링에서
생성된 액터-목적 처
리 기능을 제공한다.
… … …
목차비전-계속
사용자 수준의 목적
사용자(와 외부 시스템)는 다음과 같은 목적을 수행하는 시스템을 원한다.
 출납원 : 판매 처리, 반품 처리, 출납 업무 개시, 출납 업무 종료
 시스템 관리자 : 사용자 관리, 보안 관리, 사용자 테이블 관리
 관리자 : 시스템 시작, 시스템 종료
 영업 관리 시스템 : 판매 데이터 분석
제품 개요
제품의 전망
NextGen POS는 주로 상점 내에 설치될 것이다. 만약 이동 터미널을 사용한다면, 상점
안이든 또는 외부 근처이든 상점의 네트워크 근처에 있을 것이다. 그림 비전-1에서처
럼, POS 시스템은 사용자에게 서비스를 제공하고, 다른 시스템과 연동할 것이다.
<<actor>>
영업 관리
시스템
출납원
시스템
관리자
상점
관리자
<<actor>>
회계 시스템
<<actor>>
세금 계산기
<<actor>>
지불 인증
서비스
<<actor>>
인사 관리
시스템
<<actor>>
재고 시스템
NextGen POS
서비스 요청 서비스 요청
그림 비전-1 NextGen POS 시스템 컨텍스트 다이어그램
목차비전-계속
이점 요약
지원하는 특징 관련자의 이점
기능적으로 시스템은 판매 내역 파악, 지불 인증, 반품 처
리 등을 포함하여 판매 조직이 요구하는 모든 일반적인 서
비스를 제공
자동화되고 빠른 POS 서비스
서비스를 이용할 수 없는 경우에 대비하여, 실패의 자동 감
지, 지역 오프라인 처리로의 전환
외부 컴포넌트의 작동 실패에
도 지속적인 판매 처리
판매 처리 동안 다양한 시나리오의 지점에 장착할 수 있는
비즈니스 규칙
유연한 비즈니스 로직 구성
사업 표준 프로토콜을 사용하여 제 3자에 의해 개발된 시
스템과의 실시간 트랜잭션
측정과 계획 지원을 위한 적시
의 정확한 판매, 회계, 재고 정
보
…
목차비전-계속
시스템 피처의 요약
 판매 내역 파악
 지불 인증(신용카드, 직불카드, 수표)
 사용자, 보안, 코드, 상수 테이블 등에 대한 시스템 관리
 외부 컴포넌트의 기능 실패 시, 자동 오프라인 판매 처리
 재고, 회계, 인사, 세금 계산, 지불 인증을 포함한 산업 표준에 기초를 둔, 제 3자에
의해 개발된 시스템과의 실시간 트랜잭션
 처리 시나리오에서 어떤 고정된 일반적인 지점에 장착할 수 있는 비즈니스 규칙을
정의하고 이행
 …
그 밖의 요구사항 및 제약사항
설계 제약사항, 사용성, 신뢰성, 성능, 지원성, 문서화, 패키징 등이 포함된다. 보충 명세
서와 유스케이스를 참조하라.
목차유스케이스
버전 일자 설명 비고
Inception 초안 2011.10.10 최초 버전. Elaboration 단계 동안 주로
정제되어야 함
크레이그 라만
(Craig Laman)
Elaboration 2011.10.11 정제된 버전. 세부사항에 대한 수정
목차유즈케이스 다이어그램
Process Sale
Handle
Returns
Cash In
Cash Out
System
Start Up
StartSaleTask
EndSaleTask
회계담당
관리자
출납원
목차액티비티 다이어그램
• NextGen POS system
출납원 회계담당
Cash In
StartSaleTask
Process Sale
EndSaleTask
Cash Out
목차UC1: ProcessSale
범위 : NextGen POS 애플리케이션
수준 : 사용자의 목적
주요 액터 : 출납원
관련자 및 관심사항
- 출납원 : 정확하고 빠른 입력을 원하며 현금 지불 금액에 대한 부족분은 담당 출납
원의 봉급에서 공제되므로 지불상의 오류가 없기를 원한다.
- 판매원 : 판매수수료가 갱신되기를 원한다.
- 고객 : 최소의 노력으로 구매하고 빠른 서비스를 받기 원한다. 판매되는 물건의 가
격을 쉽게 보기 원한다. 반품할 때를 위한 구매의 증거물을 원한다.
- 회사 : 발생하는 거래를 정확하게 기록하고 고객의 요구를 충족시키기를 원한다. 지
불 인증 서비스의 지불 수취계정에 확실히 기록되길 원한다. 서버 컴포넌트(원격 신
용 검증 등)의 사용이 불가능할 때도 시스템은 결함을 허용(fault tolerace)해서 판매
정보를 얻을 수 있기를 원한다. 회계 및 재고 정보가 자동으로 빠르게 갱신되기 원
한다.
- 관리자 : 취소 기능이 빨리 수행될 수 있기를 원하고 출납원의 문제를 쉽게 찾아 해
결하기를 원한다.
- 세무서 : 모든 판매 건에 대해 세금을 징수하기 원한다. 국가, 도, 시와 같은 여러 개
의 기관이 있을 수 있다.
- 지불 인증 서비스 : 정확한 형식과 프로토콜을 따르는 디지털 인증 요청을 받기 원
한다. 상점에 지불한 내역이 정확하게 계산되기를 원한다.
목차UC1: ProcessSale-계속
사전조건 : 출납원이 식별되고 인증된다.
성공 보증(또는 사후조건) : 판매 자료는 저장된다. 세금
은 정확하게 계산된다. 회계 및 재고 정보가 갱신된다. 수
수료가 기록된다. 영수증이 생성된다. 지불 인증 승인이
기록된다.
주요 성공 시나리오(또는 기본 흐름)
1. 고객은 구매하고자 하는 물품이나 서비스를 가지고
POS 계산대에 온다.
2. 출납원은 새로운 판매를 시작한다.
3. 출납원은 품목 식별자를 입력한다.
4. 시스템은 품목을 기록하고 품목의 설명, 가격 그리고
현재까지의 금액 합계를 보여준다. 가격은 가격 결정
규칙을 통해 계산한다.
출납원은 모든 구매 품목에 대해 단계 3~4를 반복한다.
5. 시스템은 세금을 포함한 총액을 보여준다.
6. 출납원은 고객에게 총액을 말하고 지불을 요청한다.
7. 고객은 지불하고 시스템은 지불 처리한다.
8. 시스템은 완료된 판매를 기록하고 판매 및 지불 정보
를 외부 회계 시스템(회계와 수수료 처리를 위해)과 재고
관리 시스템(재고 정보를 갱신하기 위해)으로 전송한다.
9. 시스템은 영수증을 발행한다.
10. 고객은 영수증과 물품을 가지고 나간다.
• SSD
: 출납원
:System
makeNewSale
enterItem(itemID, quantiy)
description, total
loop [more
items]
endSale
total with taxes
makePayment(amount)
change due, receipt
목차UC1: ProcessSale-계속
확장 (또는 대안 흐름)
*a. 언제든지, 관리자가 판매 취소 기능을 요구하는 경우
1. 시스템은 관리자-인증 모드로 들어간다.
2. 관리자나 출납원은 한 관리자-모드 오퍼레이션을 수행한다. 예를 들어 현금 잔
액 변경, 다른 등록기에서 중지된 판매 재개, 판매 취소 등.
3. 시스템은 출납원-인증 모드로 되돌아간다.
*b. 언제든지, 시스템이 실패한 경우
회계 정보를 복구하고 수정하기 위해 모든 거래에 연결된 상태와 이벤트는 시나리
오의 어떤 단계에서도 복구될 수 있음을 확인한다.
1. 출납원은 시스템을 재시작하고 이전 상태로의 복구를 요청한다.
2. 시스템은 이전 상태로 복구한다.
2a. 시스템이 복구되는 데 방해가 되는 예외적인 것들이 발생하는 경우
1. 시스템은 출납원에게 오류를 표시하고, 이를 기록하며 초기의 깨끗한
상태로 들어간다.
2. 출납원은 새로운 판매를 시작한다.
1a. 고객이나 관리자는 일시정지된 판매 처리를 다시 시작할 것을 지시한다.
1. 출납원은 재시작 기능을 수행하고 판매 내역을 확인하기 위해 ID를 입력한다.
2. 시스템은 다시 시작할 판매 상태를 현재까지의 소계와 함께 보여준다.
목차UC1: ProcessSale-계속
2a. 판매 건을 찾지 못했다.
1. 시스템은 출납원에게 오류를 보여준다.
2. 출납원은 새로운 판매를 시작하고 모든 품목을 다시 입력해야 할 것이
다.
3. 출납원은 판매 처리를 계속 진행한다(남아 있는 품목을 입력하거나 지불 처리한
다).
2-4a. 고객은 출납원에게 자신이 비과세 대상자라는 것을 알린다(예를 들어, 노인이나
주민).
1. 출납원은 확인하고 비과세 상태 코드를 입력한다.
2. 시스템은 세금 계산 처리 시 사용할 비과세 상태를 기록한다.
3a. 유효하지 않은 ID(시스템에서 찾을 수 없는 경우)
1. 시스템은 오류를 보여주고 입력을 막는다.
2. 출납원이 오류에 반응한다.
2a. 사람이 판독할 수 있는 품목 ID(예를들어 UPC) 가 있는 경우
1. 출납원은 손으로 품목 ID를 입력한다.
2. 시스템은 품목의 설명과 가격을 보여준다.
2a. 유효하지 않은 ID일 경우 시스템은 오류를 보여주고 출납원은 다
른 방법을 시도해 본다.
목차UC1: ProcessSale-계속
2b. 품목의 ID가 없고 태그에 가격만 표시되어 있는 경우
1. 출납원은 관리자가 판매 취소 처리를 수행하기를 요청한다.
2. 관리자는 판매 취소 기능을 수행한다.
3. 출납원은 가격을 손으로 입력하고 입력한 금액에 대한 표준 세금을 받
는다. (제품에 대한 정보가 없기 때문에 세금 계산 엔진이 어떻게 과세
해야 하는지 알 수 없다).
2c. 출납원은 품목의 ID 및 가격을 알기 위해 Find Product Help를 수행한다.
2d. 그렇지 않으면, 출납원은 직원에게 품목의 ID나 가격을 물어보고 손으로
ID 또는 가격을 입력한다(위를 참조하라).
3b. 같은 품목이 여러 개 이고, 각각의 품목을 식별하는 것은 중요하지 않을 경우(예를
들어, 햄버거 5개)
1. 출납원은 한 품목의 식별자와 수량을 입력할 수 있다.
3c. 품목 종류와 가격을 손으로 입력해야 하는 품목일 경우(판매 상품에 가격이 추가되
는 꽃이나 카드 같은)
1. 출납원은 한 품목의 식별자와 수량을 입력할 수 있다.
3-6a: 고객이 구매한 품목 중 한 품목을 삭제해 주기를 요청하는 경우
품목의 가격이 출납원이 처리 가능한 무효 제한 가격보다 작을 때만 가능하다. 그
렇지 않으면 관리자에게 판매 취소를 요청해야 한다.
목차UC1: ProcessSale-계속
1. 출납원은 판매 내역에서 삭제할 품목의 식별자를 입력한다.
2. 시스템은 품목을 지우고 수정된 전체 금액을 보여준다.
2a. 품목의 가격이 출납원의 무효 제한 금액을 초과하는 경우
1. 시스템은 오류를 보여주고, 관리자가 판매 취소 처리하기를 제안한다.
2. 출납원은 관리자에게 판매 취소 처리를 요청한 후 처리되면 작업을 계
속한다.
3-6b. 고객이 출납원에게 판매를 취소할 것을 요청하는 경우
1. 출납원은 시스템에서 판매를 취소한다.
3-6c. 출납원이 판매 처리를 일시중지할 경우
1. 시스템은 다른 POS 등록기에서도 조회가 가능하도록 판매 내역을 기록한다.
2. 시스템은 판매 내역을 조회하고 판매 처리를 다시 시작할 수 있도록 품목과
판매 ID를 “일시중지 영수증”에 보여준다.
4a. 품목 가격이 원하던 가격이 아닌 경우(예를 들어, 고객이 어떤 품목에 대해 불평하
며 낮은 가격을 요구할 때)
1. 출납원은 관리자에게 승인을 요청한다.
2. 관리자는 판매 취소 처리한다
3. 출납원은 손으로 변경된 가격을 입력한다
4. 시스템은 새로운 가격을 보여준다
목차UC1: ProcessSale-계속
5a. 시스템이 외부 세금 계산 시스템과 통신하는 데 실패한 경우
1. 시스템은 POS 단말기의 외부 시스템과의 통신 서비스를 재시작하고 계속한다.
1a. 시스템은 서비스 재시작이 안 되는 것을 발견한다.
1. 시스템은 오류를 보여준다.
2. 출납원은 세금을 직접 계산해서 입력하거나 판매 처리를 취소한다.
5b. 고객이 자신이 할인 대상자라고 말하는 경우(예를 들어 직원, 우수고객)
1. 출납원은 할인 요청 신호를 보낸다.
2. 출납원은 고객 식별자를 입력한다.
3. 시스템은 할인 규칙에 의한 할인 총액을 보여준다.
5c. 고객이 판매에 사용할 수 있는 적립금이 있다고 말하는 경우
1. 출납원은 적립금 요청 신호를 보낸다.
2. 출납원은 고객 식별자를 입력한다.
3. 시스템은 가격 총액 범위 내에서 적립금을 이용하고 적립액을 감소시킨다.
6a. 고객은 현금으로 지불하려고 했지만 현금이 충분하지 않다고 말하는 경우
1. 출납원은 다른 지불 방법을 얘기한다.
1a. 고객은 구매를 취소한다고 말한다. 출납원은 판매를 취소한다.
7a. 현금으로 지불하는 경우
1. 출납원은 지불된 금액을 입력한다.
2. 시스템은 거스름돈 액수를 보여주고 금전등록기 서랍을 연다.
3. 출납원은 받은 현금을 넣고 고객에게 거스름돈을 건넨다.
목차UC1: ProcessSale-계속
4. 시스템은 현금 지불 금액을 기록한다.
7b. 신용카드로 지불하는 경우
1. 고객은 신용카드 정보를 입력한다.
2. 시스템은 검증을 위해 입력한 지불 내역을 보여준다.
3. 출납원은 확인한다.
3a. 출납원이 지불 단계를 취소하는 경우
1. 시스템은 “품목 입력” 상태로 되돌린다.
4. 시스템은 지불 인증 요청을 외부 지불 인증 시스템으로 보내고 지불 승인을 요
청한다.
4a. 시스템이 외부 시스템과의 연동에 실패했을 경우
1. 시스템은 출납원에게 오류를 보여준다.
2. 출납원은 다른 방법으로 지불하기를 요청한다.
5. 시스템은 지불 승인을 받아 출납원에게 승인 처리됨을 알리고 고객이 서명한
신용카드 지불 영수증을 넣기 위해 금전등록기 서랍을 연다.
5a. 시스템이 지불 거부를 응답받은 경우
1. 시스템은 출납원에게 지불이 거부되었음을 알린다.
2. 출납원은 다른 방법으로 지불하기를 요청한다.
5b. 승인 응답 시간을 초과한 경우
1. 시스템은 출납원에게 응답 시간이 초과했음을 알린다.
2. 출납원은 다시 시도해 보거나 고객에게 다른 방법으로 지불허가를 요
청한다.
목차UC1: ProcessSale-계속
6. 시스템은 지불 승인된 카드 지불 내역을 기록한다.
7. 시스템은 카드 지불 서명 방법을 보여준다.
8. 출납원은 고객이 카드 지불에 서명하기를 요청한다. 고객은 서명한다.
9. 영수증에 서명하면, 출납원은 금전등록기에 영수증을 넣고 서랍을 닫는다.
7c. 수표로 지불하는 경우
7d. 직불카드로 지불하는 경우
7e. 출납원이 지불 단계를 취소한 경우
1. 시스템은 “품목 입력” 모드로 복귀한다.
7f. 고객이 쿠폰을 내는 경우
1. 지불 처리하기 전에 출납원은 각 쿠폰을 기록하고 시스템은 책정된 가격을 뺀
다. 시스템은 회계 처리의 근거로 사용된 쿠폰을 기록한다.
1a. 구매 품목 중 입력된 쿠폰을 사용할 수 있는 품목이 없는 경우
1. 시스템은 출납원에게 오류를 보여준다.
9a. 환불되는 제품이 있는 경우
1. 시스템은 환불되는 각 품목에 대해 환불 양식과 영수증을 발행한다.
9b. 고객이 가격이 보이지 않는 선물용 영수증을 요구하는 경우
1. 출납원은 선물용 영수증을 요청하고 시스템은 그 영수증을 발행한다.
9c. 프린터에 용지가 없다.
목차UC1: ProcessSale-계속
1. 시스템이 발견할 수 있으면 문제를 알릴 것이다.
2. 출납원은 용지를 넣는다.
3. 출납원은 다른 영수증을 요청한다.
특수한 요구사항
- 큰 평면 모니터의 터치 스크린 UI, 문자는 1미터 내에서도 보여야 한다.
- 카드 인증의 90%는 30초 이내에 응답되어야 한다.
- 재고 시스템 실패와 같은 원격 서비스에 접근하는 경우, 제대로 복구되기를 원한다.
- 다른 나라 언어로도 텍스트를 보여줄 수 있다.
- 3과 7 사이에 비즈니스 규칙들이 추가될 수 있어야 한다.
- …
기술 및 데이터 변동 리스트
*a. 관리자가 판매 취소하는 것은 카드 판독기를 통해 판매 취소 카드를 읽히든지 키보
드로 인증 코드를 입력하는 것으로 수행된다.
3a. 품목 식별자는 (바코드가 있으면) 바코드 레이저 스캐너 또는 키보드로 입력된다.
3b. 품목 식별자는 UPC, EAN, JAN 또는 SKU의 작성 체계를 사용할 것이다.
7a. 신용카드 정보는 카드 판독기나 키보드로 입력된다.
목차UC1: ProcessSale-계속
7b. 카드 지불 서명은 영수증에 한다. 그러나 2년 안에 많은 고객들이 디지털 서명을
원할 것으로 예상된다.
발생 빈도 : 거의 지속적일 것이다.
해결할 문제
- 세법의 변동이 어떠한가?
- 원격 서비스 복구 문제에 대한 조사 필요
- 다른 비즈니스를 위해 어떤 수정사항이 필요한가?
- 출납원이 로그아웃할 떄 금전등록기를 가져가야 하는가?
- 고객이 직접 카드 판독기를 사용할 수 있는가? 아니면 출납원이 해야만 하는가?
목차UC2: HandleReturn★ -SSD수정됨
주요 성공 시나리오
1. 고객은 반품하기 위한 물건과 영수증을 가지
고 계산대에 온다.
2. 출납원이 영수증을 확인한다.
3. 출납원은 반품하고자 하는 물건의 상태를 확
인한다.
4. 출납원은 반품하고자 하는 물건을 반품 등록
한다.
5. 시스템은 환불영수증과 환불금액을 출력한다.
6. 출납원은 반품되는 각각의 물건을 기록하기
위해 POS 시스템을 사용한다.
대안 시나리오
4a. 만약 고객이 신용카드로 지불했는데 취소승
인 처리가 되지 않으면 고객에게 알리고 출납원
이 현금을 지불하게 한다.
4b. 만약 품목이 시스템상에서 검색되지 않으면,
출납원에게 알리고 식별 코드를 손으로 입력하게
한다(아마 등록된 자료가 손실되었을 것이다)
• SSD
: 출납원
:System
makeNewHandleReturn
enterHandleItem(HRitemID,quantiy)
description, total
loop [more items]
EndHandleReturn
Refund fare, receipt
Tatal with taxes
makeRepayment(amount)
목차UC3: CashIn
주요 성공 시나리오
1. 출납원은 회계과에 가서 자신의 사원카드를 회
계담당에게 제출한다
2. 회계담당은 시스템에서 사원카드와 업무일지를
확인하고 정해진 현금을 지불한다.
3. 지불 내용을 시스템에 기록한다.
대안 시나리오
2.a 출납원의 ID가 승인되지 않을 경우, 출납원의 신
상정보를 입력하여 승인한다.
2.b 정해진 현금보다 더 필요한 경우 지급한 후에 지
불 내용을 시스템에 기록한다.
:회계담당
:System
makeNewCashIn
IdentifyCasher(CasherID)
Identification
RecordCashIn(money)
목차UC4: CashOut
주요 성공 시나리오
1. 출납원은 금전등록기에서 로그아웃한다.
2. 시스템은 반납금액명세서를 출력한다.
3. 출납원은 금액이 맞는지를 확인한다.
대안 시나리오
3.a 금액이 맞지 않을 경우 맞지 않는 부분을 회계
과에게 청구한다.
출납원
:System
makeNewCashOut
Logout(CasherID)
RefundList
목차UC5: StartSaleTask
주요 성공 시나리오
1. 출납원은 수령한 현금을 금전등록기에 채우
고 로그인을 한다.
대안 시나리오
1.a 로그인이 되지 않을 경우 관리자에게 문
의 한다.
1.b 만약 id와 pw를 까먹었을 경우, 신상명세
를 입력하여 로그인 한다.
:System
StartSaleTask
LogIn(CasherID,,Password)
Identification
출납원
목차UC6: EndSaleTask
주요 성공 시나리오
1. 출납원은 회계부서로 이동하여 회계담당에게
반납금액명세서, 잔액 그리고 사원증을 제출한
다.
2. 회계담당은 사원번호를 입력하면 시스템은 잔
액을 보여준다
3. 회계담당은 잔액이 맞으면 입금 처리를 완료
한다
대안 시나리오
3a. 만약 정산 결과 지불 금액에 부족분이 있을 경
우에는 담당 출납원의 봉급에서 공제 시킨다.
:System
EndSaleTask
CheckCasher(CasherID)
balance
회계담당
목차Operation Contracts
• Process Sale
약정 CO1 : makeNewSale
오퍼레이션 : makeNewSale()
상호 참조 : 유스케이스 : Process Sale
사전조건 : 없음
사후조건 :
- Sale 인스턴스 s가 생성되었다(인스턴스 생성).
- s가 현재의 Register와 연관되었다(연관관계 형성).
- s의 속성들이 초기화 되었다.
약정 CO2 : enterItem
오퍼레이션 : enterItem(itemID : ItemID, quantity : integer)
상호 참조 : 유스케이스 : Process Sale
사전조건 : 판매가 진행 중이다.
사후조건 :
- SalesLineItem 인스턴스 sli가 생성되었다(인스턴스 생성).
- sli가 현재의 Sale과 연관되었다(연관관계 형성).
- sli.quantity가 quantity로 되었다(속성 수정).
- sli가 자신과 itemID값이 일치하는 ProductDescription과 연관되었다
(연관관계 형성).
목차Operation Contracts
약정 CO3 : endSale
오퍼레이션 : endSale()
상호 참조 : 유스케이스 : Process Sale
사전조건 : 판매가 진행 중이다.
사후조건 :
- Sale.isComplete가 true로 되었다(속성 수정).
약정 CO4 : makePayment
오퍼레이션 : makePayment(amount : Money)
상호 참조 : 유스케이스 : Process Sale
사전조건 : 판매가 진행 중이다.
사후조건 :
- Payment 인스턴스 p가 생성되었다(인스턴스 생성).
- p.amountTendered가 amount로 되었다(속성 수정).
- p가 현재의 Sale과 연관되었다(연관관계 형성).
현재의 Sale이 Store와 연관되었다(연관관계 형성);
(완료된 판매를 기록으로 남기기 위함)
목차Operation Contracts-계속
• Handle Returns
약정 CO1 : makeNewHandleReturn
오퍼레이션 : makeNewHandleReturn()
상호 참조 : 유스케이스 : Handle Returns
사전조건 : 없음
사후조건 :
- HandleReturn 인스턴스 HR이 생성되었다. (인스턴스 생성)
- HR이 현재의 Register와 연관되었다. (연관관계 생성)
- HR의 속성들이 초기화 되었다.
약정 CO2 : enterHandleItem
오퍼레이션 : enterHandleItem(HRitemID:HRitemID,quantity:integer)
상호 참조 : 유스케이스 : Handle Returns
사전조건 : 반품 처리가 진행 중이다.
사후조건 :
- HRitem 인스턴스 hri가 생성되었다(인스턴스 생성)
- hri가 현재의 HandleReturn 과 연관되었다(연관관계 형성)
- hri.quantity가 qunatity로 되었다(속성 수정)
- hri가 자신과 itemID값이 일치하는 ProductDescription과 연관되었다(연관관계 형성)
목차Operation Contracts-계속
약정 CO3 : EndHandleReturn
오퍼레이션 : EndHandleReturn()
상호 참조 : 유스케이스 : Handle Returns
사전조건 : 반품처리가 진행 중이다.
사후조건 :
- HandleReturns.isComplete가 true로 되었다(속성 수정)
목차Operation Contracts-계속
• CashIn
약정 CO1 : makeNewCashIn
오퍼레이션 : makeNewCashIn()
상호 참조 : 유스케이스 : CashIn
사전조건 : 없음
사후조건 :
- CashInOut 인스턴스 CSIO이 생성되었다. (인스턴스 생성)
- CSIO이 현재의 Register와 연관되었다. (연관관계 생성)
- CSIO의 속성들이 초기화 되었다.
- CSIO.state 가 In으로 되었다.
약정 CO2 : IdentifyCashier
오퍼레이션 : IdentifyCashier(CashierID:char)
상호 참조 : 유스케이스 : CashIn
사전조건 : 출납원의 ID가 있어야 한다.
사후조건 :
- Cashier 인스턴스 csh가 생성되었다(인스턴스 생성)
- csh.CashierID가 CashierID로 되었다(속성 수정)
- Csh가 CSIO와 연관되었다(연관관계 형성)
- csh가 자신과 CashierID값이 일치하는 CashierList과 연관되었다(연관관계 형성)
목차Operation Contracts-계속
약정 CO3 : RecordCashIn
오퍼레이션 RecordCashIn(money:integer)
상호 참조 : 유스케이스 : CashIn
사전조건 : 지불한 금액이 있어야 한다.
사후조건 :
- CSIO.money가 money로 되었다(속성 수정)
목차Operation Contracts-계속
• CashOut
약정 CO1 : makeNewCashOut
오퍼레이션 : makeNewCashOut()
상호 참조 : 유스케이스 : CashOut
사전조건 : 없음
사후조건 :
-CSIO.state가 out으로 되었다.
약정 CO2 : LogOut
오퍼레이션 : LogOut(CashierID:char)
상호 참조 : 유스케이스 : CashOut
사전조건 : Cashier이 Login되어 있다.
사후조건 :
- csh.login이 false로 되었다(속성 수정)
목차Operation Contracts-계속
• StartSaleTask
약정 CO1 : StartSaleTask
오퍼레이션 : StartSaleTask()
상호 참조 : 유스케이스 : StartSaleTask
사전조건 : 없음
사후조건 :
- SaleTask 인스턴스 ST이 생성되었다. (인스턴스 생성)
- ST이 현재의 Register와 연관되었다. (연관관계 생성)
- ST의 속성들이 초기화 되었다.
- 특히, ST.state가 start로 되었다(속성 수정)
약정 CO2 : LogIn
오퍼레이션 : LogIn(CashierID:char,Password:char)
상호 참조 : 유스케이스 : StartSaleTask
사전조건 : 출납원이 회계담당으로부터 현금을 수령하였다.
사후조건 :
- csh.login이 true로 되었다(속성 수정)
목차Operation Contracts-계속
• EndSaleTask
약정 CO1 : EndSaleTask
오퍼레이션 : EndSaleTask()
상호 참조 : 유스케이스 : EndSaleTask
사전조건 : 없음
사후조건 :
- ST.state가 end로 되었다(속성 수정)
약정 CO2 : CheckCashier
오퍼레이션 : CheckCashier(CashierID:char)
상호 참조 : 유스케이스 : EndSaleTask
사전조건 :
- 출납원이 회계담당에게 반납금액명세서, 잔액, 사원증을 제출하였다.
- SaleTask, ProcessSale 단계를 마친 상황이다.
사후조건 :
- csh가 자신과 CashierID값이 일치하는 CashierList과 연관이 해제되었다(연관관
계 해제)
목차보충명세서
개정 이력(revision history)
버전 일자 설명 저자
Inception 초안 2031.01.10 최초 버전. Elaboration 단계 동
안 주로 정제되어야 함
크레이그 라만
(Craig Larman)
목차보충명세서-계속
개요
이 문서에는 NextGen POS 의 요구사항 중 유스케이스에서 추출하지 못한 모든 요구
사항이 작성된다.
기능성
(많은 유스케이스 간의 공통적인 기능성)
로그인 및 오류 처리
모든 오류를 영구적인 저장서에 기록한다.
장착될 수 있는 규칙들
여러 유스케이스의 다양한 시나리오가 발생하는 지점이나 이벤트에서 실행된 임의의
규칙을 이용하여 시스템의 기능을 특화할 수 있도록 한다.
보안
모든 사용은 사용자 인증이 필요하다.
사용성
인적 요소
고객은 POS의 큰 모니터로 디스플레이를 볼 수 있어야 한다. 따라서
 문자는 1미터 거리에서 쉽게 판독할 수 있어야 한다.
목차보충명세서-계속
 색맹이 인식하기 어려운 색깔 조합을 피한다.
고객은 빨리 물건을 사서 상점을 나가기를 바라며 그렇지 못하면 구매한 경험을 긍정
적으로 인식하지 않는다. 따라서 시스템이 빠르고, 사용하기 쉬우며, 업무 처리시 오류
가 발생하지 않는 것 등은 판매 처리에서 중요한 요건이다.
출납원은 컴퓨터 화면이 아니라 고객과 구매 품목을 보면서 판매 처리한다. 따라서 그
래픽뿐만 아니라 소리로 신호나 경고를 하는 것도 필요하다.
신뢰성
복구성
외부 서비스(지불 인증기, 회계 시스템…)를 사용하는 데 문제가 발생하더라도, 판매 처
리를 계속 진행할 수 있도록 지역적인 해결 방법(예를 들어, 저장하고 진행하는)을 강
구해야 한다. 이 부분에는 더 많은 분석이 필요하다.
성능
인적 요소에서 언급했듯이, 구매자는 구매 절차가 신속히 이루어지기를 원한다. 여기서
문제가 되는 한 가지 요소가 외부 지불 인증이다. 우리의 목적은 발생 횟수의 90% 정
도가 1분 이내로 인증되는 것이다.
목차보충명세서-계속
지원성
적응성
NextGen POS에서의 여러 고객들은 판매 절차에 대한 다양한 비즈니스 규치과 처리
요구사항을 갖는다. 따라서 시나리오의 여러 시점에서(예를 들면, 새로운 판매가 시작
될 때나 새로운 판매 품목이 추가될 때), 장착될 수 있는 비즈니스 규칙이 적용될 수 있
다.
형상성
여러 고객들은 무거운(thick) 클라이언트 vs. 가벼운(thin) 클라이언트, 2-티어(tier)의 물
리적 계층 vs. N-티어의 물리적 계층 등과 같은 사용하는 POS 시스템에 대한 다양한
네트워크 형상을 요구할 것이다. 게다가 고객들은 비즈니스나 성능에 대한 요구사항을
반영하기 위해 이 형상들을 수정하기 원할 것이다. 따라서 시스템은 이러한 요구를
반영하기 위해 어느 정도 유연하게 형상화 할 수 있어야 한다. 유연성의 범위와 정
도 및 이를 위한 노력에 대한 분석이 더 필요하다.
구현 제약사항
NextGen 관리자들은 자바 기술 솔루션을 주장했다. 이는 자바가 개발하기 용이하
고 장기간의 이식성과 지원성을 높일 수 있을 것이라고 예상되기 때문이다.
목차보충명세서-계속
구매된 컴포넌트
 세금 계산기. 다른 나라에서도 사용 가능한 계산기를 지원해야 한다.
무료 오픈 소스 컴포넌트
프로젝트에 무료 자바 기술 오픈 소스 컴포넌트를 최대한 많이 사용할 것을
추천한다.
명확하게 컴포넌트를 설계하고 선택하는 것이 아직은 시기상조일지라도, 다
음과 같은 항목은 가능할 수 있다.
 Jlog로그 기록 프레임 워크
 …
인터페이스
주목할 만한 하드웨어와 인터페이스
 터치 스크린 모니터(운영체제에서는 일반적인 모니터로 인식되며 모니터 터치는 마
우스 이벤트로 인식된다.)
 바코드 레이저 스캐너(특수한 키보드에 주로 장착되며 읽혀진 입력은 소프트웨어 의
해 키가 입력된 것으로 인식된다.)
 영수증 프린터
 신용카드/직불카드 판독기
 서명 판독기(처음 배포하는 버전에는 없다.)
목차보충명세서-계속
소프트웨어 인터페이스
대부분의 외부 협력 시스템(세금 계산, 회계, 재고 등)을 사용하기 위해 다양한 시스템
및 인터페이스를 장착할 수 있어야 한다.
애플리케이션 종속적인 도메인(비즈니스) 규칙
(일반적인 규칙에 대한 분리된 비즈니스 규칙 문서를 참조하라.)
ID 규칙 변경성 원인
규칙 1 구매자 할인 규칙, 예:
직원 20% 할인
우수고객 10%할인
노인 15% 할인
높음.
각 소매상은 서로 다은 규
칙을 사용한다.
소매상 정책
규칙 2 판매(트랜잭션 수준) 할인 규칙.
세금 부과 전의 총액에 적용, 예:
100달러를 넘으면 10%할인
매주 월요일에 5%할인
오늘 오전 10시부터 오후 3시까지 10%할인
오늘 오전 9시부터 10시까지 두부 50%할인
높은.
각 소매상은 다른 규칙을
사용하고 일자별 또는 시
간별로 변경할 수 있다.
소매상 정책
규칙 3 제품별 할인 규칙, 예 :
이번 주는 트랙터 10% 할인
햄버거 2개 구매 시 무료 1개 추가
높음.
각 소매상은 다른 규칙을
사용하고 일자별 또는 시
간별로 변경할 수 있다.
소매상 정책
목차보충명세서-계속
법적 문제
오픈 소스 소프트웨어를 포함하는 제품의 재판매가 가능하도록 라이선스 규정이 해결
된다면, 오픈 소스 컴포넌트를 사용할 것을 추천한다.
모든 세금 관련 규정은 법에 의해 판매에 적용된다. 그러나 이 규정은 자주 바뀔 수 있
음을 유의하라.
관심 도메인 정보
가격 결정
도메인 규칙에 기술된 가격 결정 규칙뿐만 아니라, 제품에는 원래 가격이 있고 때에 따
라서는 영구적 인하가격도 있다. 만약 인하가격이 있다면, 더 많은 할인을 하기 이전의
제품 가격은 영구적 인하가격이다. 회계와 세금 문제가 있으므로 영구적 인하가격이
있더라도 제품의 원래 가격 정보를 갖고 있어야 한다.
신용카드 및 직불카드 지불 처리
지불 인증 서비스에서 신용카드 및 직불카드의 전자 지불이 승인되면, 구매자가 아니
라 판매자에게 구매 금액을 지불해야 한다. 결과적으로 각 지불에 대해, 판매자는 인증
서비스로부터 판매자의 외상계정에 금액을 기록해야 한다. 일반적으로 매일 밤, 인증
서비스는 판매자의 외상계정에 약간의 트랙잭션 수수료를 제하고 하루간의 승인 금액
을 전자식 자금 이체할 것이다.
목차보충명세서-계속
판매 세금
판매 세금 계산은 매우 복잡할 수 있고 일반적으로 정보의 행정지역 구분(도, 시,
군)에서의 법에 따라 구별한다. 따라서 외부 세금 계산 소프트웨어를 사용하는 것
이 바람직하다. 세금은 시, 도, 정부에 납부한다. 어떤 품목은 무조건 면세일 수 있
고, 어떤 품목은 구매자(예를 들어 농민, 어린이)에 따라 면세 될 수 있다.
품목 식별자 : UPC, EAN, SKU, 바코드, 바코드 판독기
NextGen POS는 다양한 품목 식별 체계를 지원해야 한다. UPC(universal product
codes, 국제 제품 코드), EAN(European article numbering, 유럽인 품목 번호체계),
SKU(stock keeping units, 재고 유지 단위)는 판매되는 제품을 위한 일반적인 세
가지 식별 체계이다. JAN(Japanese article numbers, 일본 품목 번호체계)은 EAN
의 한 종류 이다.
SKU는 완전한 소매상 임의의 식별자이다.
그러나 UPC와 EAN은 표준적이고 규정적인 컴포넌트를 갖는다. 전체를 개괄적으
로 살펴보기 위해서는 www.adams1.com/pub/russadam/upccode.html, www.uc-
council.org, www.ean-int.org를 참조할 수 있다.
목차용어집
비전 일자 설명 저자
Inception 초안 2011.10.10 최초 버전, Elaboration 단계 동안 주로
정제되어야 함
크레이그 라만(Craig Larman)
용어 정의 및 정보 형식 검증 규칙 별칭
품목 판매를 위한 제품이나 서비스
지불 인증 판매자에게 지불하거나 지불을 보증하는
외부 지불 인증 서비스에 의한 검증
지불 인증 요청 요소들이 합성되어 전자적으로 인증 서비
스에 전송된다.
요소에는 상점 ID, 고객계좌번호, 금액, 타
임스탬프가 있다
UPC 제품을 식별하는 번호로 된 코드, 보통 제
품에 붙은 바코드로 표시된다.
형식이나 검증에 대한 상세한 내용은
www.uc-nouncil.org를 참조하라.
여러 세부 부분으
로 구성된 12자리
코드
12번째 숫자는 체
크 비트이다.
세계 공통 제품
코드
개정 이력
정의
목차도메인 모델
• 도메인 모델을 그리는 과정에서는 정확한 모델을 만들기 위해 노력하지 않아도 된
다고 하기에 일단 개념적인 것들만 설계하였다.
목차시퀀스 다이어그램
• Process Sale
목차시퀀스 다이어그램
• Handle Returns
목차시퀀스 다이어그램
• Cash In
목차시퀀스 다이어그램
• Cash Out
목차설계 클래스 다이어그램(DCD)
• 도메인 모델은 개념적인 설계인데 비해, DCD는 S/W측면의 설계라고 하여서
구현하는 것 까지 염두에 두어서 그렸다. 도메인 모델과 약간 차이가 있다.
목차소스코드
목차소스코드-Casher.java
package com.foo.nextgen.domain;
public class Casher {
private String CasherID;
private String name;
public Casher(String _CasherID, String _name){
CasherID=_CasherID;
name=_name;
}
Public String getCasherID(){
return CasherID;
}
}
목차CasherList.java
package com.foo.nextgen.domain;
import java.util.*;
public class CasherList {
private Map<String, Casher>
Casherlist=new HashMap<String, Casher>();
public CasherList(){
Casher csh;
csh = new Casher("c100","park");
Casherlist.put("c100", csh);
csh = new Casher("c200","kim");
Casherlist.put("c200", csh);
csh = new Casher("c300","yoon");
Casherlist.put("c300", csh);
}
public Casher getCasherInfo(String id){
return Casherlist.get(id);
}
}
목차CashIn.java
package com.foo.nextgen.domain;
public class CashIn {
private CasherList casherlist;
private CashIOList cashIOlist;
Public CashIn(){
casherlist=new CasherList();
cashIOlist=new CashIOList();
}
public boolean IdentifyCasher(String CasherID){
if(casherlist.getCasherInfo(CasherID).getCasherID()==CasherID){ //존재한다면
System.out.println("Casher "+CasherID+" Identified..");
return true;
}//////must be
else{
System.out.println("Identification failed.. ");
return false;
} }
public void RecordCashIn(String CasherID, CashIODescription c_io_ds){
cashIOlist.pushIODescription(CasherID,c_io_ds);
}}
목차CashIODescription.java
package com.foo.nextgen.domain;
import java.util.*;
public class CashIODescription {
private String CasherID;
private int Date;
private int Money;
public CashIODescription(String CasherID, int Date, int Money){
this.CasherID=CasherID;
this.Date=Date;
this.Money=Money;
}
public String getCasherID() {return CasherID;}
public int getDate() {return Date;}
public int getMoney() {return Money; }
}
목차CashIOList.java
package com.foo.nextgen.domain;
import java.util.*;
public class CashIOList {
public static Map<String, CashIODescription>
CashIOlist=new HashMap<String, CashIODescription>();
public void pushIODescription(String CasherID, CashIODescription c_io_ds){
CashIOlist.put(CasherID, c_io_ds);
System.out.println("-------------------Cash In----------------------");
System.out.println("CasherID:"+CasherID+"/ Date:"+c_io_ds.getDate()+"/ Money:"+c_io_ds.getMoney());
}
public CashIODescription getCashIODescription(String CasherID){
return CashIOlist.get(CasherID);
}
}
목차CashOut.java
package com.foo.nextgen.domain;
public class CashOut {
public int logout(CashRegister cashregister, String CasherID){
return cashregister.logout(CasherID);
}
}
목차CashRegister.java
package com.foo.nextgen.domain;
////////////////// 금전 등록기
public class CashRegister {
private String CasherID;
private String password;
static int EarnedMoney;
public boolean login(String CasherID, String password){.
this.CasherID=CasherID;
this.password=password;
return true;
}
public void MoneyIn(int Money){
EarnedMoney+=Money;
}
public int logout(String CasherID){
System.out.println("logged Out...");
return EarnedMoney;
}
}
목차ProductCatalog.java
package com.foo.nextgen.domain;
import java.util.*;
public class ProductCatalog {
private Map<String, ProductDescription>
descriptions=new HashMap<String, ProductDescription>();
public ProductCatalog(){
String id1 = new String("100");
String id2 = new String("200");
int Money = 3;
ProductDescription desc;
desc = new ProductDescription(id1, Money, "product 1");
descriptions.put(id1, desc);
desc=new ProductDescription(id2, Money, "product 2");
descriptions.put(id2, desc);
//System.out.println(descriptions.get(id2).getDescription());
}
public ProductDescription getProductDescription(String id){
//System.out.println(descriptions.get(id).getDescription());
return descriptions.get(id);
}
}
목차ProductDescription.java
package com.foo.nextgen.domain;
public class ProductDescription {
private String id;
private int Money;
private String description;
public ProductDescription(String id, int Money, String description){
this.id=id;
this.Money=Money;
this.description=description;
}
public String getItemID() {return id;}
public int getPrice() {return Money;}
public String getDescription() {return description; }
}
목차Register.java
package com.foo.nextgen.domain;
public class Register {
private ProductCatalog catalog;
private Sale currentSale;
private CashIn currentCashIn;
private CashOut currentCashOut;
private CashRegister cashregister;
public Register(ProductCatalog catalog){
this.catalog=catalog;
}
public void endSale(){
currentSale.becomeComplete();
}
public void enterItem(String id, int quantity){
ProductDescription desc=catalog.getProductDescription(id);
currentSale.makeLineItem(desc,quantity);
}
public void makeNewSale(){
currentSale=new Sale();
}
public void makePayment(int cashTendered){
currentSale.makePayment(cashTendered);
}
public void makeNewCashIn(){
currentCashIn=new CashIn();
}
public boolean IdentifyCasher(String CasherID){
return currentCashIn.IdentifyCasher(CasherID);
}
public void RecordCashIn(String CasherID,
CashIODescription c_io_ds){
currentCashIn.RecordCashIn(CasherID, c_io_ds);
}
public void StartSaleTask(String CasherID, String
password){
cashregister=new CashRegister();
cashregister.login(CasherID, password);
cashregister.MoneyIn(300);
}
public void makeNewCashOut(){
currentCashOut=new CashOut();
}
public int LogOutCasher(String CasherID){
return currentCashOut.logout(cashregister, CasherID);
}
}
목차Sale.java
package com.foo.nextgen.domain;
import java.util.*;
public class Sale {
private List<SaleLineItem> lineItems= new
ArrayList<SaleLineItem>();
private boolean isComplete =false;
private int payment;
//private Payment payment;
public int getBalance(){ //거스름돈
return (payment-this.getTotal());
}
public void becomeComplete(){
isComplete=true;
System.out.println("Total : "+getTotal()+" Dollars");}
}
public void makeLineItem(ProductDescription
desc,int quantity){
lineItems.add(new SaleLineItem(desc,quantity));
System.out.println("itemID:"+desc.getItemID()+" /
quantity:"+quantity);
}
public int getTotal(){
int total=0;
int subtotal=0;
for(SaleLineItem lineItem : lineItems){
subtotal=lineItem.getSubtotal();
total+=subtotal;
}
return total;
}
public void makePayment(int cashTendered){
payment=cashTendered;
System.out.println("recieved cash : "+payment+"
Dollars");
System.out.println("balance : "+getBalance()+"
Dollars");
}
}
목차SaleLineItem.java
package com.foo.nextgen.domain;
public class SaleLineItem {
private int quantity;
private ProductDescription description;
public SaleLineItem(ProductDescription desc, int quantity){
this.description=desc;
this.quantity=quantity;
}
public int getSubtotal(){
return (description.getPrice()*quantity);
}
}
목차Store.javapackage com.foo.nextgen.domain;
public class Store {
private ProductCatalog catalog=new ProductCatalog();
private Register register=new Register(catalog);
public Store(){
System.out.println("-------------------Process Sale----------------------");
register.makeNewSale();
register.enterItem("100",1);
register.enterItem("200",2);
register.endSale();
register.makePayment(10);
System.out.println("-------------------Cash In----------------------");
register.makeNewCashIn();
if(register.IdentifyCasher("c300")){
register.RecordCashIn("c300",new CashIODescription("c300",20111222,300));
}
register.StartSaleTask("c300", "1234");
System.out.println("-------------------Cash Out----------------------");
register.makeNewCashOut();
System.out.println("returned money:"+register.LogOutCasher("c300"));
}
public Register getRegister(){return register;}
}
목차Main.java
package com.foo.nextgen.domain;
public class main {
public static void main(String[] args) {
// TODO Auto-generated method stub
new Store();
}
}
목차Test Code
• J-unit 프로그램을 이용하여 테스트하였다
• 모두 다 테스트해보지는 않았고, 문제를 일
으킬 가능성이 있는 unit만 테스트를 해 보
았다.
목차Test Code-CasherTest.java
package com.foo.nextgen.test;
import junit.framework.TestCase;
import com.foo.nextgen.domain.*;
public class CasherTest extends TestCase {
Casher casher=new Casher("c100","dd");
protected void setUp() throws Exception {
super.setUp();
}
public void testCasher() {
assertNotNull(casher);
//fail("Not yet implemented");
}
public void testGetCasherID() {
assertEquals(casher.getCasherID(),"c100");
//fail("Not yet implemented");
}
}
목차CashInTest.java
package com.foo.nextgen.test;
import junit.framework.TestCase;
import com.foo.nextgen.domain.*;
public class CashInTest extends TestCase {
CashIn cashin=new CashIn();
protected void setUp() throws Exception {
super.setUp();
}
public void testCashIn() {
assertNotNull(cashin);
//fail("Not yet implemented");
}
public void testIdentifyCasher() {
assertTrue(cashin.IdentifyCasher("c100"));
//fail("Not yet implemented");
}
}
목차CashIODescriptionTest.java
package com.foo.nextgen.test;
import junit.framework.TestCase;
import com.foo.nextgen.domain.*;
public class CashIODescriptionTest extends TestCase {
CashIODescription description=new CashIODescription("c100",2011,11);
protected void setUp() throws Exception {
super.setUp();
}
public void testCashIODescription() {
assertNotNull(description);
}
public void testGetCasherID() {
assertEquals(description.getCasherID(),"c100");
//fail("Not yet implemented");
}
public void testGetDate() {
assertEquals(description.getDate(),2011);
//fail("Not yet implemented");
}
public void testGetMoney() {
assertEquals(description.getMoney(),11);
//fail("Not yet implemented");
}
}
목차ProductCatalogTest.java
package com.foo.nextgen.test;
import junit.framework.TestCase;
import com.foo.nextgen.domain.*;
public class ProductCatalogTest extends TestCase {
ProductCatalog catalog=new ProductCatalog();
protected void setUp() throws Exception {
super.setUp();
}
public void testProductCatalog() {
assertNotNull(catalog);
//fail("Not yet implemented");
}
}
목차ProductDescriptionTest.java
package com.foo.nextgen.test;
import junit.framework.TestCase;
import com.foo.nextgen.domain.*;
public class ProductDescriptionTest extends TestCase {
ProductDescription description=new ProductDescription("100",11,"aa");
protected void setUp() throws Exception {
super.setUp();
}
public void testProductDescription() {
assertNotNull(description);
}
public void testGetItemID() {
assertEquals(description.getItemID(),"100");
}
public void testGetPrice() {
assertEquals(description.getPrice(),11);
//fail("Not yet implemented");
}
public void testGetDescription() {
assertEquals(description.getDescription(),"aa");
//fail("Not yet implemented");
}
}
목차Discussion
- Junit의 사용법을 몰라 한참 고생을 했다.
- 역공학으로 해야할지, 순공학으로 해야할지
결정하는데 시간이 꽤 걸렸다.
감사합니다. ♥

NextGen Pos System 프로젝트 산출물

  • 1.
    목차 NextGen POS System 프로젝트산출물 최종 보고서 (2010.12.21) 작성자: 박은지 학번: 20090544 학과: 컴퓨터공학과 과목: 소프트웨어공학
  • 2.
    목차목차 • 문서이력 • 분석 –비전 – 유스케이스 • 다이어그램 • 액티비티 다이어그램 • UC1: ProcessSale • ★ UC2: HandleReturn(2011.12.21수정) • UC3: CashIn • UC4: CashOut – 보충명세서 – Operation Contracts – 용어집 – 도메인 모델★ – 시퀀스 다이어그램★ – 설계 클래스 다이어그램 ★ – 소스코드★ – 테스트 코드★
  • 3.
    목차문서이력 버전 일자 설명비고 1차 과제 2011.10.08 교재의 내용을 단순 타이핑 2차 과제 2011.10.09 Handle, CashIn, CashOut 추가 3차 과제 2011.11.18. 다이어그램 , 유즈케이스1~4 수정 유즈케이스5,6 추가 SSD 추가 액티비티 다이어그램 추가 Operation Contracts 추가 4차 과제 2011.12.21 -도메인모델 -시퀀스 다이어그램 -DCD -소스코드 추가하고, -Handle Return SSD 수정
  • 4.
    목차비전 개정 이력 버전 일자설명 비고 Inception 초안 2011.10.10 최초 버전. Elaboration 단계 동안 주로 정제되어야 함 크레이그 라만 (Craig Laman) Elaboration 2011.10.11 정제된 버전. 세부사항에 대한 수정
  • 5.
    목차비전-계속 개요 우리는 다음 버전으로결함 허용성을 가진 NextGen POS 애플리케이션을 계획하며 이 애플리케이션은 다양한 고객의 비즈니스 규칙, 여러 터미널과 사용자 인터페이스 매커 니즘, 제 3자에 의해 개발된 지원 시스템과의 연동 등을 지원해야 한다. 위치화(positioning) 사업적 기회 현재의 POS 제품들은 비즈니스 규칙과 네트워크 설계를 다양화하는 측면에서 고객의 업무에 적합하지 않다. 그리고 터미널과 비즈니스가 증가하는 것에 대응하지 못한다. 또 한 실패에 따라 그때그때 조정하면서 온라인과 오프라인에서 작업할 수 없고, 다른 3자 에 의해 개발된 시스템과 연동도 어렵다. 무선 PDA와 같은 새로운 터미널 기술에 적용 하기도 어렵다. 이렇게 유연하지 못한 현재의 POS 제품 상태에 시장이 만족하지 못하고, 이를 충족시키는 POS 시스템에 대한 요구가 있다. 문제 기술 기존의 POS 시스템은 유연하지 않고, 결함 허용성을 제공하지 않으며, 제 3자에 의해 개발된 시스템과 연동하기도 어렵다. 따라서 적시에 판매 처리하고, 그 소프트웨어에 맞 지 않는 개선된 프로세스를 만들며, 다른 문제들 사이에서 측정과 계획을 세우는 데 필 요한 정확한 회계 및 재고 데이터를 적시에 지원하는 것들이 어렵게 된다. 그리고 이러 한 어려움은 출납원, 매장 관리자, 시스템 관리자, 회사 관리에 영향을 준다. 제품 위치 기술 현재의 시스템은 작은 규모의 상점에서부터 대형 마트에 이르기까지 다양한 규모의 상 점을 대상으로 계획 및 작성되었다.
  • 6.
    목차비전-계속 관련자 설명 관련자들의 중요한상위 수준 목적 및 문제 주제 분야 전문가와 다른 관련자들이 참여한 하루 동안의 요구사항 워크숍과 여러 소 매점에서의 조사를 통해 다음과 같이 핵심 목표와 문제를 식별하였다. 상위 수준의 목 적 우선 순 위 문제 및 관심 현재 해결책 빠르고, 견고하며 통합된 판매 처리 높음 부하가 증가함에 따라 속도 감소, 컴포넌트의 기능이 실패하면 판매 처리 능력 감소, 기존의 회계, 재고, 인사 관리 시스템과 통합되지 못함으로 인해 회계나 기타 시 스템으로부터의 최근의 정확한 정보 부 족, 측정 및 계획의 어려움 초래. 비즈니스 규칙을 고유한 비즈니스 요구 사항에 맞추는 능력 부족. 새로운 유형의 터미널이나 사용자 인터 페이스(예를 들어, 모바일 PDA) 추가에 대한 어려움. 기존의 POS 제품들은 이러한 문제의 해결 없이 유스케이스 기본 적인 판매 모델링에서 생성된 액터-목적 처 리 기능을 제공한다. … … …
  • 7.
    목차비전-계속 사용자 수준의 목적 사용자(와외부 시스템)는 다음과 같은 목적을 수행하는 시스템을 원한다.  출납원 : 판매 처리, 반품 처리, 출납 업무 개시, 출납 업무 종료  시스템 관리자 : 사용자 관리, 보안 관리, 사용자 테이블 관리  관리자 : 시스템 시작, 시스템 종료  영업 관리 시스템 : 판매 데이터 분석 제품 개요 제품의 전망 NextGen POS는 주로 상점 내에 설치될 것이다. 만약 이동 터미널을 사용한다면, 상점 안이든 또는 외부 근처이든 상점의 네트워크 근처에 있을 것이다. 그림 비전-1에서처 럼, POS 시스템은 사용자에게 서비스를 제공하고, 다른 시스템과 연동할 것이다. <<actor>> 영업 관리 시스템 출납원 시스템 관리자 상점 관리자 <<actor>> 회계 시스템 <<actor>> 세금 계산기 <<actor>> 지불 인증 서비스 <<actor>> 인사 관리 시스템 <<actor>> 재고 시스템 NextGen POS 서비스 요청 서비스 요청 그림 비전-1 NextGen POS 시스템 컨텍스트 다이어그램
  • 8.
    목차비전-계속 이점 요약 지원하는 특징관련자의 이점 기능적으로 시스템은 판매 내역 파악, 지불 인증, 반품 처 리 등을 포함하여 판매 조직이 요구하는 모든 일반적인 서 비스를 제공 자동화되고 빠른 POS 서비스 서비스를 이용할 수 없는 경우에 대비하여, 실패의 자동 감 지, 지역 오프라인 처리로의 전환 외부 컴포넌트의 작동 실패에 도 지속적인 판매 처리 판매 처리 동안 다양한 시나리오의 지점에 장착할 수 있는 비즈니스 규칙 유연한 비즈니스 로직 구성 사업 표준 프로토콜을 사용하여 제 3자에 의해 개발된 시 스템과의 실시간 트랜잭션 측정과 계획 지원을 위한 적시 의 정확한 판매, 회계, 재고 정 보 …
  • 9.
    목차비전-계속 시스템 피처의 요약 판매 내역 파악  지불 인증(신용카드, 직불카드, 수표)  사용자, 보안, 코드, 상수 테이블 등에 대한 시스템 관리  외부 컴포넌트의 기능 실패 시, 자동 오프라인 판매 처리  재고, 회계, 인사, 세금 계산, 지불 인증을 포함한 산업 표준에 기초를 둔, 제 3자에 의해 개발된 시스템과의 실시간 트랜잭션  처리 시나리오에서 어떤 고정된 일반적인 지점에 장착할 수 있는 비즈니스 규칙을 정의하고 이행  … 그 밖의 요구사항 및 제약사항 설계 제약사항, 사용성, 신뢰성, 성능, 지원성, 문서화, 패키징 등이 포함된다. 보충 명세 서와 유스케이스를 참조하라.
  • 10.
    목차유스케이스 버전 일자 설명비고 Inception 초안 2011.10.10 최초 버전. Elaboration 단계 동안 주로 정제되어야 함 크레이그 라만 (Craig Laman) Elaboration 2011.10.11 정제된 버전. 세부사항에 대한 수정
  • 11.
    목차유즈케이스 다이어그램 Process Sale Handle Returns CashIn Cash Out System Start Up StartSaleTask EndSaleTask 회계담당 관리자 출납원
  • 12.
    목차액티비티 다이어그램 • NextGenPOS system 출납원 회계담당 Cash In StartSaleTask Process Sale EndSaleTask Cash Out
  • 13.
    목차UC1: ProcessSale 범위 :NextGen POS 애플리케이션 수준 : 사용자의 목적 주요 액터 : 출납원 관련자 및 관심사항 - 출납원 : 정확하고 빠른 입력을 원하며 현금 지불 금액에 대한 부족분은 담당 출납 원의 봉급에서 공제되므로 지불상의 오류가 없기를 원한다. - 판매원 : 판매수수료가 갱신되기를 원한다. - 고객 : 최소의 노력으로 구매하고 빠른 서비스를 받기 원한다. 판매되는 물건의 가 격을 쉽게 보기 원한다. 반품할 때를 위한 구매의 증거물을 원한다. - 회사 : 발생하는 거래를 정확하게 기록하고 고객의 요구를 충족시키기를 원한다. 지 불 인증 서비스의 지불 수취계정에 확실히 기록되길 원한다. 서버 컴포넌트(원격 신 용 검증 등)의 사용이 불가능할 때도 시스템은 결함을 허용(fault tolerace)해서 판매 정보를 얻을 수 있기를 원한다. 회계 및 재고 정보가 자동으로 빠르게 갱신되기 원 한다. - 관리자 : 취소 기능이 빨리 수행될 수 있기를 원하고 출납원의 문제를 쉽게 찾아 해 결하기를 원한다. - 세무서 : 모든 판매 건에 대해 세금을 징수하기 원한다. 국가, 도, 시와 같은 여러 개 의 기관이 있을 수 있다. - 지불 인증 서비스 : 정확한 형식과 프로토콜을 따르는 디지털 인증 요청을 받기 원 한다. 상점에 지불한 내역이 정확하게 계산되기를 원한다.
  • 14.
    목차UC1: ProcessSale-계속 사전조건 :출납원이 식별되고 인증된다. 성공 보증(또는 사후조건) : 판매 자료는 저장된다. 세금 은 정확하게 계산된다. 회계 및 재고 정보가 갱신된다. 수 수료가 기록된다. 영수증이 생성된다. 지불 인증 승인이 기록된다. 주요 성공 시나리오(또는 기본 흐름) 1. 고객은 구매하고자 하는 물품이나 서비스를 가지고 POS 계산대에 온다. 2. 출납원은 새로운 판매를 시작한다. 3. 출납원은 품목 식별자를 입력한다. 4. 시스템은 품목을 기록하고 품목의 설명, 가격 그리고 현재까지의 금액 합계를 보여준다. 가격은 가격 결정 규칙을 통해 계산한다. 출납원은 모든 구매 품목에 대해 단계 3~4를 반복한다. 5. 시스템은 세금을 포함한 총액을 보여준다. 6. 출납원은 고객에게 총액을 말하고 지불을 요청한다. 7. 고객은 지불하고 시스템은 지불 처리한다. 8. 시스템은 완료된 판매를 기록하고 판매 및 지불 정보 를 외부 회계 시스템(회계와 수수료 처리를 위해)과 재고 관리 시스템(재고 정보를 갱신하기 위해)으로 전송한다. 9. 시스템은 영수증을 발행한다. 10. 고객은 영수증과 물품을 가지고 나간다. • SSD : 출납원 :System makeNewSale enterItem(itemID, quantiy) description, total loop [more items] endSale total with taxes makePayment(amount) change due, receipt
  • 15.
    목차UC1: ProcessSale-계속 확장 (또는대안 흐름) *a. 언제든지, 관리자가 판매 취소 기능을 요구하는 경우 1. 시스템은 관리자-인증 모드로 들어간다. 2. 관리자나 출납원은 한 관리자-모드 오퍼레이션을 수행한다. 예를 들어 현금 잔 액 변경, 다른 등록기에서 중지된 판매 재개, 판매 취소 등. 3. 시스템은 출납원-인증 모드로 되돌아간다. *b. 언제든지, 시스템이 실패한 경우 회계 정보를 복구하고 수정하기 위해 모든 거래에 연결된 상태와 이벤트는 시나리 오의 어떤 단계에서도 복구될 수 있음을 확인한다. 1. 출납원은 시스템을 재시작하고 이전 상태로의 복구를 요청한다. 2. 시스템은 이전 상태로 복구한다. 2a. 시스템이 복구되는 데 방해가 되는 예외적인 것들이 발생하는 경우 1. 시스템은 출납원에게 오류를 표시하고, 이를 기록하며 초기의 깨끗한 상태로 들어간다. 2. 출납원은 새로운 판매를 시작한다. 1a. 고객이나 관리자는 일시정지된 판매 처리를 다시 시작할 것을 지시한다. 1. 출납원은 재시작 기능을 수행하고 판매 내역을 확인하기 위해 ID를 입력한다. 2. 시스템은 다시 시작할 판매 상태를 현재까지의 소계와 함께 보여준다.
  • 16.
    목차UC1: ProcessSale-계속 2a. 판매건을 찾지 못했다. 1. 시스템은 출납원에게 오류를 보여준다. 2. 출납원은 새로운 판매를 시작하고 모든 품목을 다시 입력해야 할 것이 다. 3. 출납원은 판매 처리를 계속 진행한다(남아 있는 품목을 입력하거나 지불 처리한 다). 2-4a. 고객은 출납원에게 자신이 비과세 대상자라는 것을 알린다(예를 들어, 노인이나 주민). 1. 출납원은 확인하고 비과세 상태 코드를 입력한다. 2. 시스템은 세금 계산 처리 시 사용할 비과세 상태를 기록한다. 3a. 유효하지 않은 ID(시스템에서 찾을 수 없는 경우) 1. 시스템은 오류를 보여주고 입력을 막는다. 2. 출납원이 오류에 반응한다. 2a. 사람이 판독할 수 있는 품목 ID(예를들어 UPC) 가 있는 경우 1. 출납원은 손으로 품목 ID를 입력한다. 2. 시스템은 품목의 설명과 가격을 보여준다. 2a. 유효하지 않은 ID일 경우 시스템은 오류를 보여주고 출납원은 다 른 방법을 시도해 본다.
  • 17.
    목차UC1: ProcessSale-계속 2b. 품목의ID가 없고 태그에 가격만 표시되어 있는 경우 1. 출납원은 관리자가 판매 취소 처리를 수행하기를 요청한다. 2. 관리자는 판매 취소 기능을 수행한다. 3. 출납원은 가격을 손으로 입력하고 입력한 금액에 대한 표준 세금을 받 는다. (제품에 대한 정보가 없기 때문에 세금 계산 엔진이 어떻게 과세 해야 하는지 알 수 없다). 2c. 출납원은 품목의 ID 및 가격을 알기 위해 Find Product Help를 수행한다. 2d. 그렇지 않으면, 출납원은 직원에게 품목의 ID나 가격을 물어보고 손으로 ID 또는 가격을 입력한다(위를 참조하라). 3b. 같은 품목이 여러 개 이고, 각각의 품목을 식별하는 것은 중요하지 않을 경우(예를 들어, 햄버거 5개) 1. 출납원은 한 품목의 식별자와 수량을 입력할 수 있다. 3c. 품목 종류와 가격을 손으로 입력해야 하는 품목일 경우(판매 상품에 가격이 추가되 는 꽃이나 카드 같은) 1. 출납원은 한 품목의 식별자와 수량을 입력할 수 있다. 3-6a: 고객이 구매한 품목 중 한 품목을 삭제해 주기를 요청하는 경우 품목의 가격이 출납원이 처리 가능한 무효 제한 가격보다 작을 때만 가능하다. 그 렇지 않으면 관리자에게 판매 취소를 요청해야 한다.
  • 18.
    목차UC1: ProcessSale-계속 1. 출납원은판매 내역에서 삭제할 품목의 식별자를 입력한다. 2. 시스템은 품목을 지우고 수정된 전체 금액을 보여준다. 2a. 품목의 가격이 출납원의 무효 제한 금액을 초과하는 경우 1. 시스템은 오류를 보여주고, 관리자가 판매 취소 처리하기를 제안한다. 2. 출납원은 관리자에게 판매 취소 처리를 요청한 후 처리되면 작업을 계 속한다. 3-6b. 고객이 출납원에게 판매를 취소할 것을 요청하는 경우 1. 출납원은 시스템에서 판매를 취소한다. 3-6c. 출납원이 판매 처리를 일시중지할 경우 1. 시스템은 다른 POS 등록기에서도 조회가 가능하도록 판매 내역을 기록한다. 2. 시스템은 판매 내역을 조회하고 판매 처리를 다시 시작할 수 있도록 품목과 판매 ID를 “일시중지 영수증”에 보여준다. 4a. 품목 가격이 원하던 가격이 아닌 경우(예를 들어, 고객이 어떤 품목에 대해 불평하 며 낮은 가격을 요구할 때) 1. 출납원은 관리자에게 승인을 요청한다. 2. 관리자는 판매 취소 처리한다 3. 출납원은 손으로 변경된 가격을 입력한다 4. 시스템은 새로운 가격을 보여준다
  • 19.
    목차UC1: ProcessSale-계속 5a. 시스템이외부 세금 계산 시스템과 통신하는 데 실패한 경우 1. 시스템은 POS 단말기의 외부 시스템과의 통신 서비스를 재시작하고 계속한다. 1a. 시스템은 서비스 재시작이 안 되는 것을 발견한다. 1. 시스템은 오류를 보여준다. 2. 출납원은 세금을 직접 계산해서 입력하거나 판매 처리를 취소한다. 5b. 고객이 자신이 할인 대상자라고 말하는 경우(예를 들어 직원, 우수고객) 1. 출납원은 할인 요청 신호를 보낸다. 2. 출납원은 고객 식별자를 입력한다. 3. 시스템은 할인 규칙에 의한 할인 총액을 보여준다. 5c. 고객이 판매에 사용할 수 있는 적립금이 있다고 말하는 경우 1. 출납원은 적립금 요청 신호를 보낸다. 2. 출납원은 고객 식별자를 입력한다. 3. 시스템은 가격 총액 범위 내에서 적립금을 이용하고 적립액을 감소시킨다. 6a. 고객은 현금으로 지불하려고 했지만 현금이 충분하지 않다고 말하는 경우 1. 출납원은 다른 지불 방법을 얘기한다. 1a. 고객은 구매를 취소한다고 말한다. 출납원은 판매를 취소한다. 7a. 현금으로 지불하는 경우 1. 출납원은 지불된 금액을 입력한다. 2. 시스템은 거스름돈 액수를 보여주고 금전등록기 서랍을 연다. 3. 출납원은 받은 현금을 넣고 고객에게 거스름돈을 건넨다.
  • 20.
    목차UC1: ProcessSale-계속 4. 시스템은현금 지불 금액을 기록한다. 7b. 신용카드로 지불하는 경우 1. 고객은 신용카드 정보를 입력한다. 2. 시스템은 검증을 위해 입력한 지불 내역을 보여준다. 3. 출납원은 확인한다. 3a. 출납원이 지불 단계를 취소하는 경우 1. 시스템은 “품목 입력” 상태로 되돌린다. 4. 시스템은 지불 인증 요청을 외부 지불 인증 시스템으로 보내고 지불 승인을 요 청한다. 4a. 시스템이 외부 시스템과의 연동에 실패했을 경우 1. 시스템은 출납원에게 오류를 보여준다. 2. 출납원은 다른 방법으로 지불하기를 요청한다. 5. 시스템은 지불 승인을 받아 출납원에게 승인 처리됨을 알리고 고객이 서명한 신용카드 지불 영수증을 넣기 위해 금전등록기 서랍을 연다. 5a. 시스템이 지불 거부를 응답받은 경우 1. 시스템은 출납원에게 지불이 거부되었음을 알린다. 2. 출납원은 다른 방법으로 지불하기를 요청한다. 5b. 승인 응답 시간을 초과한 경우 1. 시스템은 출납원에게 응답 시간이 초과했음을 알린다. 2. 출납원은 다시 시도해 보거나 고객에게 다른 방법으로 지불허가를 요 청한다.
  • 21.
    목차UC1: ProcessSale-계속 6. 시스템은지불 승인된 카드 지불 내역을 기록한다. 7. 시스템은 카드 지불 서명 방법을 보여준다. 8. 출납원은 고객이 카드 지불에 서명하기를 요청한다. 고객은 서명한다. 9. 영수증에 서명하면, 출납원은 금전등록기에 영수증을 넣고 서랍을 닫는다. 7c. 수표로 지불하는 경우 7d. 직불카드로 지불하는 경우 7e. 출납원이 지불 단계를 취소한 경우 1. 시스템은 “품목 입력” 모드로 복귀한다. 7f. 고객이 쿠폰을 내는 경우 1. 지불 처리하기 전에 출납원은 각 쿠폰을 기록하고 시스템은 책정된 가격을 뺀 다. 시스템은 회계 처리의 근거로 사용된 쿠폰을 기록한다. 1a. 구매 품목 중 입력된 쿠폰을 사용할 수 있는 품목이 없는 경우 1. 시스템은 출납원에게 오류를 보여준다. 9a. 환불되는 제품이 있는 경우 1. 시스템은 환불되는 각 품목에 대해 환불 양식과 영수증을 발행한다. 9b. 고객이 가격이 보이지 않는 선물용 영수증을 요구하는 경우 1. 출납원은 선물용 영수증을 요청하고 시스템은 그 영수증을 발행한다. 9c. 프린터에 용지가 없다.
  • 22.
    목차UC1: ProcessSale-계속 1. 시스템이발견할 수 있으면 문제를 알릴 것이다. 2. 출납원은 용지를 넣는다. 3. 출납원은 다른 영수증을 요청한다. 특수한 요구사항 - 큰 평면 모니터의 터치 스크린 UI, 문자는 1미터 내에서도 보여야 한다. - 카드 인증의 90%는 30초 이내에 응답되어야 한다. - 재고 시스템 실패와 같은 원격 서비스에 접근하는 경우, 제대로 복구되기를 원한다. - 다른 나라 언어로도 텍스트를 보여줄 수 있다. - 3과 7 사이에 비즈니스 규칙들이 추가될 수 있어야 한다. - … 기술 및 데이터 변동 리스트 *a. 관리자가 판매 취소하는 것은 카드 판독기를 통해 판매 취소 카드를 읽히든지 키보 드로 인증 코드를 입력하는 것으로 수행된다. 3a. 품목 식별자는 (바코드가 있으면) 바코드 레이저 스캐너 또는 키보드로 입력된다. 3b. 품목 식별자는 UPC, EAN, JAN 또는 SKU의 작성 체계를 사용할 것이다. 7a. 신용카드 정보는 카드 판독기나 키보드로 입력된다.
  • 23.
    목차UC1: ProcessSale-계속 7b. 카드지불 서명은 영수증에 한다. 그러나 2년 안에 많은 고객들이 디지털 서명을 원할 것으로 예상된다. 발생 빈도 : 거의 지속적일 것이다. 해결할 문제 - 세법의 변동이 어떠한가? - 원격 서비스 복구 문제에 대한 조사 필요 - 다른 비즈니스를 위해 어떤 수정사항이 필요한가? - 출납원이 로그아웃할 떄 금전등록기를 가져가야 하는가? - 고객이 직접 카드 판독기를 사용할 수 있는가? 아니면 출납원이 해야만 하는가?
  • 24.
    목차UC2: HandleReturn★ -SSD수정됨 주요성공 시나리오 1. 고객은 반품하기 위한 물건과 영수증을 가지 고 계산대에 온다. 2. 출납원이 영수증을 확인한다. 3. 출납원은 반품하고자 하는 물건의 상태를 확 인한다. 4. 출납원은 반품하고자 하는 물건을 반품 등록 한다. 5. 시스템은 환불영수증과 환불금액을 출력한다. 6. 출납원은 반품되는 각각의 물건을 기록하기 위해 POS 시스템을 사용한다. 대안 시나리오 4a. 만약 고객이 신용카드로 지불했는데 취소승 인 처리가 되지 않으면 고객에게 알리고 출납원 이 현금을 지불하게 한다. 4b. 만약 품목이 시스템상에서 검색되지 않으면, 출납원에게 알리고 식별 코드를 손으로 입력하게 한다(아마 등록된 자료가 손실되었을 것이다) • SSD : 출납원 :System makeNewHandleReturn enterHandleItem(HRitemID,quantiy) description, total loop [more items] EndHandleReturn Refund fare, receipt Tatal with taxes makeRepayment(amount)
  • 25.
    목차UC3: CashIn 주요 성공시나리오 1. 출납원은 회계과에 가서 자신의 사원카드를 회 계담당에게 제출한다 2. 회계담당은 시스템에서 사원카드와 업무일지를 확인하고 정해진 현금을 지불한다. 3. 지불 내용을 시스템에 기록한다. 대안 시나리오 2.a 출납원의 ID가 승인되지 않을 경우, 출납원의 신 상정보를 입력하여 승인한다. 2.b 정해진 현금보다 더 필요한 경우 지급한 후에 지 불 내용을 시스템에 기록한다. :회계담당 :System makeNewCashIn IdentifyCasher(CasherID) Identification RecordCashIn(money)
  • 26.
    목차UC4: CashOut 주요 성공시나리오 1. 출납원은 금전등록기에서 로그아웃한다. 2. 시스템은 반납금액명세서를 출력한다. 3. 출납원은 금액이 맞는지를 확인한다. 대안 시나리오 3.a 금액이 맞지 않을 경우 맞지 않는 부분을 회계 과에게 청구한다. 출납원 :System makeNewCashOut Logout(CasherID) RefundList
  • 27.
    목차UC5: StartSaleTask 주요 성공시나리오 1. 출납원은 수령한 현금을 금전등록기에 채우 고 로그인을 한다. 대안 시나리오 1.a 로그인이 되지 않을 경우 관리자에게 문 의 한다. 1.b 만약 id와 pw를 까먹었을 경우, 신상명세 를 입력하여 로그인 한다. :System StartSaleTask LogIn(CasherID,,Password) Identification 출납원
  • 28.
    목차UC6: EndSaleTask 주요 성공시나리오 1. 출납원은 회계부서로 이동하여 회계담당에게 반납금액명세서, 잔액 그리고 사원증을 제출한 다. 2. 회계담당은 사원번호를 입력하면 시스템은 잔 액을 보여준다 3. 회계담당은 잔액이 맞으면 입금 처리를 완료 한다 대안 시나리오 3a. 만약 정산 결과 지불 금액에 부족분이 있을 경 우에는 담당 출납원의 봉급에서 공제 시킨다. :System EndSaleTask CheckCasher(CasherID) balance 회계담당
  • 29.
    목차Operation Contracts • ProcessSale 약정 CO1 : makeNewSale 오퍼레이션 : makeNewSale() 상호 참조 : 유스케이스 : Process Sale 사전조건 : 없음 사후조건 : - Sale 인스턴스 s가 생성되었다(인스턴스 생성). - s가 현재의 Register와 연관되었다(연관관계 형성). - s의 속성들이 초기화 되었다. 약정 CO2 : enterItem 오퍼레이션 : enterItem(itemID : ItemID, quantity : integer) 상호 참조 : 유스케이스 : Process Sale 사전조건 : 판매가 진행 중이다. 사후조건 : - SalesLineItem 인스턴스 sli가 생성되었다(인스턴스 생성). - sli가 현재의 Sale과 연관되었다(연관관계 형성). - sli.quantity가 quantity로 되었다(속성 수정). - sli가 자신과 itemID값이 일치하는 ProductDescription과 연관되었다 (연관관계 형성).
  • 30.
    목차Operation Contracts 약정 CO3: endSale 오퍼레이션 : endSale() 상호 참조 : 유스케이스 : Process Sale 사전조건 : 판매가 진행 중이다. 사후조건 : - Sale.isComplete가 true로 되었다(속성 수정). 약정 CO4 : makePayment 오퍼레이션 : makePayment(amount : Money) 상호 참조 : 유스케이스 : Process Sale 사전조건 : 판매가 진행 중이다. 사후조건 : - Payment 인스턴스 p가 생성되었다(인스턴스 생성). - p.amountTendered가 amount로 되었다(속성 수정). - p가 현재의 Sale과 연관되었다(연관관계 형성). 현재의 Sale이 Store와 연관되었다(연관관계 형성); (완료된 판매를 기록으로 남기기 위함)
  • 31.
    목차Operation Contracts-계속 • HandleReturns 약정 CO1 : makeNewHandleReturn 오퍼레이션 : makeNewHandleReturn() 상호 참조 : 유스케이스 : Handle Returns 사전조건 : 없음 사후조건 : - HandleReturn 인스턴스 HR이 생성되었다. (인스턴스 생성) - HR이 현재의 Register와 연관되었다. (연관관계 생성) - HR의 속성들이 초기화 되었다. 약정 CO2 : enterHandleItem 오퍼레이션 : enterHandleItem(HRitemID:HRitemID,quantity:integer) 상호 참조 : 유스케이스 : Handle Returns 사전조건 : 반품 처리가 진행 중이다. 사후조건 : - HRitem 인스턴스 hri가 생성되었다(인스턴스 생성) - hri가 현재의 HandleReturn 과 연관되었다(연관관계 형성) - hri.quantity가 qunatity로 되었다(속성 수정) - hri가 자신과 itemID값이 일치하는 ProductDescription과 연관되었다(연관관계 형성)
  • 32.
    목차Operation Contracts-계속 약정 CO3: EndHandleReturn 오퍼레이션 : EndHandleReturn() 상호 참조 : 유스케이스 : Handle Returns 사전조건 : 반품처리가 진행 중이다. 사후조건 : - HandleReturns.isComplete가 true로 되었다(속성 수정)
  • 33.
    목차Operation Contracts-계속 • CashIn 약정CO1 : makeNewCashIn 오퍼레이션 : makeNewCashIn() 상호 참조 : 유스케이스 : CashIn 사전조건 : 없음 사후조건 : - CashInOut 인스턴스 CSIO이 생성되었다. (인스턴스 생성) - CSIO이 현재의 Register와 연관되었다. (연관관계 생성) - CSIO의 속성들이 초기화 되었다. - CSIO.state 가 In으로 되었다. 약정 CO2 : IdentifyCashier 오퍼레이션 : IdentifyCashier(CashierID:char) 상호 참조 : 유스케이스 : CashIn 사전조건 : 출납원의 ID가 있어야 한다. 사후조건 : - Cashier 인스턴스 csh가 생성되었다(인스턴스 생성) - csh.CashierID가 CashierID로 되었다(속성 수정) - Csh가 CSIO와 연관되었다(연관관계 형성) - csh가 자신과 CashierID값이 일치하는 CashierList과 연관되었다(연관관계 형성)
  • 34.
    목차Operation Contracts-계속 약정 CO3: RecordCashIn 오퍼레이션 RecordCashIn(money:integer) 상호 참조 : 유스케이스 : CashIn 사전조건 : 지불한 금액이 있어야 한다. 사후조건 : - CSIO.money가 money로 되었다(속성 수정)
  • 35.
    목차Operation Contracts-계속 • CashOut 약정CO1 : makeNewCashOut 오퍼레이션 : makeNewCashOut() 상호 참조 : 유스케이스 : CashOut 사전조건 : 없음 사후조건 : -CSIO.state가 out으로 되었다. 약정 CO2 : LogOut 오퍼레이션 : LogOut(CashierID:char) 상호 참조 : 유스케이스 : CashOut 사전조건 : Cashier이 Login되어 있다. 사후조건 : - csh.login이 false로 되었다(속성 수정)
  • 36.
    목차Operation Contracts-계속 • StartSaleTask 약정CO1 : StartSaleTask 오퍼레이션 : StartSaleTask() 상호 참조 : 유스케이스 : StartSaleTask 사전조건 : 없음 사후조건 : - SaleTask 인스턴스 ST이 생성되었다. (인스턴스 생성) - ST이 현재의 Register와 연관되었다. (연관관계 생성) - ST의 속성들이 초기화 되었다. - 특히, ST.state가 start로 되었다(속성 수정) 약정 CO2 : LogIn 오퍼레이션 : LogIn(CashierID:char,Password:char) 상호 참조 : 유스케이스 : StartSaleTask 사전조건 : 출납원이 회계담당으로부터 현금을 수령하였다. 사후조건 : - csh.login이 true로 되었다(속성 수정)
  • 37.
    목차Operation Contracts-계속 • EndSaleTask 약정CO1 : EndSaleTask 오퍼레이션 : EndSaleTask() 상호 참조 : 유스케이스 : EndSaleTask 사전조건 : 없음 사후조건 : - ST.state가 end로 되었다(속성 수정) 약정 CO2 : CheckCashier 오퍼레이션 : CheckCashier(CashierID:char) 상호 참조 : 유스케이스 : EndSaleTask 사전조건 : - 출납원이 회계담당에게 반납금액명세서, 잔액, 사원증을 제출하였다. - SaleTask, ProcessSale 단계를 마친 상황이다. 사후조건 : - csh가 자신과 CashierID값이 일치하는 CashierList과 연관이 해제되었다(연관관 계 해제)
  • 38.
    목차보충명세서 개정 이력(revision history) 버전일자 설명 저자 Inception 초안 2031.01.10 최초 버전. Elaboration 단계 동 안 주로 정제되어야 함 크레이그 라만 (Craig Larman)
  • 39.
    목차보충명세서-계속 개요 이 문서에는 NextGenPOS 의 요구사항 중 유스케이스에서 추출하지 못한 모든 요구 사항이 작성된다. 기능성 (많은 유스케이스 간의 공통적인 기능성) 로그인 및 오류 처리 모든 오류를 영구적인 저장서에 기록한다. 장착될 수 있는 규칙들 여러 유스케이스의 다양한 시나리오가 발생하는 지점이나 이벤트에서 실행된 임의의 규칙을 이용하여 시스템의 기능을 특화할 수 있도록 한다. 보안 모든 사용은 사용자 인증이 필요하다. 사용성 인적 요소 고객은 POS의 큰 모니터로 디스플레이를 볼 수 있어야 한다. 따라서  문자는 1미터 거리에서 쉽게 판독할 수 있어야 한다.
  • 40.
    목차보충명세서-계속  색맹이 인식하기어려운 색깔 조합을 피한다. 고객은 빨리 물건을 사서 상점을 나가기를 바라며 그렇지 못하면 구매한 경험을 긍정 적으로 인식하지 않는다. 따라서 시스템이 빠르고, 사용하기 쉬우며, 업무 처리시 오류 가 발생하지 않는 것 등은 판매 처리에서 중요한 요건이다. 출납원은 컴퓨터 화면이 아니라 고객과 구매 품목을 보면서 판매 처리한다. 따라서 그 래픽뿐만 아니라 소리로 신호나 경고를 하는 것도 필요하다. 신뢰성 복구성 외부 서비스(지불 인증기, 회계 시스템…)를 사용하는 데 문제가 발생하더라도, 판매 처 리를 계속 진행할 수 있도록 지역적인 해결 방법(예를 들어, 저장하고 진행하는)을 강 구해야 한다. 이 부분에는 더 많은 분석이 필요하다. 성능 인적 요소에서 언급했듯이, 구매자는 구매 절차가 신속히 이루어지기를 원한다. 여기서 문제가 되는 한 가지 요소가 외부 지불 인증이다. 우리의 목적은 발생 횟수의 90% 정 도가 1분 이내로 인증되는 것이다.
  • 41.
    목차보충명세서-계속 지원성 적응성 NextGen POS에서의 여러고객들은 판매 절차에 대한 다양한 비즈니스 규치과 처리 요구사항을 갖는다. 따라서 시나리오의 여러 시점에서(예를 들면, 새로운 판매가 시작 될 때나 새로운 판매 품목이 추가될 때), 장착될 수 있는 비즈니스 규칙이 적용될 수 있 다. 형상성 여러 고객들은 무거운(thick) 클라이언트 vs. 가벼운(thin) 클라이언트, 2-티어(tier)의 물 리적 계층 vs. N-티어의 물리적 계층 등과 같은 사용하는 POS 시스템에 대한 다양한 네트워크 형상을 요구할 것이다. 게다가 고객들은 비즈니스나 성능에 대한 요구사항을 반영하기 위해 이 형상들을 수정하기 원할 것이다. 따라서 시스템은 이러한 요구를 반영하기 위해 어느 정도 유연하게 형상화 할 수 있어야 한다. 유연성의 범위와 정 도 및 이를 위한 노력에 대한 분석이 더 필요하다. 구현 제약사항 NextGen 관리자들은 자바 기술 솔루션을 주장했다. 이는 자바가 개발하기 용이하 고 장기간의 이식성과 지원성을 높일 수 있을 것이라고 예상되기 때문이다.
  • 42.
    목차보충명세서-계속 구매된 컴포넌트  세금계산기. 다른 나라에서도 사용 가능한 계산기를 지원해야 한다. 무료 오픈 소스 컴포넌트 프로젝트에 무료 자바 기술 오픈 소스 컴포넌트를 최대한 많이 사용할 것을 추천한다. 명확하게 컴포넌트를 설계하고 선택하는 것이 아직은 시기상조일지라도, 다 음과 같은 항목은 가능할 수 있다.  Jlog로그 기록 프레임 워크  … 인터페이스 주목할 만한 하드웨어와 인터페이스  터치 스크린 모니터(운영체제에서는 일반적인 모니터로 인식되며 모니터 터치는 마 우스 이벤트로 인식된다.)  바코드 레이저 스캐너(특수한 키보드에 주로 장착되며 읽혀진 입력은 소프트웨어 의 해 키가 입력된 것으로 인식된다.)  영수증 프린터  신용카드/직불카드 판독기  서명 판독기(처음 배포하는 버전에는 없다.)
  • 43.
    목차보충명세서-계속 소프트웨어 인터페이스 대부분의 외부협력 시스템(세금 계산, 회계, 재고 등)을 사용하기 위해 다양한 시스템 및 인터페이스를 장착할 수 있어야 한다. 애플리케이션 종속적인 도메인(비즈니스) 규칙 (일반적인 규칙에 대한 분리된 비즈니스 규칙 문서를 참조하라.) ID 규칙 변경성 원인 규칙 1 구매자 할인 규칙, 예: 직원 20% 할인 우수고객 10%할인 노인 15% 할인 높음. 각 소매상은 서로 다은 규 칙을 사용한다. 소매상 정책 규칙 2 판매(트랜잭션 수준) 할인 규칙. 세금 부과 전의 총액에 적용, 예: 100달러를 넘으면 10%할인 매주 월요일에 5%할인 오늘 오전 10시부터 오후 3시까지 10%할인 오늘 오전 9시부터 10시까지 두부 50%할인 높은. 각 소매상은 다른 규칙을 사용하고 일자별 또는 시 간별로 변경할 수 있다. 소매상 정책 규칙 3 제품별 할인 규칙, 예 : 이번 주는 트랙터 10% 할인 햄버거 2개 구매 시 무료 1개 추가 높음. 각 소매상은 다른 규칙을 사용하고 일자별 또는 시 간별로 변경할 수 있다. 소매상 정책
  • 44.
    목차보충명세서-계속 법적 문제 오픈 소스소프트웨어를 포함하는 제품의 재판매가 가능하도록 라이선스 규정이 해결 된다면, 오픈 소스 컴포넌트를 사용할 것을 추천한다. 모든 세금 관련 규정은 법에 의해 판매에 적용된다. 그러나 이 규정은 자주 바뀔 수 있 음을 유의하라. 관심 도메인 정보 가격 결정 도메인 규칙에 기술된 가격 결정 규칙뿐만 아니라, 제품에는 원래 가격이 있고 때에 따 라서는 영구적 인하가격도 있다. 만약 인하가격이 있다면, 더 많은 할인을 하기 이전의 제품 가격은 영구적 인하가격이다. 회계와 세금 문제가 있으므로 영구적 인하가격이 있더라도 제품의 원래 가격 정보를 갖고 있어야 한다. 신용카드 및 직불카드 지불 처리 지불 인증 서비스에서 신용카드 및 직불카드의 전자 지불이 승인되면, 구매자가 아니 라 판매자에게 구매 금액을 지불해야 한다. 결과적으로 각 지불에 대해, 판매자는 인증 서비스로부터 판매자의 외상계정에 금액을 기록해야 한다. 일반적으로 매일 밤, 인증 서비스는 판매자의 외상계정에 약간의 트랙잭션 수수료를 제하고 하루간의 승인 금액 을 전자식 자금 이체할 것이다.
  • 45.
    목차보충명세서-계속 판매 세금 판매 세금계산은 매우 복잡할 수 있고 일반적으로 정보의 행정지역 구분(도, 시, 군)에서의 법에 따라 구별한다. 따라서 외부 세금 계산 소프트웨어를 사용하는 것 이 바람직하다. 세금은 시, 도, 정부에 납부한다. 어떤 품목은 무조건 면세일 수 있 고, 어떤 품목은 구매자(예를 들어 농민, 어린이)에 따라 면세 될 수 있다. 품목 식별자 : UPC, EAN, SKU, 바코드, 바코드 판독기 NextGen POS는 다양한 품목 식별 체계를 지원해야 한다. UPC(universal product codes, 국제 제품 코드), EAN(European article numbering, 유럽인 품목 번호체계), SKU(stock keeping units, 재고 유지 단위)는 판매되는 제품을 위한 일반적인 세 가지 식별 체계이다. JAN(Japanese article numbers, 일본 품목 번호체계)은 EAN 의 한 종류 이다. SKU는 완전한 소매상 임의의 식별자이다. 그러나 UPC와 EAN은 표준적이고 규정적인 컴포넌트를 갖는다. 전체를 개괄적으 로 살펴보기 위해서는 www.adams1.com/pub/russadam/upccode.html, www.uc- council.org, www.ean-int.org를 참조할 수 있다.
  • 46.
    목차용어집 비전 일자 설명저자 Inception 초안 2011.10.10 최초 버전, Elaboration 단계 동안 주로 정제되어야 함 크레이그 라만(Craig Larman) 용어 정의 및 정보 형식 검증 규칙 별칭 품목 판매를 위한 제품이나 서비스 지불 인증 판매자에게 지불하거나 지불을 보증하는 외부 지불 인증 서비스에 의한 검증 지불 인증 요청 요소들이 합성되어 전자적으로 인증 서비 스에 전송된다. 요소에는 상점 ID, 고객계좌번호, 금액, 타 임스탬프가 있다 UPC 제품을 식별하는 번호로 된 코드, 보통 제 품에 붙은 바코드로 표시된다. 형식이나 검증에 대한 상세한 내용은 www.uc-nouncil.org를 참조하라. 여러 세부 부분으 로 구성된 12자리 코드 12번째 숫자는 체 크 비트이다. 세계 공통 제품 코드 개정 이력 정의
  • 47.
    목차도메인 모델 • 도메인모델을 그리는 과정에서는 정확한 모델을 만들기 위해 노력하지 않아도 된 다고 하기에 일단 개념적인 것들만 설계하였다.
  • 48.
  • 49.
  • 50.
  • 51.
  • 52.
    목차설계 클래스 다이어그램(DCD) •도메인 모델은 개념적인 설계인데 비해, DCD는 S/W측면의 설계라고 하여서 구현하는 것 까지 염두에 두어서 그렸다. 도메인 모델과 약간 차이가 있다.
  • 53.
  • 54.
    목차소스코드-Casher.java package com.foo.nextgen.domain; public classCasher { private String CasherID; private String name; public Casher(String _CasherID, String _name){ CasherID=_CasherID; name=_name; } Public String getCasherID(){ return CasherID; } }
  • 55.
    목차CasherList.java package com.foo.nextgen.domain; import java.util.*; publicclass CasherList { private Map<String, Casher> Casherlist=new HashMap<String, Casher>(); public CasherList(){ Casher csh; csh = new Casher("c100","park"); Casherlist.put("c100", csh); csh = new Casher("c200","kim"); Casherlist.put("c200", csh); csh = new Casher("c300","yoon"); Casherlist.put("c300", csh); } public Casher getCasherInfo(String id){ return Casherlist.get(id); } }
  • 56.
    목차CashIn.java package com.foo.nextgen.domain; public classCashIn { private CasherList casherlist; private CashIOList cashIOlist; Public CashIn(){ casherlist=new CasherList(); cashIOlist=new CashIOList(); } public boolean IdentifyCasher(String CasherID){ if(casherlist.getCasherInfo(CasherID).getCasherID()==CasherID){ //존재한다면 System.out.println("Casher "+CasherID+" Identified.."); return true; }//////must be else{ System.out.println("Identification failed.. "); return false; } } public void RecordCashIn(String CasherID, CashIODescription c_io_ds){ cashIOlist.pushIODescription(CasherID,c_io_ds); }}
  • 57.
    목차CashIODescription.java package com.foo.nextgen.domain; import java.util.*; publicclass CashIODescription { private String CasherID; private int Date; private int Money; public CashIODescription(String CasherID, int Date, int Money){ this.CasherID=CasherID; this.Date=Date; this.Money=Money; } public String getCasherID() {return CasherID;} public int getDate() {return Date;} public int getMoney() {return Money; } }
  • 58.
    목차CashIOList.java package com.foo.nextgen.domain; import java.util.*; publicclass CashIOList { public static Map<String, CashIODescription> CashIOlist=new HashMap<String, CashIODescription>(); public void pushIODescription(String CasherID, CashIODescription c_io_ds){ CashIOlist.put(CasherID, c_io_ds); System.out.println("-------------------Cash In----------------------"); System.out.println("CasherID:"+CasherID+"/ Date:"+c_io_ds.getDate()+"/ Money:"+c_io_ds.getMoney()); } public CashIODescription getCashIODescription(String CasherID){ return CashIOlist.get(CasherID); } }
  • 59.
    목차CashOut.java package com.foo.nextgen.domain; public classCashOut { public int logout(CashRegister cashregister, String CasherID){ return cashregister.logout(CasherID); } }
  • 60.
    목차CashRegister.java package com.foo.nextgen.domain; ////////////////// 금전등록기 public class CashRegister { private String CasherID; private String password; static int EarnedMoney; public boolean login(String CasherID, String password){. this.CasherID=CasherID; this.password=password; return true; } public void MoneyIn(int Money){ EarnedMoney+=Money; } public int logout(String CasherID){ System.out.println("logged Out..."); return EarnedMoney; } }
  • 61.
    목차ProductCatalog.java package com.foo.nextgen.domain; import java.util.*; publicclass ProductCatalog { private Map<String, ProductDescription> descriptions=new HashMap<String, ProductDescription>(); public ProductCatalog(){ String id1 = new String("100"); String id2 = new String("200"); int Money = 3; ProductDescription desc; desc = new ProductDescription(id1, Money, "product 1"); descriptions.put(id1, desc); desc=new ProductDescription(id2, Money, "product 2"); descriptions.put(id2, desc); //System.out.println(descriptions.get(id2).getDescription()); } public ProductDescription getProductDescription(String id){ //System.out.println(descriptions.get(id).getDescription()); return descriptions.get(id); } }
  • 62.
    목차ProductDescription.java package com.foo.nextgen.domain; public classProductDescription { private String id; private int Money; private String description; public ProductDescription(String id, int Money, String description){ this.id=id; this.Money=Money; this.description=description; } public String getItemID() {return id;} public int getPrice() {return Money;} public String getDescription() {return description; } }
  • 63.
    목차Register.java package com.foo.nextgen.domain; public classRegister { private ProductCatalog catalog; private Sale currentSale; private CashIn currentCashIn; private CashOut currentCashOut; private CashRegister cashregister; public Register(ProductCatalog catalog){ this.catalog=catalog; } public void endSale(){ currentSale.becomeComplete(); } public void enterItem(String id, int quantity){ ProductDescription desc=catalog.getProductDescription(id); currentSale.makeLineItem(desc,quantity); } public void makeNewSale(){ currentSale=new Sale(); } public void makePayment(int cashTendered){ currentSale.makePayment(cashTendered); } public void makeNewCashIn(){ currentCashIn=new CashIn(); } public boolean IdentifyCasher(String CasherID){ return currentCashIn.IdentifyCasher(CasherID); } public void RecordCashIn(String CasherID, CashIODescription c_io_ds){ currentCashIn.RecordCashIn(CasherID, c_io_ds); } public void StartSaleTask(String CasherID, String password){ cashregister=new CashRegister(); cashregister.login(CasherID, password); cashregister.MoneyIn(300); } public void makeNewCashOut(){ currentCashOut=new CashOut(); } public int LogOutCasher(String CasherID){ return currentCashOut.logout(cashregister, CasherID); } }
  • 64.
    목차Sale.java package com.foo.nextgen.domain; import java.util.*; publicclass Sale { private List<SaleLineItem> lineItems= new ArrayList<SaleLineItem>(); private boolean isComplete =false; private int payment; //private Payment payment; public int getBalance(){ //거스름돈 return (payment-this.getTotal()); } public void becomeComplete(){ isComplete=true; System.out.println("Total : "+getTotal()+" Dollars");} } public void makeLineItem(ProductDescription desc,int quantity){ lineItems.add(new SaleLineItem(desc,quantity)); System.out.println("itemID:"+desc.getItemID()+" / quantity:"+quantity); } public int getTotal(){ int total=0; int subtotal=0; for(SaleLineItem lineItem : lineItems){ subtotal=lineItem.getSubtotal(); total+=subtotal; } return total; } public void makePayment(int cashTendered){ payment=cashTendered; System.out.println("recieved cash : "+payment+" Dollars"); System.out.println("balance : "+getBalance()+" Dollars"); } }
  • 65.
    목차SaleLineItem.java package com.foo.nextgen.domain; public classSaleLineItem { private int quantity; private ProductDescription description; public SaleLineItem(ProductDescription desc, int quantity){ this.description=desc; this.quantity=quantity; } public int getSubtotal(){ return (description.getPrice()*quantity); } }
  • 66.
    목차Store.javapackage com.foo.nextgen.domain; public classStore { private ProductCatalog catalog=new ProductCatalog(); private Register register=new Register(catalog); public Store(){ System.out.println("-------------------Process Sale----------------------"); register.makeNewSale(); register.enterItem("100",1); register.enterItem("200",2); register.endSale(); register.makePayment(10); System.out.println("-------------------Cash In----------------------"); register.makeNewCashIn(); if(register.IdentifyCasher("c300")){ register.RecordCashIn("c300",new CashIODescription("c300",20111222,300)); } register.StartSaleTask("c300", "1234"); System.out.println("-------------------Cash Out----------------------"); register.makeNewCashOut(); System.out.println("returned money:"+register.LogOutCasher("c300")); } public Register getRegister(){return register;} }
  • 67.
    목차Main.java package com.foo.nextgen.domain; public classmain { public static void main(String[] args) { // TODO Auto-generated method stub new Store(); } }
  • 68.
    목차Test Code • J-unit프로그램을 이용하여 테스트하였다 • 모두 다 테스트해보지는 않았고, 문제를 일 으킬 가능성이 있는 unit만 테스트를 해 보 았다.
  • 69.
    목차Test Code-CasherTest.java package com.foo.nextgen.test; importjunit.framework.TestCase; import com.foo.nextgen.domain.*; public class CasherTest extends TestCase { Casher casher=new Casher("c100","dd"); protected void setUp() throws Exception { super.setUp(); } public void testCasher() { assertNotNull(casher); //fail("Not yet implemented"); } public void testGetCasherID() { assertEquals(casher.getCasherID(),"c100"); //fail("Not yet implemented"); } }
  • 70.
    목차CashInTest.java package com.foo.nextgen.test; import junit.framework.TestCase; importcom.foo.nextgen.domain.*; public class CashInTest extends TestCase { CashIn cashin=new CashIn(); protected void setUp() throws Exception { super.setUp(); } public void testCashIn() { assertNotNull(cashin); //fail("Not yet implemented"); } public void testIdentifyCasher() { assertTrue(cashin.IdentifyCasher("c100")); //fail("Not yet implemented"); } }
  • 71.
    목차CashIODescriptionTest.java package com.foo.nextgen.test; import junit.framework.TestCase; importcom.foo.nextgen.domain.*; public class CashIODescriptionTest extends TestCase { CashIODescription description=new CashIODescription("c100",2011,11); protected void setUp() throws Exception { super.setUp(); } public void testCashIODescription() { assertNotNull(description); } public void testGetCasherID() { assertEquals(description.getCasherID(),"c100"); //fail("Not yet implemented"); } public void testGetDate() { assertEquals(description.getDate(),2011); //fail("Not yet implemented"); } public void testGetMoney() { assertEquals(description.getMoney(),11); //fail("Not yet implemented"); } }
  • 72.
    목차ProductCatalogTest.java package com.foo.nextgen.test; import junit.framework.TestCase; importcom.foo.nextgen.domain.*; public class ProductCatalogTest extends TestCase { ProductCatalog catalog=new ProductCatalog(); protected void setUp() throws Exception { super.setUp(); } public void testProductCatalog() { assertNotNull(catalog); //fail("Not yet implemented"); } }
  • 73.
    목차ProductDescriptionTest.java package com.foo.nextgen.test; import junit.framework.TestCase; importcom.foo.nextgen.domain.*; public class ProductDescriptionTest extends TestCase { ProductDescription description=new ProductDescription("100",11,"aa"); protected void setUp() throws Exception { super.setUp(); } public void testProductDescription() { assertNotNull(description); } public void testGetItemID() { assertEquals(description.getItemID(),"100"); } public void testGetPrice() { assertEquals(description.getPrice(),11); //fail("Not yet implemented"); } public void testGetDescription() { assertEquals(description.getDescription(),"aa"); //fail("Not yet implemented"); } }
  • 74.
    목차Discussion - Junit의 사용법을몰라 한참 고생을 했다. - 역공학으로 해야할지, 순공학으로 해야할지 결정하는데 시간이 꽤 걸렸다. 감사합니다. ♥