Upgrade to Pro — share decks privately, control downloads, hide ads and more …

フロントエンドでDDDやってみた

ak2ie
July 03, 2022

 フロントエンドでDDDやってみた

「#Webフロントエンド なんでもLT 会 #5」での発表内容です。
https://ncdc-dev.connpass.com/event/248156/

ak2ie

July 03, 2022
Tweet

More Decks by ak2ie

Other Decks in Technology

Transcript

  1. ValueObject • ドメイン固有の概念を値として表す • 「金額」や「税率」を ValueObjectとして定義 • 作成時の数値チェックや金額計算のミスを防止 export class

    Price extends PrimitiveValueObject <number> { static create(value: number): Price { if (value < 0) { throw new Error('金額には0円以上を指定してください ') } return new Price(value) }
  2. ValueObject • 加算:金額同士のみ public add(value: Price) { return Price.create(this.price +

    value.price) } • 乗算:金額×税率 public times(value: TaxRate) { return Price.create(this.price * value.rate) }
  3. ドメインサービス export class TaxService { /** * 一日当たりの税額算出 * @param

    param * @returns 税額(単位 :円) */ public calcTax(param: { person: Person government : Government cofogCode : CofogCode }): Price | null { const taxAmount = this.calcAmountTax ({ person: param.person, government: param.government , })
  4. ドメインのテスト const person = new Person({ salary: Price.create(10000000 ), homeType:

    HOME_TYPE .SINGLE, }) const govFactory = new GovernmentFactory (wrapper.vm) const goverment = govFactory .Get() const service = new TaxService (wrapper.vm) expect( service.calcTax({ person, government: goverment , cofogCode: CofogCode .create({...}), }) ).toEqual(Price.create(((10000000 - 330000) * 0.06 * 2000) / 10000 / 365))
  5. リポジトリ • StoreやAPIからのデータ取得はリポジトリを通して行うことで統一した export class HogeRepository { public GetStoreData(): Data

    | null { const storeData = this.app.store?.getters['storeData'] } } export class HogeHogeRepository { public async GetAPIData(): Promise<APIResponse> { const apiResponse = await this.app.$axios.$get<APIResponse>(uri) } }
  6. リポジトリの定義 declare module '@nuxt/types' { interface NuxtAppOptions { readonly $repositories:

    <K extends keyof Repositories>(key: K) => ReturnType<Repositories[K]> } } declare module 'vue/types/vue' { interface Vue { readonly $repositories: <K extends keyof Repositories>(key: K) => ReturnType<Repositories[K]> } }