チケット料金モデリング === ###### tags: `DDD` パッケージ図 ![](https://i.imgur.com/FR8wcb4.png) ドメインモデル図 ![](https://i.imgur.com/p6XQROi.png) ```java= class ScreenPricePatternTest { @Test void calcBasePriceTest() { assertBasePrice(CinemaCityCitizen60, WeekdayNormal, 1000); assertBasePrice(Normal, WeekdayNormal, 1800); assertBasePrice(Senior70, WeekdayNormal, 1100); // 以下略 } private void assertBasePrice(ScreenPricePattern screenPricePattern, ScreenTimeType screenTimeType, int basePriceValue) { assertThat(screenPricePattern.calcPrice(screenTimeType), is(BasePrice.of(basePriceValue))); } } ``` ```java= package org.littlehands.ticket_modeling.pricing; import lombok.AllArgsConstructor; import lombok.Getter; /** * 料金区分を表すクラス */ @AllArgsConstructor @Getter public enum ScreenPricePattern { // @formatter:off CinemaCityCitizenNormal (1000, 1000, 1300, 1000, 1100), CinemaCityCitizen60 (1000, 1000, 1000, 1000, 1000), Normal (1800, 1300, 1800, 1300, 1100), Senior70 (1100, 1100, 1100, 1100, 1100), UnivStudent (1500, 1300, 1500, 1300, 1100), JuniorStudent (1000, 1000, 1000, 1000, 1000), Child (1000, 1000, 1000, 1000, 1000), Handicapped (1000, 1000, 1000, 1000, 1000), HandicappedJunior ( 900, 900, 900, 900, 900), MiCardMember (1600, 1300, 1600, 1300, 1100), ParkingPark (1400, 1100, 1400, 1100, 1100); // @formatter:on private int weekdayNormalPrice; private int weekdayLateShowPrice; private int holidayNormalPrice; private int holidayLateShowPrice; private int movieDayPrice; public BasePrice calcPrice(ScreenTimeType screenTimeType) { switch (screenTimeType) { case WeekdayNormal: return BasePrice.of(this.weekdayNormalPrice); case WeekdayLateShow: return BasePrice.of(this.weekdayLateShowPrice); case HolidayNormal: return BasePrice.of(this.holidayNormalPrice); case HolidayLateShow: return BasePrice.of(this.holidayLateShowPrice); case MovieDay: return BasePrice.of(this.movieDayPrice); default: throw new IllegalArgumentException(); } } } ``` ```java= /** * 上映時間区分を表すクラス */ public enum ScreenTimeType { WeekdayNormal, WeekdayLateShow, HolidayNormal, HolidayLateShow, MovieDay } ``` ```java= /** * 基本料金を表すクラス */ @AllArgsConstructor(access = AccessLevel.PRIVATE) public class BasePrice { private int value; public int intValue() { return value; } public static BasePrice of(int value) { return new BasePrice(value); } } ``` チケット料金モデリング === ###### tags: `DDD` `モデリング` ユースケース図 ``` @startuml left to right direction actor チケット購入者 rectangle { チケット購入者 --> (支払い金額を確認する) (支払い金額を確認する) ..> (割引を選択する) : <<include>> (支払い金額を確認する) ..> (映画、上映日時、枚数を選択する) : <<include>> } note bottom of チケット購入者 前提 ・当日会場で購入するときの処理とする ・映画→上映日時→枚数→割引の順番で選択するものとする ・支払い方法処理については一旦スコープアウトとする end note @enduml ``` ドメインモデル図 ``` @startuml skinparam packageStyle rectangle package 映画 { object 映画 { 映画ID タイトルなどその他諸々 } object 映像Dimension{ dimension(2D/3D) } 映画 "1" *-u- "1" 映像Dimension } package 上映 { object 上映 { 上映ID 映画ID } object 上映時間 { 曜日区分 (平日/土日祝) レイト時間帯 (true/false) 映画の日 (true/false) } 上映 "1" *-- "1" 上映時間 } 映画 <-u- 上映 package 予約 { object 予約 { 上映ID } object 適用3Dオプション { 3Dオプション区分(なし   /メガネレンタル/メガネ持参) } 予約 "1" *-- "1" 適用3Dオプション object 座席予約 { 年齢区分 (一般/70歳以上/学生(大・専)      /中・高校生/幼児(3才以上)・小学生) 障害者 (true/false) } 予約 "1" *-- "1..n" 座席予約 object 適用割引 { 割引タイプ (シネマシティズン    /エムアイカード/駐車場パーク80割引) } 座席予約 "1" *-- "0..1" 適用割引 note top of 適用割引 ・割引は1つしか適用されない ・シネマシティズンは年齢によって割引幅が変わる end note note top of 座席予約 ・1座席予約で1名分を表す ・障害者割引は同伴者1名にも適用されるので、  計算時に考慮する。 ・シニア、学生、中高生は身分証提示必要  オペレーションで確認するのでシステム上追加対応なし end note } 予約 --> 上映 package 料金設定 { object 上映時間区分 { 曜日区分 (平日/土日祝) レイト時間帯 (true/false) 映画の日 (true/false) } object 上映時間区分Calculator { } 上映時間区分 <-d- 上映時間区分Calculator 上映時間区分Calculator -u-> 上映時間 object 料金区分 { 料金区分(一般/シニア/シネマシティズン 等) } object 料金区分Calculator 料金区分 <-d- 料金区分Calculator 上映時間区分 <-r- 料金区分 note left of 料金区分Calculator ・入力した年齢、割引などをもとに  どの区分か判断する end note note left of 料金区分 ・料金区分×時間区分の  基本料金はここに定義する end note object 3Dオプション { 3Dオプション区分 値段 } 適用3Dオプション --> 3Dオプション } 座席予約 <-u- 料金区分Calculator 適用割引 <-u- 料金区分Calculator package 支払い料金 { object 支払い料金 { 合計金額 } } 上映時間区分 <-- 支払い料金 3Dオプション <-- 支払い料金 料金区分 <-- 支払い料金 note bottom of 支払い料金 ・1〜N件の座席予約を元に計算する end note note as N1 ・単一映画館が前提とする ・特別興行の場合は考慮しない end note @enduml ``` パッケージ図 ``` @startuml skinparam packageStyle rectangle object 映画 object 上映 object 予約 object 料金設定 object 支払い料金 映画 <-- 上映 上映 <-l- 予約 上映 <-- 料金設定 予約 <-- 料金設定 料金設定 <-l- 支払い料金 @enduml ```