Ch18. GRASP...
Transcript of Ch18. GRASP...
Professor Seung-Hoon Choi
Ch18. GRASP 패턴을 이용한 객체 설계 예제
2/55
객체들이 책임을 가지고 협력하는 것을 어떻게 설계할 것인가?
◦ applying OO Design principles and the UML
책임을 할당하고 객체들 사이의 협력을 설계하는 것은,
◦ 설계 시에 가장 중요하고 창조적인 작업이다.
3/55
유스케이스 실체화
◦ 특정 유스케이스가 설계 모델 내에서 어떻게 실현될 것인가를, 협력하는
객체들의 관점에서 기술
UML 상호 작용 다이어그램은,
◦ 유스케이스 실체화를 보여주는 일반적인 언어이다.
Operation: enterItem(…)
Post-conditions:- . . .
Operation Contracts
Sale
date. . .
SalesLineItem
quantity
1..*1 . . .
. . .
Domain Model
Use-Case Model
Design Model: Register
enterItem(itemID, quantity)
: ProductCatalog
d = getProductDescription(itemID)
addLineItem( d, quantity )
: Sale
Require-ments
Business Modeling
Design
Sample UP Artifact Relationships
: System
enterItem(id, quantity)
Use Case Text
System Sequence Diagrams
makeNewSale()
system events
Cashier
Process Sale
: Cashier
use case
names
system operations
Use Case Diagram
SupplementarySpecification
Glossary
starting events to design for, and detailed post-condition to satisfy
Process Sale
1. Customer arrives ...2. ...3. Cashier enters item identifier.
inspiration for names of some software domain objects
functional requirements that must be realized by the objects
ideas for the post-conditions
Register
...
makeNewSale()enterItem(...)...
ProductCatalog
...
getProductDescription(...)...
1*
non-functional requirements
domain rules
item details, formats, validation
5/55
UP 산출물들간의 관계(이전 슬라이드 그림 참조)
◦ 유스케이스는 SSD에서의 시스템 오퍼레이션들을 제안한다.
◦ 시스템 오퍼레이션은 도메인 계층의 Controller로 들어가는 시작
메시지가 된다.
◦ 도메인 계층의 인터랙션 다이어그램은,
객체들이 요구되는 태스크를 달성하기 위해
어떻게 상호작용하는가(use case realization)을 보여준다.
이번 POS 개발 iteration에서는 ProcessSale 유스케이스의 SSD에
나타나는 다음 4개의 시스템 오퍼레이션을 설계한다.
6
:RegisterenterItem
:RegisterendSale
:RegistermakePayment
1: ???
1: ???
1: ???
:RegistermakeNewSale 1: ???
makeNewSale, etc., are the system operations from the SSD
each major interaction diagram starts with a system operation going into a domain layer controller object, such as Register
DOMAIN LAYERUI LAYER
Window objects or
GUI widget objectsor
Web control objects
. . .시스템이벤트메시지
7/55
유스케이스 실체화를 커뮤니케이션 다이어그램을 이용하여
보여준다면, 시스템 이벤트 메시지 하나 당 다이어그램이 하나씩
필요하다. (그림 17.1)
:RegisterenterItem()
:RegisterendSale()
:RegistermakePayment()
1: ???()
1: ???()
1: ???()
:RegistermakeNewSale() 1: ???()
:RegisterenterItem()
:RegisterendSale()
:RegistermakePayment()
1: ???()
1: ???()
1: ???()
:RegistermakeNewSale() 1: ???()
시퀀스 다이어그램을 사용한다면, 하나의 다이어그램에 모든
시스템 이벤트 처리를 보여주는 것이 가능하다.
8
: Register
: Sale
makeNewSalecreate
: Register
enterItem(...)
: ProductCatalog
desc = getProductDesc( itemID )
. . .
UI LAYER
Window objects or
GUI widget objectsor
Web control objects
. . .
DOMAIN LAYER
9/55
너무 복잡해지므로, 각 시스템 이벤트 메시지마다, 하나씩의 순차
다이어그램을 그려도 된다.(그림 17.3)
makeNewSale()
: Register: Register
makeNewSale() create(): Sale: Sale
: Sale: Sale
(itemID, quantity)spec := getProductSpec( itemID )
addLineItem( spec, quantity ). . .
(itemID, quantity)spec := getProductSpec( itemID )
addLineItem( spec, quantity ). . .
: ProductCatalog: ProductCatalog: Register: RegisterenterItem
10/55
약정(Contract)과 유스케이스 실체화
◦ 유스케이스 텍스트로부터 직접 유스케이스 실체화를 설계하는 것도
가능함
◦ 약정이 작성된 시스템 오퍼레이션에 대해서는
사후 조건(post-condition)의 상태 변화를 다루고, 그 요구사항을
만족시키기 위해 메시지 상호작용을 설계한다.
11/55
약정(Contract)과 유스케이스 실체화
◦ 예: enterItem 시스템 오퍼레이션에 대해 SalesLineItem 인스턴스
생성이라는 상태 변화를 만족시킨다.
1: makeLineItem(...)enterItem(id, qty)
1.1: create(...)
:Register :Sale
:SalesLineItem
초기화와 ‘Start Up’ 유스케이스
◦ 대부분의 시스템은 Start Up 유스케이스와, 응용 프로그램 시작과 관련된
어떤 초기화 시스템 오퍼레이션을 가진다.
◦ 이 startUp 시스템 오퍼레이션은 실행은 제일 먼저 되지만, 초기화
활동에 필요한 모든 정보를 충분히 얻기 위해, 맨 나중에 설계한다.
12
13/55
고객이 구입할 물건을 들고 오면, 출납원은 새로운 판매를 시작할것을 요청함◦ 이 때, makeNewSale 시스템 오퍼레이션이 일어난다.
약정 CO1: makeNewSale
오퍼레이션: makeNewSale( )상호참조: 사용사례: Process Sale사전조건: 없음사후조건: - Sale 인스턴스 s가 생성되었다(인스턴스 생성)
- s가 Register와 연관되었다(연관 형성)- s의 속성들이 초기화되었다.
Controller 클래스 선택
◦ 먼저, 시스템 오퍼레이션 메시지 makeNewSale에 대한 컨트롤러를
선택해야 한다.
◦ Controller 패턴에 의해 다음과 같은 선택이 가능하다
전체 “시스템”, 장치 혹은 서브시스템을 나타내는 클래스
Store, Register, POSSystem 등
하나의 유스케이스 시나리오의 모든 시스템 이벤트들에 대한 수신자
또는 처리자를 나타내는 클래스
ProcessSaleHandler, ProcessSaleSession
14
Controller 클래스 선택(계속)
◦ 단지 몇 개의 시스템 오퍼레이션만 있고, 외관 컨트롤러(facade
controller)가 너무 많은 책임을 맡지 않는다면, Register와 같은 외관
컨트롤러를 선택하는 것이 바람직하다.
◦ 시스템 오퍼레이션이 많고, 각 컨트롤러 클래스를 가볍게 유지하기 위해
책임을 분산시키고자 한다면, 사용사례 컨트롤러(use-case controller)를
선택하는 것이 적합하다.
◦ 이 경우에는 Register를 선택함
15
:Register
makeNewSale:Salecreate
새로운 Sale 생성
◦ Creator 패턴은, 생성되는 객체를 포함하고 기록하는 클래스에 그 객체
생성의 책임을 부여할 것을 제안한다.
◦ 도메인 모델을 분석하면, Register가 Sale을 기록하는 것으로 생각됨
Register가 Sale을 생성시키는 책임을 가지는 후보 클래스
◦ Sale은, 여러 개의 SalesLineItem 인스턴스를 포함하고 유지한다.
따라서, Sale을 생성할 때, 여러 개의 SalesLineItem 인스턴스를 포함하고
유지할 컬렉션(List와 같은 컨테이너)을 Sale이 생성해야 한다.
16
17
:Register
makeNewSale
:Salecreate
Register creates a Sale by Creator
create lineItems :List<SalesLineItem>
by Creator, Sale creates an empty collection (such as a List) which will eventually hold SalesLineItem instances
by Creator and Controller
this execution specification is implied to be within the constructor of the Sale instance
Collection 객체(List
다중 객체를의미함)
출납원이 itemID와 구매하려는 물품의 양을 입력할 때, enterItem
시스템 오퍼레이션이 일어난다.
약정 CO2: enterItem
18
오퍼레이션: enterItem(itemID: ItemID, quantity: integer)상호참조: 사용사례: Process Sale사전조건: 판매가 진행중이다.사후조건: - 하나의 SalesLineItem 인스턴스 sli가 생성되었다(인스턴스 생성)
- sli가 현재의 Sale과 연관되었다(연관 형성)- sli.qunatity가 quantity로 되었다(속성 수정)- itemID가 일치하는 ProductDiscription과 sli가 연관되었다(연관 형성)
컨트롤러 클래스 선택
◦ Controller 패턴에 의해, enterItem의 경우도 Register가 컨트롤러 역할을
한다.
물품 설명과 가격의 화면 출력?
◦ 출력 작업은 비-GUI 객체(예를 들어, Register나 Sale)의 책임이 아니다.
◦ 정보를 화면에 출력하는 것이 유스케이스에 적혀있지만, 현재
설계에서는 이 책임은 무시한다.
19
새로운 SalesLineItem 생성
◦ enterItem 약정에서 사후 조건은
SlaesLineItem의 생성, 초기화, 연관을 나타낸다.
◦ Sale이 SalesLineItem 인스턴스 하나를 생성하여 컬렉션에 저장한다.
◦ 사후 조건을 보면,
SalesLienItem이 생성될 때 수량(quantity)를 필요로 한다.
따라서, Register는 Sale에게 quantity를 보내야 하고, Sale은 SalesLineItem
인스턴스를 생성할 때, 생성자에게 이 quantity를 보내야 한다.
20
ProductDescription 찾기
◦ SalesLineItem은 itemID가 일치하는 ProductDescription과 연관되어야
한다.
◦ 즉, itemID가 일치하는 ProductDescription 을 찾아야 함을 의미한다.
◦ 책임 명시: “itemID가 일치하는 ProductDescription 을 찾을 책임은 누가
맡아야 하는가?”
21
ProductDescription 찾기 (계속)
◦ Information Expert 패턴 적용
“어떤 책임을 이행하기 위해 필요한 정보를 갖는 객체가 그 일을 해야
한다”
누가 ProductDescription 에 관해 모든 것을 알고 있는가?
도메인 모델을 분석하면, ProductCatalog가 논리적으로
ProductDescription 들을 전부 포함하고 있다.
따라서, ProductCatalog가 ProductDescription 을 찾는 책임에 대한
좋은 후보가 된다.
ProductCatalog.getProductDescription ( ) 메소드로 구현될 것이다.
22
ProductCatalog에 대한 Visibility(가시성)
◦ ProductDescription을 요청하기 위해 누가 ProductCatalog에게
getProductDescription 메시지를 전달할 것인가?
◦ 가정: 초기의 Start up 사용사례 동안
Register와 ProductCatalog 인스턴스가 생성되고
Register객체에서 ProductCatalog 객체로 영구적인 연결이 있다라고 가정할 수
있다.
따라서, Register가 ProductCatalog에게 getProductDescription 메시지를
전달하는 것이 가능하다.
23
Final Design
24
2: makeLineItem(desc, qty)enterItem(id, qty)
1: desc = getProductDesc(id) 2.1: create(desc, qty)
1.1: desc = get(id)
:Register :Sale
:ProductCatalog
sl: SalesLineItem
lineItems : List<SalesLineItem>: Map<ProductDescription>
2.2: add(sl)
by Expert
by Controllerby Creator
add the newly created SalesLineItem instance to the List
Partial DCD(Design Class Diagram)
25
SalesLineItem
quantity : Integer
...
ProductCatalog
...
getProductDesc(...)
ProductDescription
description : Textprice : MoneyitemID: ItemID
...
1..*
1..*
Register
...
enterItem(...)...
Sale
isComplete : Booleantime : DateTime
makeLineItem(...)...1
1
1
catalog
currentSale
descriptions{Map}
lineItems{ordered}
description
데이터베이스에서 ProductDescription들을 추출하기
◦ POS 최종 버젼에서는 ProductDescription 정보들이 메모리가 아니라
데이터베이스에 저장되어야 함
◦ 그러나, 현재 iteration에서는 고려하지 않음
26
출납원이 판매가 끝났음을 나타내는 버튼을 누르면,
◦ endSale 시스템 오퍼레이션이 일어난다.
약정 CO3: endSale
27
오퍼레이션: endSale( )상호참조: 사용사례: Process Sale사전조건: 판매가 진행중이다.사후조건: - Sale.isComplete이 참이 되었다 (속성 수정)
컨트롤러 클래스 선택
◦ Controller 패턴에 의거, Register 클래스를 선택함
Sale.isComplet 속성 설정
◦ 책임: “누가 Sale의 isComplete 속성을 참으로 설정할 것인가?”
◦ Information Expert 패턴에 의거, Sale 자신이어야 한다.
이유: Sale이 isComplete 속성을 가지므로
28
:RegisterendSale( s :Sale1: becomeComplete
by Expertby Controller
판매 총액 계산
◦ ProcessSale 유스케이스의 주요 성공 시나리오 마지막 단계:
7. 시스템은 세금을 포함한 총액을 보여준다
◦ 누군가가 판매 총액을 계산해야 한다.
◦ Model-View Separation 원리에 의해, 판매 총액이 화면에 어떻게 표시될
것인가는 설계하지 않는다.
◦ 컨트롤러나 생성 문제가 아니면, Information Expert 패턴을 제일 먼저
고려한다.
29
판매 총액 계산 분석 과정
◦ 1. 책임을 기술한다.
누가 판매 총액을 알 책임이 있는가?
◦ 2. 필요한 정보를 요약한다.
판매 총액은, 모든 판매 라인 아이템의 소계의 합이다.
판매 라인 아이템의 소계 = 라인 아이템의 양 * 제품에 기재된 가격
30
판매 총액 계산에
필요한 정보Information Expert 구현 오퍼레이션
ProductDescription.price ProductDescription ProductDescription.getPrice( )
SalesLineItem.quantity SalesLineItem SalesLineItem.getSubTotal( )
현재 Sale의 모든 SalesLineItem Sale Sale.getTotal( )
Sale.getTotal Design
◦ Sale이 getTotal 메시지를 받을 때 어떤 일이 일어나는가를 상호 작용
다이어그램으로 설계해야 한다.
getTotal( ) 메시지는 누가 보내는가?
Java JFrame과 같은 UI 계층의 객체가 될 것이다.
31
:Saletot = getTotal 1 * [i = 1..n]: st = getSubtotal
:ProductDescription
1.1: pr = getPrice
lineItems[ i ]: SalesLineItem
by Expert by ExpertUML: note the selector notation to select elements from the lineItems collection
노트 기호로 메소드를 보여줌
32
:Saletot = getTotal 1 *[ i = 1..n]: st = getSubtotal
:ProductDescription
1.1: pr = getPrice
lineItems[ i ] :SalesLineItem
쳋 ethod?public void getTotal(){ int tot = 0; for each SalesLineItem, sli tot = tot + sli.getSubtotal(); return tot}
지불을 위해 고객이 건넨 현금이 액수를 출납원이 입력할 때,
makePayment 시스템 오퍼레이션이 발생한다.
약정 CO4: makePayment
33
오퍼레이션: makePayment(amount:Money)상호참조: 사용사례: Process Sale사전조건: 판매가 진행중이다.사후조건: - Payment의 인스턴스 p 가 생성되었다(인스턴스 생성)
- p.amountTendered가 amount로 되었다(속성 수정)- p가 현재의 Sale과 연관되었다(연관 형성)- 현재의 Sale이 Store와 연관되었다(연관형성)
(완료된 판매들의 기록에 이 판매내역을 추가하기 위하여)
Payment 생성
◦ Creator 패턴 적용
Register가 논리적으로 Payment를 기록 => Register가 후보
Sale 소프트웨어가 Payment를 밀접하게 사용 => Sale이 후보
◦ 여러 가지의 설계 선택이 주어졌을 때, 좋은 응집도와 결합도를 가지는
설계를 선택하라.
34
Payment 생성 (계속)
Sale이 Payment를 생성하는 것으로 선택하면,
Register의 일이 줄어 들고, 결합도가 낮아진다.
35
1: makePayment(cashTendered)
1.1: create(cashTendered)
:Register :Sale
:Payment
makePayment(cashTendered)
by Controller by Creator and Low Coupling
판매 로그 기록(Logging)
◦ 판매 완료 후에, 판매 내역을 로그에 기록해야 한다.
◦ 책임: 누가 로그 기록될 판매들을 알고, 로그 기록을 수행할 것인가?
◦ 재정과 밀접한 관계가 있는 Store가 담당하는 것이 좋다
설계가 진행되면서 Store의 응집력이 약해지면, SalesLeger(판매
원장)라는 새로운 클래스를 도입할 수도 있다.
see the next slide.
36
37
Store
...
addSale(s : Sale)...
SalesLedger
...
addSale(s : Sale)...
Store is responsible for knowing and adding completed Sales.
Acceptable in early development cycles if the Store has few responsibilities.
SalesLedger is responsible for knowing and adding completed Sales.
Suitable when the design grows and the Store becomes uncohesive.
Sale
...
...
Sale
...
...
Logs-completed Logs-completed* *
1 1
판매 로그 기록(Logging)
38
1: makePayment(cashTendered)
1.1: create(cashTendered)
:Register s :Sale
:Payment
makePayment(cashTendered)
:Store
2: addSale(s)
completedSales: List<Sale>
2.1: add(s)
by Expert
note that the Sale instance is named's' so that it can be referenced as a parameter in messages 2 and 2.1
잔액 계산
◦ Process Sale 사용 사례는, 지불의 잔액이 영수증에 출력되고 화면에도
출력됨을 암시한다.
◦ Model-View Separation 원리에 의해, 출력 방식은 신경 쓸 필요가 없다.
◦ 책임: 누가 잔액을 알 책임이 있는가?
◦ 잔액 계산에 필요한 정보: 판매 총액과 고객이 건넨 금액
정보 전문가는 Sale과 Payment 이다.
39
잔액 계산
◦ 방법 #1: Payment인 경우
총액을 묻기 위해 Sale로의 가시성이 필요하다.
현재로서는 Payment가 Sale에 관하여 알지 못하므로, 이 설계는
결합도를 높인다.
◦ 방법 #2: Sale인 경우
고객이 건넨 금액을 묻기 위해 Payment로의 가시성이 필요하다.
Sale은 Payment 생산자로서, 이미 Payment에 대한 가시성을 가지고
있다.
이 접근 방법은 결합도를 높이지 않는다. => 이 방법을 선택함
40
잔액 계산
41
s :Sale pmt: Payment1: amt = getAmountbal = getBalance
2: t = getTotal
{ bal = pmt.amount - s.total }
A more complete DCD
42
SalesLineItem
quantity : Integer
getSubtotal()
ProductCatalog
...
getProductDesc(...)
ProductDescription
description : Textprice : MoneyitemID: ItemID
...
Store
address : Addressname : Text
addCompleteSale(...)
Payment
amount : Money
...
1..*
1..*
Register
...
endSale()enterItem(...)makeNewSale()makePayment(...)
Sale
isComplete : Booleantime : DateTime
becomeComplete()makeLineItem(...)makePayment(...)getTotal()
1
1
1
1
1
1
*
catalog
catalog
register
currentSale
descriptions{Map}
lineItems{ordered}
payment
completedSales{ordered}
description
2가지 방법
◦ 방법 #1. Initializer 객체 이용
Java의 main( ) 메소드에서 Initializer 객체의 초기화 메소드 호출
Initializer 객체의 초기화 메소드 안에서
UI 객체와 Domain 객체를 생성한 후
Domain 객체를 UI 객체에 전달함
◦ 2. UI 객체가 먼저 만들어지고
UI 객체가 factory 객체 등을 이용하여 Domain 객체를 얻은 후 이를
reference한다.
◦
43
일단, UI 객체가 Register 인스턴스에 대한 연관을 가지게 되면
◦ UI 객체는 enterItem 이나 endsale 같은 시스템 이벤트 메시지들을
Register 인스턴스에게 전달할 수 있다.
44
:Register
Cashier
:ProcessSaleJFrame
actionPerformed( actionEvent )
1: enterItem(id, qty) system event
UILayer
DomainLayer
presses button
enterItem 메시지의 경우, 각 물품들이 입력될 때 윈도우가 그
시점까지의 합계를 보여주어야 한다.
◦ UI 객체와 도메인 객체와의 메시지 전달 방식에 따라 여러 가지 설계
방법이 존재한다.
45
◦ 해결책 #1 getTotal 메소드를 Register에 추가한다. UI가 getTotal 메시지를 Register에 보내고, Register는 이 메시지를 Sale에
전달한다. 장점: UI에서 도메인 계층으로의 결합도를 낮춘다. 단점: Register 객체의 응집력이 낮아진다.
◦
46
:Register
Cashier
:ProcessSaleJFrame
actionPerformed( actionEvent )
1: enterItem(id, qty) system event
UILayer
DomainLayer
presses button
◦ 해결책2: UI가 현재 Sale 객체에 대한 참조를 Register에게 요청한다. 그 후에, UI가 합계(혹은 판매와 관련된 다른 정보)가 필요하면 Sale에 직접
메시지를 보낸다. 단점: UI에서 도메인 계층으로의 결합도를 높임. 그러나, Sale은 안정된 객체라면, 안정된 객체와의 높은 결합도는 문제가 되지
않는다.
47
:Register
Cashier
:ProcessSaleJFrame
actionPerformed( actionEvent )
1: enterItem(id, qty)
2 [no sale] : s = getSale : Sale
UILayer
DomainLayer s : Sale
3: t = getTotal
presses button
책에서 선택한
설계 방법
UI 계층은 도메인 논리에 대한 책임을 갖지 않는 것이 좋다.
◦ 예: Java의 윈도우(ProcessSaleJFrame)은 응용 프로그램의 논리를
처리하지 않고, 도메인 객체로 메시지를 전달하는 역할만 담당하도록
하는 것이 좋다.
48
언제 초기화를 설계하는가?
◦ “초기화 설계를 마지막에 해라”
◦ 대부분의 시스템은
Start Up 유스케이스와
응용 프로그램 시작과 관련된 어떤 초기 시스템 오퍼레이션을 가진다.
◦ 이 startUp 시스템 오퍼레이션이 제일 먼저 실행되지만, 초기화 활동에
필요한 모든 정보를 충분히 얻기 위해, 맨 나중에 설계한다.
49
어플리케이션을 어떻게 시작하는가?
◦ “초기 도메인 객체(initial domain object)를 생성하라”
◦ 비교:
도메인 객체: 도메인 논리와 관련된 객체
UI 객체: 사용자 인터페이스와 관련된 객체
◦ 초기 도메인 객체는 생성되고 난 후, 직접 자식 도메인 객체를 생성할 책임이 있다.
50
어플리케이션을 어떻게 시작하는가?(계속)
◦ main( ) 메소드에서 주로 초기 도메인 객체가 생성된다.
예: Store 초기 도메인 객체가 생성됨 => Store 객체가 Register 객체를 생성함
51
Public class Main{
public static main(String[ ] args) {Store store = new Store( );Register register = store.getRegister( );ProessSaleJFrame frame = new ProcessSaleJFrame(register);... ...
}}
POS 응용프로그램의 startUp 오퍼레이션
◦ 관리자가 POS 시스템을 켜고, 소프트웨어를 메모리에 로드할 때 startUp 시스템
오퍼레이션이 일어난다.
◦ 제어는, 초기 도메인 객체가 생성된 후 UI 계층(예를 들어, Java의 JFrame)에 남게
된다.
Event-driven 방식
52
초기 도메인 객체 선택 방법
◦ 어떤 것이 초기 도메인 객체 클래스가 되어야 하는가?
◦ 도메인 객체들의 포함 관계나, 집합 관계 계층구조 상 root 또는
root에서 가장 가까운 클래스를 선택하라.
◦ 예: Register와 같은 외관 컨트롤러나, 다른 객체들 모두 또는 대부분을
포함하는 Store 클래스
◦ 예제에서는, Store 클래스 선택함
53
Store.create (초기 도메인 객체의 생성자) 설계
◦ 초기화 시 필요한 작업
Store, Register, ProductCatalog, ProductDescription 들이 생성되어야 한다.
ProductCatalog는 ProductDescription들과 연관되어야 한다.
Store는 ProductCatalog와 연관되어야 한다.
Store는 Register와 연관되어야 한다.
Register는 ProductCatalog와 연관되어야 한다.
54
55
:Store :Register
pc:ProductCatalog
create 2: create(pc)
1: create
1.2: loadProdSpecs()
descriptions:Map<ProductDescription>
1.1: create
1.2.2*: put(id, pd)
1.2.1*: create(id, price, description)
pd:ProductDescriptionthe * in sequence number indicates the
message occurs in a repeating section
pass a reference to the ProductCatalog to the Register, so that it has permanent visibility to it
by Creator create an empty collection object
1.2: loadProdSpecs( ) 메소드 안에서1.2.1*: create(id, price, description)1.2.2*: add(ps)
메시지를 차례로 호출한다.
역속적인(persistent) 객체: ProductDescription
◦ ProductDescription 인스턴스는 영구 저장 매체에 위치한다.
관계형 데이터베이스
객체 데이터베이스
◦ 관계형 데이터베이스 사용 시,
ProductDescription 정보에 대한 데이터 모델링이 필요하다.
56
p:ProductDescription
itemID: 1price: 700description: 새우깡
ItemID Price Description
1 700 새우깡
2 600 콜라
… … …
ProductDescription들의 테이블 (in DB) “새우깡” 객체 (in Memory)
1.2.1*: create(id, price, description) in 슬라이드 p.55
◦ ProductDescription의 생성자이다.
◦ id, price, description 인자들의 값은
영구 저장 매체(Database)에서 읽어온 값이다.
◦ 이 인자들을 이용하여 ProductDescription 생성자를 호출한다.
57
58
Register
id
ItemStore
nameaddress
Sale
dateTime/ total
CashPayment
amountTendered
SalesLineItem
quantity
Cashier
id
Customer
ProductCatalog
ProductDescription
itemIDdescriptionprice
Stocks
*
Houses1..*
Used-by
*
Contains1..*
Describes
*
Captured-on
Contained-in
1..*
Records-sale-of
0..1
Paid-by Is-for
Logs-completed
*
Works-on
11
1
1 1..*
1
1
1
1
1
1
1
0..1 1
1
Ledger
Records-accounts-
for
1
1