LoginSignup
2
4

More than 3 years have passed since last update.

Salesforceで実現するDomain Driven Design(DDD)

Last updated at Posted at 2021-01-15

参照関係

SalesforceでDDDを実現した場合の参照関係は以下のようになります。

image.png

インフラ層(オレンジ)

DBや外部APIに接続する部分になります。
DAOもこちらに該当します。

ドメイン層(グリーン)

システムにおける知識を持ったクラスが該当します。
ドメイン層は二つに分けられます。
 ・ドメインモデル
   ⇒ふるまい・ルールを持ったオブジェクト
 ・ドメインサービス
   ⇒ドメインモデルで表し切れない処理をここに書く
SalesforceにおいてはsObjectが最もドメインモデルに近いかと思います。
なので、ドメインモデルクラスは作りません。
ドメインサービスはsObjectを補助するようなクラスにします。(バリデーションチェックなどが該当)

アプリケーション層(ブルー)

ここではシステムにおけるユースケースに対応するクラスが該当します。

UI/Batch/Trigger/GlobalAPI層(グレー)

ユースケース処理を呼ぶクライアント層になります。
Salesforceでは、UI(Visualforce・LightningComponent等)、Batch、Trigger、GlobalAPI(Apexの外部公開カスタムAPI)が該当します。

高レベルから低レベルへ依存させる

依存は高レベル(より人間に近い動き)から低レベル(より機械に近い動き)に参照させます。
それぞれのパターンから入ってきたユースケースを低次元の処理を使って解決させていきます。

サンプルアプリ

要件

■Contact Create Page
 ・Contactレコードが作成できる
 ・「Account Phone」が同じAccountレコードが既に存在している場合は、そのレコードをContactレコードに紐づける
 ・「Account Phone」が同じAccountレコードがない場合は、作成してそのレコードをContactレコードに紐づける
image.png
image.png

■Contact Table
 ・Contact Create Pageで作成したレコードが表示される
image.png

クラス構成

以下がサンプルアプリのソースコードです。
https://github.com/MASA-JAPAN/Salesforce-DDD-Template

処理概要

■Contact Create Page
LWCフレームワークで開発しております。
コントローラ(dddContactCreateController.cls)は一番上のグレー層に該当します。
こちらからContactApplicationService(アプリケーション層)のユースケース処理(createNewDddContact)を呼びます。

public with sharing class dddContactCreateController {
    public dddContactCreateController() {

    }

    @AuraEnabled
    public static String clickAction( String AccountName, String AccountPhone, String LastName, String FirstName ){
        ContactApplicationService contactAppService = new ContactApplicationService();
        return contactAppService.createNewDddContact(AccountName, AccountPhone, LastName, FirstName);
    }
}

createNewDddContactでは、ドメイン層(sObjectとObjectService層)とインフラ層(DAO)を駆使してユースケースを実現してます。

    public Id createNewDddContact( String AccountName, String AccountPhone, String LastName, String FirstName ){

        //If there is not an Account record, create it.
        AccountService accountService = new AccountService();
        Account targetAccount = new Account( Name = AccountName, Phone = AccountPhone );
        List<Account> sameAccounts = new List<Account>( accountService.getSameAccount(targetAccount) );
        if( sameAccounts.size() == 1){
            targetAccount = sameAccounts[0];
        } else if( sameAccounts.size() == 0 ){
            insert targetAccount;
        } else {
            throw new ContactApplicationServiceException('Phone ' + AccountPhone + ' is duplicated' );
        }

        Contact contact = new Contact(AccountId = targetAccount.Id, LastName = LastName, FirstName = FirstName, LeadSource = 'DDD' );
        insert contact;
        return contact.Id;
    }

さらに詳しくはGithubのソースコードを見て頂ければと思います。

まとめ

ざーっと書いてみました、まだまだブラッシュアップすべき点は満載です!
是非コメント頂けると嬉しいです。

2
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
4