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

20230916 - DDDTW - 導入 Domain-Driven Design 的最佳時機

20230916 - DDDTW - 導入 Domain-Driven Design 的最佳時機

蒼時弦や

October 05, 2023
Tweet

More Decks by 蒼時弦や

Other Decks in Programming

Transcript

  1. Epic 1 - Q1 Epic 2 - Q2 Feat 1

    - W1 Feat 2 - W3 Feat 3 - W1 Feat 4 - W2 從敏捷的角度,我們把一次改版切割成以功能單位來看
  2. Epic 1 - Q1 Epic 2 - Q2 Feat 1

    - W1 Feat 2 - W3 Feat 3 - W1 Feat 4 - W2 Feat 5 - W3 也可以很彈性對應變化,調整某個功能的優先順序
  3. // Golang // ... package type interface error error {

    (context.Context) (context.Context) } daemon Service Start Stop
  4. // Golang package type struct func * error return func

    * error return { http.Server } (s HttpServer) (ctx context.Context) { s. () } (s HttpServer) (ctx context.Context) { s. (ctx) } main HttpServer Start Stop ListenAndServe Shutdown
  5. // Golang // ... package import func := & &

    if := != ( ) () { d daemon. ( HttpServer{ Addr: }, GrpcServer{ Addr: }, ) err d. (context. ()); err { (err) } } main myapp/pkg/daemon main " " ":8080" ":8081" New Run Background nil panic
  6. Scenario When Then : I click I can see When

    user click "Toggle" button and show "Hello" "Toggle" "Hello" # 介面:Button() # 輸入:ClickEvent(Label="Toggle") # 輸出:String("Hello")
  7. #language:zh-TW 功能 場景 假設 | token | name | type

    | | 1234567890 | 蒼時 | 一般票 | 當 那麼 : : 有一張票券 我發出 GET 請求到 我會看到 JSON 格式的回應 票券資訊 當查詢票券資訊時,可以看到名稱和票種 "/status?token=1234567890" """ { "name": "蒼時", "type": "一般票" } """
  8. interface extends : interface : : export async function :

    : return { ; } { ; ; } ( ) < > { { name: , type: , }; } AttendeeInfoRequest HttpRequest AttendeeInfoResponse statusHandler AttendeeInfoRequest Promise AttendeeInfoResponse token name type request string string string // ... '蒼時' '一般票'
  9. interface : : & export async function : : const

    = const = await return { ; } HttpRequest ( ) < > { { , } request; attendeeUsecase. (token); { name: attendee.name, type: attendee.type, } } AttendeeInfoRequest AttendeeUsecase statusHandler AttendeeInfoRequest Promise AttendeeInfoResponse getAttendee token attendeeUsecase request string token attendeeUsecase attendee // ... // ...
  10. interface : : export class async : : return {

    ; ; } { ( ) < > { { name: , type: , }; } } AttendeeInfo AttendeeUsecase getAttendee Promise AttendeeInfo name type token string string string // ... '蒼時' '一般票'
  11. // ... // ... export class public readonly : public

    readonly : private ?: constructor : : = = = new { ; ; ; ( , ) { .name name; .type type; } () { ._lastUsedAt (); } } Attendee AttendeeType Date AttendeeType touch name type _lastUsedAt name type string string this this this Date
  12. export class private : async : : const : =

    await await return { ; ( ) < > { .attendees. (token); attendee. (); .attendees. (attendee); { name: attendee.name, type: attendee.type, }; } } AttendeeUsecase AttendeeRepository getAttendee Promise AttendeeInfo Attendee findByToken touch save // Next // ... attendees token string attendee this this
  13. type = : : export class async : : const

    = return new { ; ; }; { ( ) < > { .database . ( , [token]) . < >(token); ({ name: res.name, type: res.type, }); } } AttendeeSchema PostgresAttendeeRepository findByToken Promise Attendee prepare first AttendeeSchema Attendee name type token string number string res this // ... '[SQL]'
  14. AttendeeInfoRequest / AttendeeInfoResponse getAttendee(token) / AttendeeInfo AttendeeRepository Attendee Infrastructure 的介面會照

    Presenter / Application 需要而定, 沒辦法契合時則會實作 Adapter 來對應