1
/
5

ドメインを分析し、設計に落とし込むには? #devsumi

2024年7月23日(火)24日(水)にJPタワー ホール&カンファレンスでおこなわれた「Developers Summit 2024 Summer」。

23日にはCTOの畠中が登壇。ドメインを分析して設計に落とし込む方法について話をしました。本記事では来場の方からも好評いただいた、2つのSaaSをフルスクラッチで開発した経験にもとづく手法を紹介します。

「ドメインを分析し、設計に落とし込むには?~ 2つのSaaSをフルスクラッチで開発した経験から学んだこと~」

追求するのは圧倒的なスピード

当社は、Vertical(バーティカル)SaaSのコングロマリットを目指すテックカンパニーです。創業当初から美容医療などの自由診療向けオールインワンSaaSである「medicalforce」を提供しています。さらに、医療業界にとどまらず、警備業向けのオールインワンSaaSである「警備フォース」を2024年5月にリリースしました。

「これからの産業の成長プロセスを合理化する」という弊社のミッションを達成するためには、PMF(プロダクトマーケットフィット)が重要です。PMFを実現するには、顧客に既存のやり方をやめて新しいシステムに移行してもらう必要がありますが、既存のやり方を止めることで「できなくなること」も生じます。

そのため「できなくなること」を減らし「できるようになること」を増やすために、できるだけ早く実装し対応することが重要でした。

実際「medicalforce」のリリース時は、約20年前からマーケットのシェアを獲得する既存システムがあり、開発当初は「できなくなること」が非常に多い状態でした。PMFを実現するのは非常に大変でしたが、開発スピードを加速させて次々と機能実装することで問題を乗り越えていきました。

しかしサービスをローンチした直後は既存システムだけが競合であった業界でも、しばらくすると競合となる新規サービスが生まれてくるものです。顧客が求める機能やニーズは本質的には変わらないため機能は似たものに収斂されていき、「機能」だけでは差別化は困難になります。そのため、そのなかで競争優位性を確立するため徹底的に顧客に向き合い、実装とカイゼンを高速のサイクルでまわしていくことが大切だと考えています。

変更箇所と影響範囲を明確にし、カイゼンスピードを高める

仕様変更やカイゼンのスピードをあげるために必要な条件は、変更箇所が明確であること、変更した時の影響範囲が明確であることの2点です。

変更箇所が明確であるというのは、処理をまとめる各関数やオブジェクトをつくる設計書であるクラスの責務が明確で、メンテナンス性に優れた見通しのよいコードで書かれている状態を指します。

また、機能やモジュールの依存関係が明確で、依存の向きが限定的であれば、変更した時の影響範囲も明確にできます。

重要なのは高凝集・低結合


結論として、スピード感をあげるには高凝集・低結合が大切です。システムの機能やクラスの要素同士が密接に関連し、他の機能やクラスと独立していれば、仕様変更もカイゼンも安全かつ少ない変更量で実施できます。

しかし、高凝集・低結合を一般的な三層アーキテクチャで実現するのは難易度が高いものです。特に「medicalforce」は基幹システムに近い大きなバーティカルSaaSをつくっているため、プレゼンテーション層・ロジック層・データアクセス層のうち、ロジック層が混沌としてしまいやすいことが課題にありました。

高凝集・低結合を維持するのは難しい

そこで、カイゼンに向けてロジック層の整理に取り組みました。

これまで使っていた三層アーキテクチャは、レイヤーの責務自体や依存の向き・向き先は明確なので、一見すると高凝集・低結合に見えます。しかし、実際に仕様変更・カイゼンをするとさまざまな問題が発生します。

例えば、ロジックAとロジックBがあったとして、ロジックAでもロジックBの一部を使いたいというパターンはよくあります。しかし、ロジックBの一部をロジックAに置くと、本来ロジックAですべきではない処理が発生し凝縮度が下がってしまいます。逆にロジックBから持ってくる方法だと結合度が上がってしまいます。

凝縮度が下がると、変更漏れや複雑な処理が毎回発生することでバグを起こしやすくなります。反対に、結合度が上がると意図しない仕様が生まれ、バグが起きやすくなります。つまりどちらに寄せても問題が起きてしまうのです。

例1:在庫アラート機能で発生した問題

在庫アラート機能で発生した問題を例にします。

在庫アラート機能とは医薬品の在庫が10個以下になったらアラートを出す機能です。その機能を実現するために、2つの方法を考えました。1つは在庫減算ロジックに置く方法です。在庫減算ロジックは在庫の仕入れや使用時に呼び出すものでした。しかし、結果として結合度が上がり、在庫の増減が複数回発生する場合などアラートを出したくない処理のときに意図せずアラートが出るといったバグが出やすくなりました。

