📜 제목으로 보기

계약과 거래를 하는 트랜잭션 관계

계약하기

  • 형태
    • 인 doctor가 reception들에게 [void setter/boolean 거래 제안기능]을 통해, [거래조건]과 함께 먼저 알고서 데리고 온다.
      • [거래 제안기능]은 내부에서 갑인 reception의 [boolean 거래 수락기능]을 통해 결과를 받아와서, 결국엔 내부 필드에 계약자들을 저장하는 void setter받기기능과 유사한 형태며, boolean으로 doctor를 사용하는 사람에게 알려줘도 된다.
    • 인 reception은 [boolean 거래 수락기능]을 통해, doctor와 [거래조건]을 알고서 데려가 검증한 뒤, 성공시 필드에 거래조건과 함께 저장하며, boolean으로 수락여부를 을인 doctor에게 알려준다.
      • 계약이든 거래든 갑이 데리고 가서 검증/결정후 결과를 반환해서 알려주면 을은 결과에 따라서 행동한다.
  1. 을(doctor)가 먼저 [boolean 거래제안 기능]을 거래대상인 갑(reception)에게 [거래조건]과 함께 제안한다.

    image-20220629213237291

  2. doctor의 계약제안 기능의 내부에서는

    • 갑의 [boolean 계약수락 기능]을 호출한 뒤, 반환받은 결과에 따라 행동한다.

    • 추가로 이미 계약중(컬렉션필드 -> CRUD 생각 -> CREATE시 중복검증)되면 안된다.
      • if A && B 여야만 수행 -> 컬렉션에 계약자로 추가
        • **if not A   not B -> return false (early return) -> 수행**
          • 만족(if A) 시 수행이라면 not A early return을 고려한다.
          • **둘다 만족시(if A && B) 수행이라면, not A   not B early return을 고려한다.**
            • **둘다 return값이 동일하다면,   로 묶어서 한번에 early return**
          • not A return (early) false ;
          • not B return (early) false;
          • 수행
            • == not A   not B reutrn (early) false;
            • == 수행
    • Set컬렉션을 쓰고 있으므로 중복검증(A)는 생략한다.
      • if not B early return 후 수행만 하면 된다.

    cb007026-e263-4ec9-a44e-2ca1dffa774d

    image-20220629213706946

  3. reception의 거래수락 기능 내부에서는

    1. 거래대상과, 거래조건을 매칭해서 저장할 HashMap 필드를 만들고
    2. (거래는 상대방의 돈검증) 이미 계약중인지, 거래대상 검증(중복검증)을 한다.
    3. (거래는 내가 줄 물건검증) 계약대상과 계약조건을 내부필드에 저장하여 계약한다.
    4. (거래는 상대방 돈차감 -> 물건반환) 수락여부true를 반환한다. (검증실패시 false)

    fd6c3c9d-767e-4061-a23e-86eac71cbf50

    image-20220629214322785

    image-20220629214256145

  4. 계약 제안/수락 기능처럼, 계약취소 제안/수락기능도 있다.

    1. 계약취소 제안기능(DELETE)

      • A: 계약취소 대상자 존재 검증 && B:갑의 계약취소 수락기능의 결과가 true

        • 둘다 만족해야지 수행
          • **not A   not B early return한다.**

        9761c111-683a-4a64-a5e5-eb9a43908dcf

        image-20220629220352023

    2. 계약취소 수락기능(DELETE)

      • 갑으로서 누구의 결과를 기다리지 않으니, 삭제 전 존재 검증만 하면 된다.

        df449e6b-fbff-4e44-ba9d-66455e177081

      image-20220629220807026

