typescript × express × prisma × nuxt での ドメイン駆動設計開発
カラダノートでエンジニアをしている田中です。 弊社ではドメイン駆動設計を導入しており、実際に運用しているパッケージ構成についてまとめようと思います。
ちなみにですが、参考書籍の記述では、「ドメイン駆動設計にとってアーキテクチャは主役でない」とのことでした。ビジネスモデルに合わせたドメイン知識を主役に処理を作っていく中で、アーキテクチャはあくまでドメイン駆動設計の開発思想を実装に落とし込むための副産物なのだと解釈しています。
今回、説明する構成も弊社で扱う開発の中で模索した一例です。ドメイン駆動設計のパッケージ構成に無理やり合わせるばかりではなく、使っているフレームワークがあるならば、基本的にはフレームワークの構成、規則に従って開発をすることが個人的には安定した開発につながると思っています。
express × prisma × nuxt での開発構成
さっそくですが、パッケージ構成を下記に記載します。
├── app │ ├── api (backend 構成) │ │ ├── controller │ │ ├── index.ts │ │ └── router.ts │ ├── client (frontend 構成 [nuxt]) │ │ ├── assets │ │ ├── components │ │ ├── layouts │ │ ├── middleware │ │ ├── pages │ │ ├── plugins │ │ ├── static │ │ ├── stores │ │ └── utils │ ├── domain │ │ └── model │ ├── infrastructure │ │ └── prisma │ ├── nuxt.config.js
nuxt init
で作成されるフロントエンドのソースを client/
、
バックエンドのソースを api/
、
汎用的に使われるドメインモデルを domain/
、
他の層を支える技術基盤との連携処理を infrastructure/
で扱っています。
ドメイン駆動設計の説明で扱われる一般的なアーキテクチャとして下記が挙げられますが、特にレイヤードアーキテクチャに沿った構成にしています。
レイヤードアーキテクチャとはドメイン駆動設計の文脈の中でも、よく出てくるアーキテクチャで下記 4 層のレイヤーに分け、役割を分割したものです。
これに記載したディレクトリを当てはめていくと下記のようになります。
それぞれの構成について説明していきます。
client/
├── client (frontend 構成 [nuxt]) │ ├── assets │ ├── components │ ├── layouts │ ├── middleware │ ├── pages │ ├── plugins │ ├── static │ ├── stores │ └── utils
client/
配下は前述した通り、 nuxt の構成を基本としています。
基本的にはフレームワークの構成、規則に従って開発をすることが個人的には安定した開発につながると思っています。
アプリケーション層
├── api (backend 構成) │ ├── controller │ │ ├── [usecase].ts │ ├── index.ts │ └── router.ts
バックエンドのアプリケーションリソースを扱っています。
上記の構成で api/controller/
に持たせてアプリケーションのユースケース毎にファイルを作っておりその中で各処理を記述しています。
ドメイン層
├── domain │ └── model
ここでは、ドメイン駆動設計の名の通りドメイン知識を扱っています。 弊社ではここに設計に沿った値オブジェクトや使い回しのできる軽量なドメインモデルを実装しています。
下記記事を参考にしてください。
インフラストラクチャ層
├── infrastructure │ └── [module_name]
ここでは、他の層を支える技術基盤との連携処理を扱っています。 弊社で使っている例としては下記が挙げられます。
- ORMツールを利用した、データベースからのデータの取得や更新処理
- 外部ストレージへの画像保存処理
- メール送信処理
ここで定義した処理を api/controller/
で呼び出すことでアプリケーションの構築をしています。
まとめ
ドメイン駆動設計を進めていくに当たり、アーキテクチャ、パッケージ構成についてまとめてみました。主に新規開発で取り入れているため、まだまだ軽量な設計で運用しています。 これからプロダクトが継続して進めばシステム規模も大きくなり、処理も増えていくので、現在の構成を改善していくことも検討していこうと思います。
参考
スクラムはじめました
こんにちは、そろそろ夏ですね。モバイル開発部の長岡です。
モバイル開発部では2月からスクラム開発をはじめました。
6ヶ月間やってみて結果どうなったか?
気になるとおもいますので、まず結果からここに記します。
リリース回数が増えました
スクラム導入前後の6ヶ月間で比較したところ、導入後のリリース回数が導入前よりも約1.4倍!に増えました。
リリース回数が増えたということは、開発にスピード感が生まれ、ユーザーへ価値を届ける頻度が高くなったということです。
チーム全員が状況把握できるようになりました
プロジェクト管理ツールを導入したことで開発全体が見える化され、いまどんな開発が動いているのか?それぞれどういった状況なのか?優先度は?次は何をすればいいのか?が可視化され、プロダクトオーナーとエンジニア全員が状況把握でき、スムーズに開発を進められるようになりました。
(プロジェクト管理ツールには「Backlog」を使っています)
エンジニア間の会話が増えて技術的な情報を共有できるようになりました
デイリースクラムやレトロスペクティブで、エンジニア全員で集まって情報の共有や議論する機会が増え、内部のつくりがこうなっていた、こんないい解決方法があった!、こんなとこでハマった・・など、ナレッジを有効活用しやすくなりました。
(あとみんなで技術に関すること話すのってシンプルに楽しいですよね)
それまでどうだったか?
管理の部分
スクラム導入前はスプレッドシートで開発項目や優先度を管理していて、管理できている風ではあったのですが、優先度や進捗状況が把握しづらいという課題がありました。まずはその部分を解決したいと考え、比較的シンプルで直感的につかいやすい「Trello」をスクラム導入前の数ヶ月使ってみました。新しいツールの導入には学習コストも発生しますし、抵抗感も少なからずあるかなと考えたからです。
プロダクトオーナーも「Trello」を使っていくうちに優先度や進捗状況が見える化され慣れてくると、だんだんと「これじゃ物足りない」という声が聞こえるようになってきました。そこでより詳細にチケット管理できて見た目も堅苦しくない「Backlog」へ移行しスクラム導入に備える、というように段階的に準備を進めていくことでスムーズにスクラム開発の環境を整えることができました。
開発の効率化の部分
弊社では14種類のモバイルアプリを運用しているのですが、各担当のプロダクトオーナーから直接エンジニアに対して開発依頼していくようなスタイルで行っていました。プロダクトオーナー間で開発スケジュールや状況の共有はしていたものの、開発と開発の間にエンジニアが待ちの状態になることが多く、効率的な開発ができていませんでした。
この点について、1週間スプリントで毎週プランニング→開発のサイクルを繰り返していくことによって、待ちの状態になることなく開発にリズムが生まれてきたことがリリース回数というわかりやすい数字に表れてきたのではないかなと考えています。
どうやったか?
スクラムについては「SCRUM BOOT CAMP THE BOOK」という書籍を全員で読んで共通理解をつくってから、その内容ベースで進めていきました。ただ全くそのままというわけではなく、フルリモートで参画いただいているエンジニアもいて稼働日もバラバラだったこともあり、スクラムイベントを開催する曜日や時間帯については弊社の体制に合わせてアレンジしていきました。
あとは、とにかくやってみる!でした。スクラム経験のあるエンジニアもいましたので当時のことをヒアリングして取り入れたり、やっていきながら日々のデイリースクラムやレトロスペクティブでやりづらさや改善したいことをプロダクトオーナーとエンジニア双方にヒアリングして改善策を考え、それを即時適用させていく、ということを繰り返していくことで少しずつスムーズにスプリントを回せるようになっていきました。
今後どうするのか?
スクラムを導入したことによって、まだまだ改善の余地はあると感じていますが、まずは足元を固めることができたかなとポジティブな印象を受けています。
その部分は引き続き改善を図っていきながら、よりユーザーへ価値を届けるための開発&運用プロセスづくりにチャレンジしていきます。
モブプログラミング振り返り
カラダノートの嶋田です。事業開発のチームは3ヶ月ほどモブプログラミングを毎週行ってきました。
7月で下期が終わるのでここで振り返りをしておきたいと思います。
ルール
モブプログラミングのルールは下記のような形でした。
- スプリント内のタスクを一つピックアップして参加者で行う
- 1人10分制
- 1セッション、1時間
- 4人で開催し、最後の10分は振り返り
- ツールはVSCode Live Share
- リモートワークに対応するためオンラインで行う
やってよかったこと
まずはコロナ禍ということもあり日々のコミュニケーションが少なくなる中、大人数で時には笑いながら仕事をすすめることができたというのがまず大きなポイントだったかと思います。
また、新入社員もいたなかで、業務フローや開発ドキュメントでは補足しきれない細かな部分でのなぜここをこのように実装したのか等々、先輩エンジニアの経験を伝える機会としても最適な時間だったと思っています。
実際にコードをかくことについては途中からVSCode Live Shareを導入したことによりタイピスト交代後の受け渡しだだいぶスムーズになりました。
細かなところだとLinuxのコマンドやショートカットキーなどなかなか同僚と共有する機会がありませんが、間近にみることで今これってどうやったんですかとその場で聞いてその後取り入れることができるのも開発効率といったところでも貢献したのではないかと思っています。
反省点やいまいちだったこと
VSCode Live Shareはコードの共有ができるもののローカルのサーバー環境を不完全な状態でしか次のタイピストへ渡すことができず、タイピストとモブとモブ兼VSCodeのホスト(&画面共有)という少し役割が煩雑化してしまったこと。(LiveShareについて解決方法があるのかもしれませんが時間もなく解決にはいたりませんでした)
1時間だと少し時間が足らず最後の振り返りが駆け足になりがちなところと、テーマとなるタスクの最初の触りくらいしかふれられないことが多かった。
また経験豊富な人がしゃべりがちになって、該当タスクの先が見えている人と見えていない人の差が大きかった。
そのときのスプリントによってはモブプログラミングに最適なタスクがないケースもあった。
まとめ
メンバーの多くからは時間が足りないという発言が多かったです。来期以降開催するときには時間を検討しつつモブプログラミングを毎週やるというモブプログラミングが主となって行うのではなく、各タスクと紐付けて可否を検討してやっていくといったような改善が必要になってくるかと思います。
リソース効率よりフロー効率を重視する
はじめに
カラダノートの堀内です。 今回は作業効率や生産性について持論を展開します。
それは、 仕事の進め方には リソース効率 と フロー効率 があるよね、という話と フロー効率を重視したほうがいいよね という話です。
リソース効率とフロー効率
リソース効率とは
- リソース(キャパ)を最大限に利用しよう、という考え方です。
- 交通に例えると、道路に車を詰められるだけ詰めよう、という考え方です。
フロー効率とは
- 仕事の流れを最大限に良くしよう、という考え方です。
- 交通に例えると、車間距離をとって車の流れを良くしよう、という考え方です。
交通流の世界を覗く
理論的な背景は交通流の分野に通じるものがあります。
道路のリソース効率を上げる(道路に車を詰められるだけ詰める)と、ある一定までは交通流量(単位時間あたりに通過した車両数)が向上しますが、ある閾値を境に交通流量が低下していきます。イメージとしては、車がびっしり道路にうまってノロノロ走っている状態です。
図にすると以下のようになります。
この図は交通流の世界では基本図(Q-k図)と呼ばれています。 (学術的な数値の正確さはすみませんがググってください)。
この図から読み取れるのは、
- 「臨界密度を境に、車両密度に比例して交通流量が低下する」領域と、
- 「臨界密度を境に、車両密度に比例して交通流量が上昇する」領域がある、
ということです。
なぜ密度が高くなるほど交通流量が低下するか。
たとえば、ある一台がブレーキを踏むと、その後ろのすべての車に影響を及ぼします。
すると、全体の車の流れが悪くなり、その結果、交通流量が低下するイメージです。
ちなみに、海外の高速道路では車の密度を制御するために、入り口に one vehicle per green という標識や信号があります。 フロー効率ですね。
何が言いたいか
縦軸(交通流量)に注目すると、密度が低いところと高いところで、交通流量が同じところがあります。
このとき、密度が低い方が、目的地への到着時刻の精度が上がります。 なぜなら、一台がブレーキを踏んでも、その影響を受けにくいからです。
これがフロー効率の恩恵です。
要するに
仕事の世界に話を戻します。
車の流れ = 捌いた仕事量、車の密度 = 対応中の仕事量 だとしたら、
フロー効率を重視すれば、仕事の期限の精度があがる
ということになります。
あるいは、対応中の仕事量を閾値より増やすと、捌いた仕事量が低下する、ということです。
「一台がブレーキを踏むと、それ以降のすべての車に影響を及ぼし、車の流れが悪くなる」に例えるなら、ある工程や誰かの作業が遅れたとき、
それが全体に及ぼす影響が大きく、チーム全体として捌いた仕事量が低下する
ということです。
もしそういう状態に陥っているのであれば対応中の仕事量を減らせばよいのです。 これは単に「仕事の量を減らす」という意味ではなくて、「仕掛りの仕事を減らす」、ということです。
WEBサーバで言えば、リソース効率を重視するのが Apache で、フロー効率を重視するのが Nginx だと言うこともできます。
私達は「対応中の仕事量」ではなく「捌いた仕事量」を重視しています。 アジャイルやモブプログラミングを採用しているのはそのためです。 そちらについては他の記事も読んでいただければと思います。
ドメイン駆動設計を学んでいろいろと腑に落ちた話
こんにちは。事業開発チームの嶋田と申します。
ドメイン駆動設計とは
まずはドメイン駆動設計(以下 DDD)の軽くおさらいです。DDDはソフトウェアで解決する領域をエンジニアや非エンジニアが共通の言語を持ち、共通の言語からそのままプログラムのコードへ反映することで、ビジネス価値や生産性の向上を一体となって目指す設計手法です。
弊社に最適解だった
基本的なエンジニアの業務フローとして営業・マーケティング職等の方から上がってくる課題等をエンジニアがコミュニケーションを取りながら実現していくというのがよくある形であったのですが、エンジニアサイドからの視点のみで設計しても、非エンジニアの業務フローが複雑化していてるケースに対応できていない課題がありました。例えばAという機能をリリースしたが、時間の経過とともに機能が不足することになりその不足分を人的リソースでカバーしていたり、A機能についてエンジニアに相談して改修して部分的には効率化ができたけど非エンジニアの全体の業務が見えておらずあとから別件で改修するときにボトルネックになっていた等、効率が少しずつ落ちていきました。
DDDはこの問題に対する一つの解かと思います。
DDD用語を駆使して上記の問題点を言うと、ドメインエキスパートが不在なため最適なコアドメインの選出と最適なドメインモデルを作り続けることができていないということになるかと思います。
最適なコアドメイン・ドメインモデルを作り続けるとは
会社の戦略や方針についてエンジニアチームというのは特にビジネスチームとエンジニアチームが明確に別れているのであれば、それについての対応が遅れがちになるかと思います。
ですが、適切なDDDが設定されているのであれば、会社の方針にアップデートがあった場合は即座に注力すべきことや、これまで作ってきたものの取捨選択の議論がエンジニアを含んで議論が可能になるはずです。
すなわちより無駄な開発というのが少なくなります。
特にベンチャー企業だと最適なコアドメイン・ドメインモデルを作り続けることが困難
- 人が入れ替わる
入社退社や配置換えなどはよくあることです。ドキュメントの共有や引き継ぎ等はどこの会社でも行われているかと思いますが、どういう意図でそういう事になったのかといった当時の背景等は徐々に薄まります。
- 集中する領域がよく変わる
会社の方針によりビジネスモデルが変わったり、収益となるポイントが徐々にずれていったりしていきます。
- どれがあたるかわからない
作っては捨てを繰り返すので、スモールスタートというのは普通かと思いますが、どこまでを想定して設計するかの取捨選択が難しい。
とはいえDDDがすべてを解決する銀の弾丸ではないです
会社によってそれまでに様々な事情があり、人的リソースの問題もあります。特に非エンジニアを巻き込みつつやっていくには高いハードルがあります。
また、正解なモデルというのは存在しないので、常に改善していく必要があります。
個人的なところとしては、MVCフレームワークへDDDを落とし込むのにどうしても違和感が発生してしまうというのはあります。このあたりは折り合いをつけていくしかないのかなと感じています。
まとめ
数年前に現在の担当している領域に途中から参加したのですがしばらく開発してみて感じていたのが、ビジネスチームと一体となっていやっているはずだけど拭えない非効率感でした。
DDDは自分の感じていた非効率感を一つの軸をつくりそれをベースに議論できる拠り所になると感じています。
エンジニア組織が大きくなるにつれて参考にしてきた書籍
事業開発チームの嶋田です。前回のブログでアジャイルな開発手法を取り入れて約一年と最初に書きましたが、それはエンジニアが組織化するようになったのとほぼイコールになります。
今回はそこを振り返るとともに都度参考にしていた書籍を紹介していきたいと思います。
スクラムの導入
スクラムの導入に当たりWebエンジニア全員でこの書籍を読んで導入をすすめていきました。
平易で読みやすくスクラムの概要が頭に入った形で進めたことや、スクラム経験者のサポートもありスムーズに始めることができたかと思います。
日々スクラムを維持していく上で課題は出ていますが、前回のブログでも書いたように振り返りも機能したりしているので、1年前と比べるとだいぶ洗練されたチームになってきたのかなと感じています。
採用について
作るもの・作る人・作り方から学ぶ 採用・人事担当者のためのITエンジニアリングの基本がわかる本
エンジニア組織として大きくしていく関係で採用にも力を入れています。採用に力を入れていくにあたって、個人的にはまずエンジニアの職種ってなにがあるのかとか自分が採用するにあたって足りない知識があるのだろうかということを知りたくこちらの本を参考にしました。
エンジニアをマネージメントするにあたって
エンジニアのためのマネジメントキャリアパス ―テックリードからCTOまでマネジメントスキル向上ガイド
私自身はマネージメントをする時間の割合も多くなりました。組織人として求められる役割のひとつに視座を自分のポジションよりひとつ上に持つみたいなことをよく言われるかと思います。
そういった手がかりになる一つかこれらの書籍にあるかと思います。読んだのは半年以上前ですがそろそろまた読み返しても新たな発見がありそうです。
ファシリテーターとして
ファシリテーターをする機会も多くなり、自分がうまくファシリテーションできないこともありました。
そのときに紹介された書籍です。この本が恐ろしいのはたぶん会議に興味がなくても読み進められるくらいストーリーが面白いです。
こちらは入門書ですし、エンジニアリングとは対極にありそうなスキルなファシリテーションは組織の生産性に直結しそうな課題でもあるので引き続き書籍を読んでいきたいと思っています。
最後にビジネス書を読むのにおすすめな方法
ここにあげられた多くの書籍は紹介されて読んでみたものなのですが、タイトルを検索した時に気づいたんです。結構Kindle Unlimitedにあるじゃないか!と。
漫画読みである自分は何回かKindle Unlimitedを利用したりしたんですが、漫画に関してはいいものが少なく、Kindle Unlimitedはもっぱら雑誌読みに利用することが多かったんですが、ビジネス書においては良書がたくさんあるんだなと気付かされました。
また、この本の2章だけしか役に立たなかったなと感じる書籍もあるかと思いますが、Kindle Unlimitedであればそういった買って失敗した感がなくなるのもよいです。
スプリントレトロスペクティブを実施するようになって目に見えて変わったところ2選
事業開発チームの嶋田です。弊社はアジャイルな開発手法を取り入れてまもなく一年になろうとしています。
私自身はアジャイル導入前の状態もよく知っているため、導入前後で大きく変わったところも見てきました。
アジャイルは開発手法として一般的なスクラムを弊社も行っていますが、スクラムの活動の中でもスプリントレトロスペクティブ(長いので以下振り返り)をするようになったことが、エンジニアの意識も大きく変わったところじゃないかと感じています。
今回はその中でチームとして大きく変わったというところを2点上げていきたいと思います。
不具合発見の増加
不具合検知の仕組みがまだまだなところがありますが、最近整備できたことのひとつにHTTPステータスコードの監視があります。
これまでのリリース後の不具合発見の多くは非エンジニアチームの報告が多かったのですが、これによりエンジニア発の不具合報告も数として多くなってきました。
ステータスコードの監視は仕組みとしては少し前からあったのですが、毎日みんなで確認することを振り返りですることが決まり、これにより全員の正常動作に関する意識が高まりました。
少し違和感がある状態があると調査を行い結果的にその周辺でバグを発見したりというケースも出てきて、良い循環が生まれています。
曖昧さの排除
今回ブログを書くにあたって振り返りのログを一通り見たんですが、振り返りがうまく働くとそのチームの問題点が浮き彫りになるのかなとログをみて感じ、自分たちの問題点は曖昧な部分が多かったというのが気づきでした。
スクラムの導入前まではそれぞれのエンジニアが自分たちの力量で細かなところをカバーして運用していくという割合がおそらく他社比でもかなり多かったかと思います。
例えば、ビジネスサイドからのタスクの依頼方法はテンプレートに沿って作ってもらいこれを運用していく形になっていました。
これまでだとこのテンプレートの方法だととあるケースでは分かりづらいなとかあったとしても、報告の場があまりなかったこともあり、その時にエンジニアが追加でヒアリングするなどして対応するみたいなエンジニアがその場その場で臨機応変に対応するといったことがこのケースに限らず多発していました。
しかし振り返りが習慣化したことで、これはあとで振り返りで議題として上げようといった流れができて、曖昧なところがどんどんと解消されていっています。
これによりあとからエンジニアが参加してもキャッチアップの時間が短くなり、より組織としてスケールしやすい体制になりつつあるかと思います。
以上、1年近くスプリントレトロスペクティブを運用しての気づきでした。引き続き組織としてブラッシュアップすべく改善を繰り返していきたいと思います。