もう一つは、在庫ロジック・在庫使用ロジックに在庫のアラート通知ロジックを置く方法です。こちらでは凝縮度が下がり、いろいろなところで本来関係のない、通知周りのロジックを書く必要が発生しました。「何かよくないな」と感じつつも、比較的問題が少なかったこちらを採用しました。


例2:名寄せ機能で発生した問題

名寄せは、さらに大変でした。名寄せとは、同一人物のカルテが複数存在する際に、統合する作業を指します。電子カルテの処理では名寄せはわりと頻繁に発生するのですが、カルテ情報・会計情報・予約情報などのあらゆる情報をひとつにするという複雑な処理をしなければいけません。

患者ロジックに含まれている名寄せロジックをカルテロジックに置いたところ、名寄せロジックが巨大なため、本来は軽い処理でもコードの量が膨大になり、コードの可読性・品質が低下しました。

つまり、ロジックBの一部をロジックAにも置いた場合も、ロジックBから呼び出すことにした場合も、悪影響が出るという結論に達しました。

ロジック層をビジネスロジックとドメインロジックに分解

高凝集・低結合の実現に向けて、はじめのうちはロジックをできる限り細かく分解しました。高凝集を目指したのですが、結果として複数のロジックがいろいろな方向に依存して、どこに呼ばれているかもわからない状態に陥りました。

この状況を脱出するために試みたのが、変更箇所とその影響範囲の明確化です。

まずは、ロジック層をアプリケーションロジック(ビジネスロジック)とドメインロジックの2種類に分けました。アプリケーションロジックは、プロダクトごとに仕様が異なり、頻繁に変更されるものです。「medicalforce」と競合のプロダクトでは、全くロジックが異なる場合があります。逆にドメインロジックは、そもそも知識として蓄積されるもので、どんなアプリケーションも同じである点が特徴です。

例1:在庫アラート問題の解決

ロジック層の分解により、前述の在庫アラートの問題が解決しました。アラート通知のために在庫使用のアプリケーションロジックを呼び出しますが、それぞれの処理はしないように設定し、処理自体はドメインロジックの方に書きました。

エリアを限定して、アプリケーションロジックからアプリケーションロジックを呼び出さない、ドメインロジックからドメインロジックを呼び出さないというルールを守ることが大切です。

例2:名寄せ問題の解決

名寄せの件も同様の方法で解決できます。名寄せを含む患者のドメインロジックからそれぞれのアプリケーションロジックを呼び出すことでロジック層を整理でき、品質低下を防げます。

高凝集・低結合を守るオニオンアーキテクチャ

結論として、仕様変更・カイゼンのスピード感を上げるうえで一番重要なのは、やはり高凝集・低結合を守ることです。

そのためには、ロジック層をアプリケーションロジックとドメインロジックにわけて考え、データアクセス層やプレゼンテーション層にはロジックを全く持ち込まないというルールを徹底する必要があります。

しかし、メンバーみんなにルールを守ってもらうのは難しいため、当社ではオニオンアーキテクチャ(※)を採用しました。これにより、クラスの責務や依存関係が明確になり、依存関係も理解しやすくなるため、高凝集・低結合を保持しやすくなります。結果、テストが書きやすくなった・コードの再現利用性が高まり新規実装のスピードが上がった・バグが出にくくなったなどの成果をあげることができました。

(※)オニオンアーキテクチャ……丸型表記では、ドメイン層を中心に、アプリケーション層、その外殻をプレゼンテーション層、インフラ層、テスト層が覆う。「medicalforce」の開発ではドメインモデルを核に、ドメインサービス層、アプリケーションサービス層と殻を形成し、最外殻にユーザーインターフェース、テスト、インフラが存在する。全ての依存関係は円の中心にある層に対して向かい、中心の層から外側の層へは依存しない。


一緒にスクラム開発するメンバーを募集中

メディカルフォースでは、フルスタックエンジニアを積極的に採用しています。すぐに選考を受けるつもりがなくても大丈夫です。まずはカジュアル面談でエンジニアたちと話をしませんか?

If this story triggered your interest, why don't you come and visit us?
SaaS企業で自社サービス開発/フルスタックエンジニアを目指す方 大歓迎!
株式会社メディカルフォース's job postings

Weekly ranking

Show other rankings
Like 採用担当's Story
Let 採用担当's company know you're interested in their content