거래하기

  • 참고

    거래이미지

    • Patient가 [void setter구매기능]을 통해 거래를 제안한다.

    • Coordinator는 최초 [getter물건 판매기능]을 제공하고, Patient에게 결과를 [물건반환]으로 알려주는데, 실패시 NULL객체를 반환한다. (NULL객체를 쓰는 순간, boolean의 반환이 필요없어진다.)

      • A(돈 검증) && B(물건 검증)시 상대방의 돈을 차감한다. 돈 가산은 물건을 주는 Reception에게 미룬다.
        • not A   not B early NULL객체 return을 해도 될 것 같지만.
          • if A 와 if B 사이에 로직이 존재하여 early return이 불가하다.
        • 이 땐, 실패의 else마다 똑같은 값이 반환되므로, 애초에 반환값을 EMPTY(NULL객체)로 변수로 선언해놓고 시작하고, 성공시 재할당하여, 마지막에만 해당 변수를 return한다.
      1. [상대방 돈 검증] 하기 전, 검증기준인 [물건의 가격을 계산]해야한다.

        • Coordinator는 계산의 책임을 수수료를 챙겨서 계산하는 Reception에게 [물건 가격 계산]도 위임한다.

        • 사실, 물건가격계산은, 정책이 적용될 Specialty객체로 바로 할 수 있지만, 의존성이 1곳에서만 생기도록 Reception에게 위임한다.

      2. [상대방 돈 검증]

      3. [건네줄 물건 검증]을 하기 전, 검증 기준은 [물건]을 받아와야한다.

        • Coordinator는 최초 물건 발행권자인 Doctor로부터 생성해서 받아와야하므로 [getter물건 판매기능]을 Coordinator -> Reception -> Doctor까지 연쇄적으로 호출해서 물건을 받아온다.
      4. [받아온 물건 검증]

      5. [상대방 돈차감]

        • 돈 가산은 계산의 책임이 있는 Reception에서, Reception의 [판매기능]내에서 이루어지게 한다.
      6. [물건 반환]

    • Reception

      1. 연쇄적인 [getter물건 판매기능]안에서 들어오는 [구매정보 검증]을 한다.
        • 돈 검증은 구매자와 최초연결된 Coordinator에서 담당한다.
        • [정보 검증]을 통해, Doctor로 가서 Package발행 전에 NULL객체를 물건으로 반환해서 미리 컷한다.
      2. [물건 검증]전, 물건을 Doctor의 [getter물건 판매기능]으로 떼온다.
        • 수량제한에 걸려서 Doctor가 NULL을 건네줄 수 있다.
      3. [물건 검증]
      4. [돈 가산]
        • 물건이 검증되면, Coordinator의 돈차감과 같은 레벨로 [돈 가산]을 해야한다.
        • 구매정보에 담긴 (정책적용객체) Specialty에서 물건가격을 계산하고
        • **구매정보의 doctor와 계약된 commisionRate를 꺼내서, 수수료를 계산해, [내 자본금을 가산] **한 뒤
        • 물건가격 -수수료 만큼을 [발행권자 doctor에게 가산]해준다.
          • 계산은 Reception에서만 이루어져서 나도 챙기고, 발행권자도 챙겨준다.
      5. [물건 반환]
    • Doctor

      • 연쇄적인 [getter물건 판매기능]을 통해 물건을 생성해야하는데
      1. 내가 소유하고 있는 정보로 [구매정보 검증]한다.
        • Reception에서 컷 안당했지만, doctor만의 소유정보로 컷 당할 수 있다.
        • 예를 들어, Specialty - Treatment들의 매칭 정보
      2. [발행 전 발행가능 갯수 검증]을 한다.
        • 발행가능 갯수는 Treatment의 count로 명시되어있으며, 생성될때마다 감산되어야한다.
          • 발행가능한지 검증(trigger) 실패시 runtime에러를 낸다.
      3. [물건 발행하여 반환]한다.
  1. 환자는 [void setter 구매기능]을 통해 Coordinator(거래대상, 갑) 이외에 구매package정보들 from 발행doctor내부정보와 구매 갯수를 같이 인자로 넘긴다.

    image-20220630005501089

  2. 구매기능 내부에서는, 거래의 갑인 Coordinator의 [getter물건 판매기능]을 이용하여 반환받아 저장한다.

    • 실패시 NULL객체가 반환되도록 짤 예정이므로 바로 필드에 저장만 하면 된다.

    image-20220630005607331

  3. coordinator(seller)의 판매기능은 거래 성공의 조건이 if + 로직 + if로 복잡하고 까다롭기 때문에

    • 그외 많은 경우가 실패이므로 early return없이 default NULL객체가 반환되도록 미리 반환변수를 NULL객체로 선언하고, 성공의 경우 재할당해주도록 짠다.

    image-20220630010223294

    • 쿠폰 유무의 경우의 수를 if + else 로 하기 싫다면 if + if 혹은 if-earlyreturn + NoIf 를 선택한다. image-20220630010947463
  4. 일반적인 쿠폰이 없는 경우부터 작성한다. Seller가 먼저 상대방의 돈 검증을 시행해서 돈 없으면 컷 해야한다. 그러기 위해선, 돈 검증 전에, 물건(Package)의 가격을 계산해야한다.

      • 가격계산은 가격정책이 적용될 예정 && fee를 가지고 있는 Specialty객체로 할 수 있다.
      • 그러나, specialty를 Coordinator내부에서 사용할 경우 vs 전달만 할 경우 의존성을 가지냐 안가지냐의 차이를 가지므로 specialty를 받아가고, 계산도 할 Reception에게 가격 계산의 책임을 위임한다.

      • 구매 물건의 가격을 계산시, 1개당 가격정보를 포함하는 Specialty + 몇개 살 것인지 Count도 같이 받아야지 총 금액이 계산된다.
        • 또한, 차후 정책조건의 trigger에서 sequence/time 등을 조건판단 정보로 주려고, 지금은 사용하지 않는 treatment도 같이 넘겨준다.

      image-20220630024309178

      • reception의 판매기능 내부에서도 결국 가격은 fee필드를 가진 specialty가 한다.

        image-20220630025235621

      • 정책이 없다면, specialty는 내부 1개당 가격 X count를 해준다. 나중에 NONE POLICY에서 이걸 반환하면 될 듯 하다.

        image-20220630121500908

      • 맞는지는 모르겠지만, count만큼 돌면서 money를 더해서 곱하기를 만들었다. image-20220630121545120

  5. 구매자 돈 검증

    image-20220630123230334

  6. 물건 검증 전에, 물건 떼오기 from Reception image-20220630135717187

    • 물건을 생성해주는 Doctor까지 위해 정보들을 다 전달해줘야한다.
    • Coordinator와 연결된 Reception에게 doctor부터 물건정보 + 갯수까지 다 전달한다.

    • 물건을 떼오는 것도, reception입장에서는 getter물건 판매기능으로서, 실패시 NULL객체를 반환, 성공시 정상물건이 온다.
      • 이 때, default NULL객체의 물건반환변수에 재할당한다.

    image-20220630123532470

    • reception은 앞에서 이미 상대방 돈검증으로 미리 컷 가능하게 했으니, 구매정보 검증을 통해 doctor에게 가기전 컷(NULL객체로 물건반환)할 수 있게한다.

      • 3가지 구매정보 검증( A&& B&& C)을 다 통과해야하지, 판매가 진행되므로

        • **not A   not B   not C** -> early return false대신 NULL객체를 사용한다.

        image-20220630134604418

      • doctor가 제공하는 isValidMatching

        image-20220630124711469

      • treatment가 제공하는 구매가능갯수 검증

        image-20220630132627284

    • doctor[getter물건 판매기능]으로 물건을 만들어서 반환해줘야한다. image-20220630134541595

      • 내부에서는 생성전, 구매정보 검증하여 미리 컷(NULL객체 반환)

        • 돈 검증 대신 구매정보 검증한다.
      • 발행(생산)전, 구매갯수가능 검증 및 차감

        • 물건검증->돈차감 대신 생산가능갯수 검증 및 갯수 차감을 한다. 차감의 책임은 treatment에 있으며, count필드로 조정한다.
      • 물건 생성하여 반환

        image-20220630135555024

    • reception은 떼온 물건을 검증한다.

      image-20220630135849470

    • reception은 구매자돈차감(Coordinator)대신 돈 가산(reception-커미션, doctor-나머지 금액)을 한다.

      image-20220630140807614

    • recpetion은 물건을 반환한다.

      • if 물건검증 통과시만 돈계산이 이루어지고, 내부에서 반환은 안한다.
        • if 내부에서하지 않아도 이미 물건떼오기에서 반환받은 물건은 if와 무관하게반환될 물건은 결정된 상황이기 때문이다.
        • 반환될 물건은 이미 결정, if 정상물건일시, 돈계산 추가

      image-20220630142409828

  7. 떼온 물건 검증 후 -> 환자(구매자)의 돈차감

    image-20220630185008015

  8. 쿠폰이 있는 경우는, Coordinator가 어떻게 해야할까

    • 돈계산 -> 돈검증안한다.
    • 물건 떼오기 -> 물건 검증 -> 돈차감이 아니라 쿠폰차감 with count만큼
  9. 일단 reception에게 물건을 공짜로 가져온다. image-20220630185944884

    • reception에서는 doctor에게 발행하여 물건 받아오는 과정이 완전히 동일하기 때문에

      • sellPackage 메서드를 그대로 쓴다.
      • doctor의 기능은 돈계산이 없이 정보검증 -> 구매가능갯수 차감 -> 발행의 3단계만 거치기 때문이다.

      image-20220630190530535

    • reception은 물건검증 성공시 돈차감했었는데, 돈차감이 없으니 물건검증도 생략한다. image-20220630191224044

  10. Coordinator에서는 물건 검증이 되면, 돈차감 대신 patient의 쿠폰을 차감한다. 여러개 골랐으면 갯수만큼 차감해야한다.

    image-20220630191408520

  11. patient는 Coupon coupon = Coupon.EMPTY로 1개 밖에 못들고 있게 설계되었다.

    • 여러개 쿠폰을 가질 수 있게 coupon필드를 컬렉션으로 바꿔줘야한다.

      image-20220630191757079

      • 필드를 바꾸면 getter나 eq/hC도 변경해준다.
      • setter도 할당이 아니라 add로 바꿔준다. / remove도 NULL객체 할당에서 remove(0)으로 바꿔준다.
    • 컬렉션 필드의 검증은 EMTPY(NULL객체)가 아니라 size로 하도록 다시 다 바꿔줘야한다. image-20220630192036354

  12. 돈계산 -> 돈검증 대신, 돈검증 자리에 구매count만큼 Coupon을 들고 있는지도 검증한다.

    image-20220630192912538

    image-20220630192928861

    image-20220630193047170

  13. 원래로직을 유지하고 (뒤에 쿠폰없는 상황에 대한 early return이 껴있는 상황)

    • 쿠폰 갯수가 모자랄 땐, 에러메세지로 알려주도록 early thr를 던졌다.
    • 그대로 두면, 쿠폰갯수가 모자라면 NULL객체로 갈텐데, 그것보다 직접 알려준다.

    image-20220630193410116

  14. Doctor -> Paitent 쿠폰 주는 것에 대해, 갯수를 정해서 주고, 차감시에도 여러개 차감하게 한다.

    • 쿠폰 직접주기 in Doctor by Client image-20220630230803854

    • 쿠폰 차감 in Patient by Coordinator (돈 차감 대신)

      image-20220630230844517 image-20220630233703119

  15. Package와 Coupon을 발행하는 Doctor(생산자)는 Patient(구매자)가 가진 데이터객체(Package)를 확인하는 검증을 한다.

    • Doctor는 필드에 무리하게 Many테이블의 정보를 컬렉션으로 모은 상태의 정보전문가로 만들어놨다.
      • 원래 DB에서는 Many테이블의 One테이블의 정보를 fk로 가진다.

    image-20220630234523167

    • Doctor가 Paitent들의 구매한 Package들을 검증한다.

      image-20220630234818309

  16. Doctor는 내부정보로 검증할 예정이므로 Patient를 인자로 받아서

    1. 물건 제공받기 by getter
      1. 물건 검증(기본) : NULL객체 검증
      2. 물건 기본정보(필드) 검증 by getter
        1. 발행권자로 받은 것(Doctor자신)
        2. 상하위도메인 매칭정보 검증
          • Treatment는 사기전 count필드와 사고난 후 count필드가 변한다
          • 구매정보 비교시, 구매 전후로 변하는 필드인 Counteq/hC에서 제외한다. image-20220701004331144
        3. 구매한 갯수 vs 검증할 갯수 검증

    image-20220701000335895

  17. A && B && C && D의 검증은 검증마다 early thr를 날려서 어떤 것에 검증실패했는지 알려주도록 변경한다.

    image-20220701004515665