# 11. Application Architectures ________________________________________ 1988-1997 Object-Oriented Software Construction 2nd Edition https://archive.eiffel.com/doc/oosc/page.html オブジェクト指向入門 第2版: 原則・コンセプト 絶版 参考サイト:OOSC - 超要約 https://seesaawiki.jp/supersummary/d/OOSC 1994 Design Patterns: Elements of Reusable Object-Oriented Software https://www.oreilly.com/library/view/design-patterns-elements/0201633612/ オブジェクト指向における再利用のためのデザインパターン https://www.sbcr.jp/product/4797311126/ 1996 Analysis Patterns: Reusable Object Models https://martinfowler.com/books/ap.html アナリシスパターン―再利用可能なオブジェクトモデル 絶版 2001 Core J2EE Patterns: Best Practices and Design Strategies https://www.oreilly.com/library/view/core-j2eetm-patterns/0130648841/ J2EEパターン―明暗を分ける設計の戦略 絶版 2002 Patterns of Enterprise Application Architecture https://www.martinfowler.com/books/eaa.html エンタープライズ アプリケーションアーキテクチャパターン https://www.shoeisha.co.jp/book/detail/9784798146515 Martin Fowler's Bliki (ja) PofEAA http://bliki-ja.github.io/pofeaa/ 2002 Object Design: Roles, Responsibilities, and Collaborations https://www.oreilly.com/library/view/object-design-roles/0201379430/ オブジェクトデザイン - 責務、コラボレーションによる設計技法 絶版 2003 Core J2EE Patterns: Best Practices and Design Strategies, Second Edition https://www.oreilly.com/library/view/core-j2eetm-patterns/0131422464/ J2EEパターン 第2版 絶版 Core J2EE Patterns http://www.corej2eepatterns.com/ 2003 Domain-Driven Design: Tackling Complexity in the Heart of Software https://www.oreilly.com/library/view/domain-driven-design-tackling/0321125215/ エリック・エヴァンスのドメイン駆動設計 https://www.shoeisha.co.jp/book/detail/9784798126708 2009 Microsoft Application Architecture Guide, 2nd Edition https://docs.microsoft.com/en-us/previous-versions/msp-n-p/ff650706(v=pandp.10) 2014 Microsoft .NET - Architecting Applications for the Enterprise, 2nd Edition https://www.microsoftpressstore.com/store/microsoft-.net-architecting-applications-for-the-enterprise-9780735685352 .NETのエンタープライズアプリケーションアーキテクチャ 第2版 https://bookplus.nikkei.com/atcl/catalog/15/P98480/ 2017 現場で役立つシステム設計の原則 〜変更を楽で安全にするオブジェクト指向の実践技法 https://gihyo.jp/book/2017/978-4-7741-9087-7 3層アーキテクチャー https://www.ibm.com/jp-ja/cloud/learn/three-tier-architecture ________________________________________ ## 1. Terms & Overview ________________________________________ ### 1.1. Terms Basic terms ```text [more old] Crud : - Factory : オブジェクトを生成して返す仕組みの総称 OOP : - [MVC] Model : ビジネスロジック。ViewやControllerを直接知らず、通知のみ出来る View : UI表現そのもの Controller : 入力のフィルタリングや加工の上、Modelに簡単な指示を行う(指示に対する詳細な動作はModel自身の責任) 補足。ControllerがViewを組み変えたり操作するのは事実上禁止。Viewは新しい状態を知り自分自身を最新にする [Web MVC] 1. MVCはViewがModelから変更通知を受け取り直接Modelを読み取ったが、Web MVCはControllerが仲介するようになった 2. UIとサーバで分離されControllerがエンドポイントになったため、「Controllerの差し替え」という概念が消えた [Design by Contract] Precondition : 事前条件。動作保証できる範囲の入力範囲。入力チェックvalidation Postcondition : 事後条件。操作後の状態が問題がないことをチェックするvalidation Object invariant : オブジェクト不変条件。validationをオブジェクト自体の性質に落とし込んだ時の言い方 オブジェクトが常に満たす必要がある状態や性質 [CQS] CQS : Command Query Separation. コマンド(Write)と問い合わせ(Read)は明確に分けろ Command : コマンド。CUD操作 Query : クエリ。問い合わせ。R操作 [OOSC] ADT : Abstract Data Type。抽象データ型。インターフェース指向&Value Object推進、の古い表現 Design by Contract : 前述の通り Open Closed : SOLIDのO No Side Effect : 副作用を避けよ CQS : 前述の通り [Architecture] Architectural pattern: Pofeaaなどを含む、特定の領域に対する具体的な方針 Architectural style : Soa/message bus、cs/3-tier、ddd、component base、oo、layered、mvc、restなど [J2EEパターン] DAO : DB製品ごとの固有の実装を吸収して操作を提供し、クエリならばdtoコレクションを返却する仕組み DTO : 単純な属性のみを持つオブジェクト。場合によってはシリアライズ・デシリアライズも提供する Pojo(poco) : - [PofEAA] PofEAA : Layeredアーキテクチャなどを前提とした特定の領域に対する方針カタログ ORM : active recordやdata mapperを実現する機構のこと [DDD] Aggregate root : 集約されたオブジェクトの内、ライフライクルや利用の基準となるもの Repository : pofeaa repository。sqlを隠ぺいしddd entityを返す、Aggregate rootと対になるファサード。DBトランザクション制御はしない [定義が複数ある用語] Entity(DB) : ERのE。いわゆるテーブルがEntity Type、いわゆるレコードがEntity Entity(DDD) : DDDの一意性を持つドメイン Service(PofEAA) : ビジネスロジックの外殻。サービス層。DDD文脈の狭義のアプリケーション層と同義。上のレイヤと1対1の粒度 ・入力情報の1次検証と調整、出力形式の調整 ・DBトランザクション制御 ・フレームワーク固有作法などの吸収(ドメイン層をピュアに保つ) ・上記3つが共通部品にする必要があるなら、共通部品化する役割も含む thin domain facade、fat application serviceの2種類の方針がある 概念的にはAPI設計そのものなのだが、実際には公開WebAPIは別途定義(URLルーティング)される Service(DDD) : DDDのDI前提なビジネスロジック部品。application service、domain service、infrastructure serviceに細分化できる Service(スラング1) : トランザクションスクリプトにおける、ビジネスロジックの本体のこと(※ PofEAAのコード例でもサービス層かつドメイン層なので○○Serviceと命名されている) Service(スラング2) : Railsフォロワーにおける、CとMの間にあるDI前提のビジネスロジック部品 役割としてはDDD Serviceなのだが、そもそもDDDしてないことが多く実質トランザクションスクリプトとユーティリティクラスの中間のような存在になりがち System Transaction : DBトランザクションの事 Business Transaction : 注文カート~購入確定までなどのような、複数の操作をまたがった一連の処理の事 ``` 3-tier and 3-layer? ```text https://docs.microsoft.com/en-us/previous-versions/msp-n-p/ee658117(v=pandp.10) この2つの違いは、MicrosoftやPofEAAで同様の言及がある 3-tierは例えばブラウザ、Applicationサーバー、DBサーバーがそれぞれ別の物理環境であるさまそのもの 3-layerは3-tierの考え方をApplicationサーバー内のプログラムに適用したもの ただしJ2EE Core Patternの○○tierのように、tierはlayerの意味でも使われる ``` Network toporogy terms ```text cs : msn messenger, skype for business hybrid p2p : msn messenger(file transfer), winmx, skype(login) super node : skype pure p2p : winny, indie games ``` ER terms ```text ER diagram ``` UML terms diagram |mean |detail -------------|------------------------------------|-------------------------------------- Use case |登場人物とシステムとの関係を整理する|アクターと業務作業を列挙し、線で結ぶ。システム境界を明確にする。外部システムはアクターとする Class |クラス関係を表す |ノード=クラス、矢印=関連/集約/汎化 Sequence |概念間の呼出時系列を表す |ノード=要素、生存期間、矢印=呼出しと返却 Communication|概念間の関係図を表す |ノード=要素、矢印=呼出しや参照関係。DDDの主軸 Statemachine |状態遷移図 |ノード=状態、矢印=操作 Activity |フローチャート |並列・同期のあるフローチャート Deployment |略 |略(記法が現実的でなく、そのままでは利用されない) Component |略 |略(記法が現実的でなく、そのままでは利用されない) - ________________________________________ ### 1.2. Well-known Architectures Web MVC 要素 |J2EE1.2~5 |Struts |Railsフォロワー|Spring boot + MyBatis --------------------|----------------|-----------------|---------------|------------------------ URL routing |DTD or web.xml |struts-config.xml|routing file |web.xml DI Container |- |- |(yes) |context.getBean() simple annotation |@WebServlet |- |- |@RequestMapping Middleware/filter/fc|- |- |(Middleware) |filter, DispatcherServlet Controller |HttpServlet |struts-config.xml|Controller |@Controller request dto |※1 ※2 |ActionForm Bean |(yes) |Form Bean Action |getPathInfo() |Action class |method name |method name Model(logic) |- |- |Model |- Model(dao/dto) |- |- |Model |MyBatis Form Support |- |- |- |SSR + Form Bean View |jsp |jsp(カスタムタグ)|Template engine|jsp + jstl + EL Http Session |getSession(true)|getSession(true) |session |※3 - ※1 Java系は、フロントコントローラであるServletがマルチスレッドであることに注意 ※2 jsp:setProperty name="foo" property="*"。ただし、空の場合変更されないため注意 ※3 @Scope(value = "session", proxyMode = ScopedProxyMode.TARGET_CLASS) multitier/layered architecture |2-tier |classical 3-layer(Analysis pattern) |IPA 3-layer |3-tier |AAfN |AAG |legacy ddd 4-layer |------------|------------------------------------|--------------------|------------|-------------|------------|------------------ |Application |Presentation(UI) + Application logic|Presentation |Presentation|Presentation |Presentation|UI |- |Domain |Function |Application |Business |Services |Application |- |- | |- |- |Business |Domain |Database |Data interface |Database access |Data |Data |Data |Infrastructure ※ IPAが使うFunctionの出典元が割と不明 ________________________________________ ### 1.3. 3-Layer vs Web MVC vs MVC vs MVVM ```text Template A View A A UI Public api Presentation A View View UIComponent Url routing V Controller | V Bind Action A V V Controller ViewModel Presentation Model/Event Handler Validation Business logic A A A A Validation Main logic V Model Model Model Main logic Repository A | | | Repository Pojo, orm Data | | | Pojo, orm Dao V V V V Dao ``` ________________________________________ ### 1.4. Webの基本パターン ```text [パターン] 1. Redisをセッションサーバにしてセッション状態の保持 2. 2つのアクセス制御戦略 - URIルーティング・ミドルウェアによるアクセス制御 - Viewテンプレートに埋め込むアクセス制御 3. 重複送信の対処 - クライアント :クライアントコードによるボタン非活性制御(2重サブミットの防止) - プレゼンテーション:同期(デジャブ)トークン(CSRFトークンの一種) - ビジネスロジック :楽観ロックバージョンチェック 4. バリデーション - クライアント側のUXのための簡易チェック - サーバ側のビジネスロジックレベルで必須なチェック - 方針1. フォームごとにバリデーターを用意 - 方針2. バリデーション要素自体のコンポーネント化とその組み合わせ - 方針3. Aggregate rootごとのバリデーターを用意 [アンチパターン] 1. Viewテンプレートにあるべきでない処理が書かれている - Viewテンプレートにアクセス制御の具体的な処理が書かれている - Viewテンプレートにビジネスロジックが直書きされている - dtoやDDD EntityからViewModelへの変換が、Viewテンプレート上で行われている 2. Http固有情報やフォーム上のデータ構造を、ビジネスロジック層やドメイン層に渡してしまう - ビジネスロジック層やドメイン層のクラスが、HttpServletRequestなどを引数に取ってしまっている。Pojo/Pocoになっていない 3. 重複送信を考慮していない 4. クライアントが機密情報にアクセスできてしまう 5. コントローラーが肥大化する 6. Java EEにおいて、jsp:setPropertyのライフサイクルや初期化サイクルを理解していない 7. Java EEにおいて、マルチスレッドを理解せずにメンバ変数やEJBを使ってしまう 8. MVCではなく、フロントコントローラも導入されていない 9. CSRFトークンを利用していない 10. URIルーティング(間接アクセス)が徹底されていない - 適切なパーミッションが設定されておらず、ディレクトリトラバーサル脆弱性を抱える 11. DAOやRepositoryが実装されていない [Html/Jsプラクティス] behavior(jQuery Behavior) - jsによる振る舞いをスクリプトコードに閉じ込め、html側はclass属性を付与するだけにする [帳票生成のプラクティス] スナップショットの保存 - マスタデータと業務データからスナップショットを作成する - 契約書など当時の印刷情報を確実に再出力したい場合が必ず出てくるため、スナップショットは必須である - 帳票用テーブルとして実装するか、生成ファイルを直接保存するかはどちらでもよい [日付のプラクティス] 1. SYSDATEは原則、ログやcreated_at、updated_at列以外では直接利用せず、1皮かぶせる 2. カレンダーマスタを用意する - 休日や祝日かどうかをシステムで見分ける必要があるなら、カレンダーマスタを作ればよい - システムの要件によっては、支店やレジごとに持つ必要がある 3. 営業日パラメータ - 営業日関連の日付は、SYSDATEを直接使わず、システムが保持する営業日パラメータで決定すると良い - システムの要件によっては、支店やレジごとに持つ必要がある [その他のセキュリティ対策プラクティス] ドキュメントルートリソースちゃんとパス書け問題 ``` ________________________________________ ### 1.5. UIとMVCの系譜 GUI Architectures https://martinfowler.com/eaaDev/uiArchs.html アーキテクチャ パターン: MVC、MVP、MVVM の説明 | AppMaster https://appmaster.io/ja/blog/akitekuchiya-patan-mvc-mvp-oyobi-mvvm Angular NgRx Store and Redux - When to use a Store and Why? https://blog.angular-university.io/angular-2-redux-ngrx-rxjs/ Fluxに至るまで ```text MVC : 原初のUIパターン MVP(Supervising C) : 古典2-1。MVVMに近い内容だが、View側にビューロジックが残っていてもよい MVP(Passive View) : 古典2-2。MVVMに近い内容。PresenterがほぼViewModel。Viewにビューロジックがない Form & Control : Visual Basicと共に登場したUIモデル Web MVC : ViewとModelのやりとりをなくしてControllerを仲介するようにしたMVC MVVM : 別名Presentation Model。詳細略。WPF関連の公式情報を参照のこと Flux : 一方通行が保証されたMVC。グローバル状態管理手法の1つ Action=EventArgs Dispatcher≒Controller。Storeを登録して通知するので、参照が逆転している Store=Model View≒View。ViewはStoreを参照しない Redux : Fluxの変形の1つ 1. ドメインロジックはStoreではなくReducer 2. Reducerは前の状態とActionをパラメータとして、状態遷移図を体現する 3. Dispatherの機能はActionと分かれていない ``` AngularにFluxのようなアプローチが流行らない理由 ```text グローバル状態はDIコンテナのシングルトンサービスに持たせて間に合うケースが多いため ``` ________________________________________ ## 2. J2EE Core Patterns ________________________________________ Presentation Tier ```text Intercepting Filter : Webフレームワークにおけるフィルターやミドルウェア。デコレーター。 Front Controller : WebフレームワークにおけるUriルーティング、リンク生成と解決、アクセス制御を実現する共通前処理のこと Application Controller : WebフレームワークにおけるControllerのこと。2ndにて追加 Context Object : 2ndにて追加。略 View Helper : WebフレームワークにおけるViewテンプレートエンジン機構の内、Viewとdtoの仲立ちをする役割のこと Composite View : WebフレームワークにおけるViewテンプレートエンジン機構の内、コンポーネント化に対応する仕組みのこと Dispatcher View : Front ControllerとView Helperを統合する方針の内、巨大なViewディスパッチャコンポーネント方針のこと Service To Worker : Front ControllerとView Helperを統合する方針の内、小さいViewディスパッチャコンポーネント方針のこと ``` Business Tier ```text Business Delegate : ビジネスロジック層の外殻としてあるファサード方針の1つ(ただし登場当初はService Locatorと併用が前提だった) Service Locator : 現在ではアンチパターン Session Facade : ビジネスロジック層の外殻としてあるファサード方針の1つ Application Service : ビジネスロジック層の外殻としてあるファサード方針の1つ。2ndにて追加 Business Object : 2ndにて追加。略 Composite Entity : DDD文脈以外でのAggregate rootのこと Transfer Object : dto。J2EE 1stの時点では、Value Objectと呼ばれていた。現在ではValue Objectと言えばDDD Value Objectを指す TO Assembler : モデルから適切なdtoを取り出すファサード Value List Handler : ページング等を自前実装する場合における、DAOに対するファサードなキャッシュ機構 ``` Integration Tier ```text Data Access Object : DAO Service Activator : 略 Domain Store : 2ndにて追加。略 Web Service Broker : 2ndにて追加。略 ``` ________________________________________ ## 3. PofEAA ________________________________________ ### 3.1. 一覧 Domain logic ```text Transaction script : ロジックを手続き階層として実装する。アンチddd Domain model : ロジックを概念に対応させた純粋なoopとして実装する。ddd Table module : ドメインロジックをテーブル単位でまとめる Service layer : リクエスト&レスポンス整形、DBトランザクション制御などを行う層。DDDで言うアプリケーション層 ``` Data Source Architectual Patterns ```text Table data gateway : テーブル単位でsqlコール用のgatewayクラスを作る Row data gateway : 行単位でcudを提供するgatewayクラス(cursor)とrするfinderクラス Active record : 行に対するDdd entity、ormのo(dto)、ormのm、sql隠蔽メソッドをすべて一つにした構造 Data mapper : ormの構造そのもの。Ormのo(dto)とdbの変換層。クエリビルダが併用された場合は操作コードが不格好で汚い (*) Railsではインスタンスがgateway、staticメンバがfinderとなっている ``` Object-relational behavioral patterns ```text Unit of work : ado.net dataset等の考え方。dtoまたはddd entityをダーティ管理し、後でまとめて永続領域に反映する Identify map : 同一レコードのdtoまたはddd entityが同一インスタンスを指すようにするため、OrmまたはRepositoryの裏側でキャッシュする 背景として、ビジネスロジックで必要な情報を読み出すパターンは以下の2つの方針が考えられる A. dtoは単なるデータの入れ物であり、インスタンスが存在の同一性を保証しない B. 同一の存在を指すdtoまたはddd entityは、インスタンスの同一性も保証する Identify mapは後者の方針を実現する方法の1つである これは理想的なDdd entityを実装するためには必須となり、Repositoryの裏側で併用される Lazy load : ormのレイジーロードのこと。実際に必要になるまでdbへ問い合わせをしない。外部キーormなど ``` Object-relational structural patterns ```text etc. ``` Object-relational metadata mapping patterns ```text Metadata mapping : Ormの実装例 Query object : クエリビルダの実装例(sqlに対するgofインタプリタ) Repository : Ddd entityを何らかのストレージに保存するための窓口。単純な仕組みの場合はDaoでもある ``` Web presentation patterns ```text Model view controller : Smalltalk-80 mvc, Web mvc の双方に言及 Page controller : = Web mvc's c Front controller : J2EE Coreパターン参照のこと Template view : テンプレートエンジン Transform view : Dddモデルから応答内容を生成する変換機構 Two step view : Viewの生成を2段階に分け、2段階目で全体デザイン等を決定する Application controller : Dddアプリケーション層の集中管理機構。コンテキストに対応するドメインコマンドとViewを得る ``` Distribution patterns ```text Remote facade : 外部に公開するapiを荒いファサードとして用意する Data transfer object : DTO。外部に通信するものは複数の情報をjsonやxmlにしてまとめて送る ``` Offline concurrency patterns ```text Optimistic offline lock : 楽観ロック。表示時にlsn取得、更新時にUPDATE foo SET lsn=lsn+1 WHERE pk=引数 AND lsn=引数 Pessimistic offline lock: 悲観ロック。排他ロックしてから表示 Coarse grained lock : 粗粒度ロック。用途から意味を戻すと親ロック、あるいはaggregate rootロックか。大きめのロック単位を規定する Implicit lock : 実装者は明示的に実装せずフレームワークで自動制御させるべき ``` Session state patterns ```text Client session state : クライアントに置く。webではセキュリティに難あり Server session state : セッション内容をシリアライズして保持 Database session state : セッション内容を内容ごとにカラム分けして保持 ``` Base patterns ```text Gateway : 概ねファサード。ファサードとメディエータの中間のような役割で、実装によってはアダプターを伴う Mapper : 上記が双方向の場合は、双方向の変換も考慮する Layer supertype : 各レイヤごとに基本型を用意する Separated interface : Dll分離時に、実装とインターフェースを別パッケージにする Registry : 限定的なグローバル変数の使用 Value object : 日付、お金、日付範囲、行列など Money : お金を表す構造体を作るべき Special case : Nullを返すな、専用のサブクラスインスタンスを返せ Plugin : プラグインはリフレクション等を利用して再コンパイル不要に Service stub : サードパーティツールのアクセスに対するテストスタブを作れるように Record set : あるデータ型と対になるuiに対して、gofプロキシを作り任意のロジックを挟みこむ ``` ________________________________________ ### 3.1.2. Further PofEAA Development of Further Patterns of Enterprise Application Architecture https://martinfowler.com/eaaDev/ Temporal Patterns ```text Audit Log : 監査ログ。更新操作とロギングをひとまとめにラップしたメソッド、あるいは自動ロギング機構 Time Point : 時点。必要な精度を保証(不要な情報をトリム)したりヘルパーメソッドを追加したDateTimeラッパValueObject Effectivity : 有効期間。有効期間のある情報。単属性なら時間的プロパティ、複数属性がまとまってるなら時間的オブジェクト Temporal Property : 時間的プロパティ。有効期間のある情報の取得方法として、集約オブジェクトが各プロパティの代わりに時点を引数に取る各メソッドを用意するアプローチ Temporal Object : 時間的オブジェクト。それぞれのオブジェクトが特定の有効期間に関する内容そのものとなったもの。こちらの方が一般的 Snapshot : スナップショット。時間的プロパティ/オブジェクトをアダプタパターンで時間を固定する ``` Events ```text Domain Event : ドメインイベント。業務上を出来事をそのままValueObjectあるいはEntityにしたもの。これをQueueしたり永続化することがEvent Sourcing Event Collaboration : イベントコラボレーション。各コンポーネントやオブジェクト間を敢えてイベント駆動で繋いでいく設計方針。メリットは疎結合、デメリットは全体の相互作用が不明瞭になる Event Sourcing : イベントソーシング。何か変更が必要な時、直接値を変更するのではなく変更したという操作そのもの(Domain Event)を追記していく Agreement Dispatcher : アグリメントディスパッチャ。ある程度方向性の定まったカスタマイズ可能なイベントハンドラ(処理機構)を用意するデザインパターン ・受信者は、処理をAgreementクラスとRuleクラスで記述された内容へ委譲する ・通常、AgreementクラスがセットアップされたAgreement自身を返すファクトリメソッドをいくつか持つ。あるいは派生クラスでファクトリメソッドを用意してもよい ・key=eventType、val=Ruleの連想配列がある(eventTypeはpub/subのtopicあるいはchannelに相当。イベントはeventTypeのプロパティを持つ) ・個々のファクトリメソッドは、上記の連想配列の固有なセットアップを行いAgreementを返す ・受信者は、個々のどれかのAgreementを保持し、そのAgreementに移譲することになる Parallel Model : イベントソーシングされた内容を解決せずにそのまま永続化。読み取り側が時点を指定して当時どうだったかをすべて算出する やりたいこと自体はバージョン管理システムと同じと言える Retroactive Event : 典型的なDBマイグレーションツールの考え方そのもの。UpとDownがペアになったイベントソーシング。あんまり有効な場面は多くない ``` Accounting Patterns ```text Account : 会計関連。略 Accounting Entry : 会計関連。略 Accounting Transaction : 会計関連。略 Replacement Adjustment : 会計関連。略 Reversal Adjustment : 会計関連。略 Difference Adjustment : 会計関連。略 ``` Presentation Patterns ```text Notification : 考え方自体は参考になるが、現在のWebではもう少し洗練された仕組みになっている。略 Supervising Controller : 古いMVC系(Webではない)におけるUI役割分担アプローチの1つ。UIはMVPのVとPに役割を分担せよ Passive View : 古いMVC系(Webではない)におけるUI役割分担アプローチの1つ。UIはMVPのVとPに分担するが、Vを受け身にしPが大半を制御せよ Presentation Model : 古いMVC系(Webではない)におけるUI役割分担アプローチの1つ。MVVMとほぼ同義 Event Aggregator : Pub/Subのこと。特にObservableを直接バインドできるが敢えて仲介者を挟むニュアンスが強い Window Driver : 各UIコンポーネントを直接操作するのではなく、UI側にAPI層を追加してUIの更新や操作を簡略化・統一する。特にUI操作と等価なことが出来るようなAPIを用意する Flow Synchronization : 例えば非モーダルウィンドウ同士で表示を同期したい場合、アクティブウィンドウが変わる時など特定のタイミングでデータを読み直す。単純な場合に使いやすい Observer Synchronization : 例えば非モーダルウィンドウ同士で表示を同期したい場合、コアデータがObservable、各ViewがObserverにする。つまり古典的なMVCそのもの。画面が多い場合はこちらが良い Presentation Chooser : あるウインドウの特定の操作が別のウインドウを開くが、どれを開くかはデータや設定の状況によって異なる必要がある場合、何を開くかを判断することのみを行う仕組みを用意する Separated Presentation : プレゼンテーション層またはAPI/コントローラ/アプリケーション層と、ドメイン層をそもそもモジュールを分ける。ドメインは他者を知らない。 ``` ________________________________________ ### 3.2. 楽観ロック詳細 意味 ```text 更新対象が読み取った時の世代と同じなら、別の誰も更新してないから更新してOK ``` シンプルな例 ```text 1. 表示時にLSNも取得する 2. UPDATE foo SET lsn=lsn+1 WHERE pk=引数 AND lsn=引数 3. 更新行数が0行の場合例外発生させる ``` 注意すべきポイント 1. 更新先と読み取り元が異なる場合 - そのままでは読み取り元の値が変わっても、更新先のLSNとしては問題ないため更新できてしまう - 方針1:更新先の更新を行うビジネスロジックが、読み取り元に対してもLSNチェックする - 方針2:粗粒度ロックと併用する ________________________________________ ### 3.2. 粗粒度ロック詳細 意味 ```text いつでもまとめて考えることができる単位は、その単位でロックを管理すればいいよね ``` 前提 ```text ビジネスロジックの真の不変条件と境界こそが、集約ルートの基準になるべきである(iDDDより) 言い換えると、DBトランザクション整合性が何が必要で、結果整合性は何が必要で、DBトランザクション整合性が集約ルートの基準になる ・トランザクション整合性:DBレベルで常に維持したいこと。DBトランザクションと対 ・結果整合性 :Revertな処理や再実施等の操作をユーザや非同期バッチが行うことで、最終的に所望の状態に持っていけるようにすること ``` 例 ```text トランザクションスクリプトの場合 1. 表示時に親のLSNも取得する 2. 子の更新時に、親も楽観ロックに従って処理する 3. 親が更新できなかった場合、全てロールバックする DDDの場合 集約ルートに対応させる ``` 詳細記事 Martin Fowler's Bliki (ja) PofEAA の Coarse grained lock http://bliki-ja.github.io/pofeaa/ 実践ドメイン駆動設計 の第10章 https://www.shoeisha.co.jp/book/detail/9784798131610 ________________________________________ ## 4. Interface Design for Http ________________________________________ REST URL format samples ```text Simple URL1 : https://domain:port/ja-jp/path?foo=a&bar=b#section1 Simple URL2 : https://ja-jp.domain:port/path?foo=a&bar=b#section1 App page URL : https://domain:port/(prefix/)controller/action/id RESTful URL1 : https://domain:port/api/v1/resources/uuid/resources/uuid/... RESTful URL2 : https://api.domain:port/v1/resources/uuid/resources/uuid/... ``` RESTful ```text 1. Resource is address without query-string. 2. Use http method as a operator. - GET(read) - POST(auto increment create etc.) - PUT(idempotent create & update. e.g. replace.) - PATCH(update part of resources) - DELETE(delete) 3. Use http response as a result. 4. Stateless. ``` ________________________________________ ## 5. システム間のやり取り ________________________________________ 方式の分類 ```text 1. ファイル転送 2. 同期RPC 3. 非同期RPC 4. メッセージング(非同期)。典型的な実装は再送機能付きpub/sub ``` 過去のプロトコル ```text [DCOM] COMのCreateObject()にIP引数が追加されマシン間でもCOM呼び出しを可能にしたもの OSがブローカーを兼ねる [CORBA] ライブラリ例はJava IDLなど サーバ側はサーバプログラム本体とORBを起動し、クライアントはORB経由で参照を取得 [RMI] Java用の仕組み 概ねDCOMとほぼ同一の使用感 ``` 典型的なプロトコル ```text [単純] 指定ディレクトリへのcsvファイル転送&読み込み [WSDL/SOAP] asmx、apache axis2など wsdlを読み取ることでスケルトンクラスの自動生成が可能なのが売り [RESTful/Json] シンプル ``` ________________________________________ ## 6. 結果整合性 ________________________________________ 結果整合性の例 - DNS - privateレベルで一時的に不変条件を満たさなくなるオブジェクト - イベントソーシングにおけるジャーナルリプレイ ________________________________________ ## 7. その他、理解の助けになる記事 ________________________________________ Refactoring to Functional–Why Class? https://hadihariri.com/2013/11/24/refactoring-to-functionalwhy-class/ GUI Architectures https://martinfowler.com/eaaDev/uiArchs.html Chapter 3: Architectural Patterns and Styles https://docs.microsoft.com/en-us/previous-versions/msp-n-p/ee658117(v=pandp.10) ASP.NET Core および Azure での最新の Web アプリケーションの設計 https://docs.microsoft.com/ja-jp/dotnet/standard/modern-web-apps-azure-architecture/