じゃんけんアドベントカレンダー の最終日です。
時が経つのは早いもので、じゃんけんアドベントカレンダーも最終日となりました。
総括として
- テーマ・内容について
- ふりかえり
- 今後の構想
といったものを書いていきます。
テーマ・内容について
このアドベントカレンダーでは、いわゆるアプリケーションアーキテクチャの話題を中心にしつつ、一部 CI / CD といった環境面の整備なども実施してきました。
そのテーマや内容について考えていたことを書いていきます。
じゃんけんアドベントカレンダーの背景
実はこのアドベントカレンダーは、以前自分が主催したブートキャンプがもとになっています。
多くの人が一度は書いたことがあるじゃんけんという例題で、リーダブルコード的な改善から、アプリケーション構成まで整理していくことで、参加した方にはなかなか好評でした。
もともと数分の一くらいの内容で実施したブートキャンプのコンテンツに、再整理して欠けている要素を足したのがこのアドベントカレンダーになります。
そんなブートキャンプの経験と、そのうち一人アドベントカレンダーをやってみたいという気持ちがあったことから、「じゃんけんアドベントカレンダー」というものを思い付きました。
そのことを知り合いに話したら「めちゃくちゃ面白いと思う!」と後押しされ、始めるに至りました。
ちなみに、じゃんけんという題材自体にはあまりこだわりはないのですが、CLI アプリケーションとして小さく始められつつ、Web アプリケーションとしても成立するもの、ということでこの題材になっています。
対象読者
このアドベントカレンダーは、コーディングにイマイチ自信が持てなかった頃の自分くらいの方が対象読者になっています。
- アプリケーションを実装しようとして、どこに何を書けばいいのか自信が持てなかったり
- オブジェクト指向を実際の開発にどう生かすかが分からなかったり
そんな悩みがあった頃の自分に対し、考え方の指針やヒントになるように書いています。
仕事でプログラミングに関わってある程度経った方は、実装の中で同じような悩みに遭遇したりすると思います。
そういった方にはこのアドベントカレンダーは面白いかもしれません。
逆に、まだ実務経験があまりないといった方は、もう少し時間を置いてから見ていただいた方がいいかもしれません。
リーダブルコード的なプラクティスをある程度身に付けて、でもそれだけでは解決できない悩みに遭遇したときに見てみると、ヒントになる部分もあると思います。
これは DDD ?
このアドベントカレンダーを読まれた方の中には、これは DDD の話だと思われる方もいらっしゃるかもしれません。
たしかに DDD のプラクティスに触れている点が少なくありませんし、かなり参考にしてはいるのですが、私はこれは DDD ではないと思います。
そのため、記事の中で DDD という単語を使った箇所でも、「DDD でいうこれと対応しています」くらいのニュアンスで書いています。
理由としては、DDD は「ユビキタス言語を使ってドメインエキスパートと話して、ドメイン知識をそのままソフトウェアで表現する」などといった思想や開発の進め方が本質であり、実装上のプラクティスは補助的なものにすぎないと考えているからです。
このアドベントカレンダーの内容は、DDD の中でもアプリケーションの実装に関するプラクティスを取り入れただけで、いわゆる「軽量 DDD」と呼ばれるものです。
軽量 DDD はアンチパターンだと言われることもあります。
これは個人の経験からの意見に過ぎないのですが、軽量 DDD がうまくいかないのは、そもそものプラクティスがよく理解されていないことが原因の場合が多いと思います。
プラクティスの意味やメリット・デメリットなどをしっかり理解した上であれば、軽量 DDD であっても有効な場面は多いと思います。
これはクリーンアーキテクチャ ?
DDD と並んで、これはクリーンアーキテクチャの話だと思われる方もいらっしゃるかもしれません。
クリーンアーキテクチャは大いに参考にしていますが、これがクリーンアーキテクチャなのか、と聞かれると、なんとも答えにくいです。
そもそもクリーンアーキテクチャとは何か、というのも、いくつかの派閥があると思います。
「具体的なアプリケーションの構成のことである」と言う人もいれば、「関連するいくつかのプラクティスを満たした構成のことである」と言う人もいます。
これについて、自分は結構どっちつかずの立場です。
クリーンアーキテクチャの話でよく引用される同心円の図には「The Clean Architecture」と書かれており、「The」には「まさに」、「唯一の」、「これこそが」といった意味があるため、その図の通りなのがクリーンアーキテクチャなのかもしれません。
一方で、重要なのは、学んだ手法をそのまま使うことではなく、なぜそうするのか・どんなメリットがあるのか (逆にどんなデメリットがあるのか) を踏まえて適切に使うこと、だと思います。
用語は共通認識を作る上で重要ですが、用語以上に、なぜそうするのかが重要だと思います。
軽量 DDD にも近いところがありますが、クリーンアーキテクチャも誤った理解で取り組むとただ複雑になっただけでデメリットしかない構成になってしまう可能性があります。
慣れればどんどん使っても良いと思いますが、理解が深まるまでは少しずつ取り入れた方が失敗しにくいのではないかと思います。
ビジネスロジックやドメインモデルを中心に考えるべきではないか
このアドベントカレンダーでは、まずは 1 クラスに全てのコードが書かれている状態から始まり、徐々に表示用の関心事やデータアクセスを分離してビジネスロジックを抽出していきました。
このアプローチに対して、そもそもビジネスロジックやドメインモデルが中心にあり、それに対して UI や DB を付け加えるべきだ、という意見を持つ方もいらっしゃると思います。
以前書いた記事「「ビジネスロジック」とは何か、どう実装するのか」でも、そういった批判を見かけました。
この意見については、私もその通りだと思います。
ビジネスロジックやドメインモデルを中心に考えるスキルがあるのであれば、そこに注目して整理して、UI や DB といった詳細については付属的なものとして扱うべきだと思います。
しかし、それは「ビジネスロジック」という言葉の意味をすでに理解している方にだけできるアプローチで、ビジネスロジックという概念がまだ分からないという方には難しいです。
「ビジネスロジック」とは何かを理解するためのきっかけとして、UI や DB といった技術詳細ではない部分、くらいの理解から始めて一度実装してみると、「ビジネスロジック」とは何かが分かってきやすいのではないかと思います。
その次のステップとして、ビジネスロジックを中心に考えられるようになっていくと思います。
また、状況によっては今回のじゃんけんアプリケーションの初期の状態のように、プレゼンテーション・ビジネスロジック・データアクセスが混在してしまっており、そこから改善するアプローチで進めざるを得ない場面もあると思います。
そういった際には、ビジネスロジックを中心としたトップダウン的なアプローチだけでなく、今回のようなボトムアップ的なアプローチも有効なのではないかと思います。
じゃんけんアプリケーションを作るときにここまでやるべきか
じゃんけん CLI のような簡単なアプリケーションであれば、このアドベントカレンダーで取り組んだ整理はほとんど不要です。
初日の状態でも十分だと思います。
ですが、小さくないアプリケーションであれば、このアドベントカレンダーで取り組んだプラクティスはすぐに役立つと思います。
これまで取り組んできた整理は、非常に小さなサービスやプロトタイプ、ちょっとしたツール程度であれば不要ですが、多くのアプリケーションでは有効なプラクティスだと思います。
これは完全に個人の想像ですが、小さくないにも関わらずこういったプラクティスが役に立たないアプリケーションは、ノーコードでの開発が発展することでどんどん減っていくのではないかとも思っています。
ただし、だからといって、ある程度以上の規模なら必ずこれらのプラクティスが有効という訳でもないと思います。
一番ネックになるのは学習コストです。
特にスタートアップや新規事業開発などで低コストかつスピーディに開発を進めたい場合、学習コストを支払えない場合が少なくありません。
学習済みの状態であればアプリケーションの整理や自動テストといったプラクティスはすぐに効果がコストを上回りますが、学習コストが高い場合は効果がコストを上回るのは当面先になります。
きれいな設計にこだわることでビジネスチャンスを逃しては元も子もないことと、繰り返しになりますが生兵法が怪我の元になりやすいプラクティスであることから、気軽に大きく採用しないことをオススメします。
とはいえ、いずれ導入するためにも学習することは大事だと思いますし、今回やってきたプラクティスは少しずつでも導入できるものです。
しっくりきた部分から少しずつ取り入れていくと良いのではないでしょうか。
CI / CD をなぜ入れたか
テーマ・内容についての最後に、なぜ CI / CD に関する記事を入れたかについて書きます。1
アプリケーションアーキテクチャの話だけだと話題が足りなくなりそうだから、という理由もありますが、自分が CI / CD にかなり思い入れがあるというのが一番の理由です。
もともと仕事で CI / CD まわりを整備することが多いので意見が偏っているとは思いますが、CI / CD の整備具合は、クオリティ・コスト・デリバリーの全てにプラスに働きやすいです。
CI で品質が向上するのはもちろんのこと、ビルドエラーに早期に気付けることや、デプロイ後の動作確認を早期にできることで、修正コストの低下や、完成までのデリバリーの高速化に寄与します。
手作業でのビルド・デプロイと比べて障害発生率も非常に低くなりますし、本番稼働させるアプリケーションであれば、まず確実に取り組んだ方が良いと思っています。
そんな CI / CD ですが、本来プロジェクト初期に構築すべきにも関わらず、後回しにされてしまうことが多いです。
短期的に時間がないと後回しにされがちですが、ほんの少し時間を使うだけで、すぐにそのコストを効果が上回ります。
そのことを訴えるためにも、このアドベントカレンダーでは、まず自動テストを書いて CI を組み、Web アプリケーションを実装する時点でもまず自動デプロイを組むところから始める、という方針をとりました。
もちろん全ての作業を必ずしも自動化する必要はありませんが、その取り組みへのハードルが低い環境であることは、開発の成功に繋がりやすい環境であることと近いと思います。
今回採用した GitHub Actions は非常に手軽に使い始められますし、まだそういった取り組みに未挑戦の方は是非試してみてください。
ふりかえり
では、アドベントカレンダーのテーマや内容についてはここまでとして、やってみてのふりかえりに移ります。
良かったこと
まず良かったのは、最後まで完走できたことです。
投稿がその日のギリギリになることもありましたが、翌日以降に遅れることなく最後まで走り抜けられました。
これは自分でも頑張ったなと思います。
そして何より、このアドベントカレンダーを面白いと思ってくれる方がいたことです。
最初はとある知り合いに面白そうと言われて始めた企画ですが、他の知り合いにも話すと面白がってくれたり、中には社内でディスカッションに使ってくれる人もいました。
直接の知り合い以外に、どこかでこのアドベントカレンダーを見つけて見てくれている方がいたことも、非常にありがたかったです。書き進める中で大きな励みになりました。
個人としては、やはり記事を書くことが習慣になったのが良かったです。
最初の頃は記事を毎日書き続けていると頭がおかしくなりそうでしたが、慣れると「とりあえず記事書くか」と思うようになりました。
この習慣を今後にも生かしたいところです。
また、自分が持っているアプリケーション開発のプラクティスをある程度まとめることができたのも良かったです。
反省点
反省点としては、プログラミング初心者向けではないため、対象読者がかなり限定されてしまったことが挙げられます。
よくあることではありますが、初心者向けの記事やビジネスほど対象者が多いため、見られる数・売れる数も多くなりやすいです。
ちょうどハマる人には面白い内容にできたのではないかと思いますが、始める前に想像していたよりも全然見られていなかったため、心が折れそうになったりもしました。
自分のモチベーションのためにも、もっと見てもらうための工夫を入れていくべきだったと思います。
分かったこと
この企画を通して分かったこととしてまず挙げられるのは、一人アドベントカレンダーを完走するのは思った以上にすごいことだった、ということです。
例年やっている人を見かけて、面白そうだし自分もやってみたい、と気軽に始めたのですが、想像していたよりもはるかに大変でした。
ほとんど書き溜めしていなかったのも原因なのですが、これは結構頑張ったと自分で言ってもいいと思います。
皆さんの周りに一人アドベントカレンダーを達成した人がいたら、是非ほめてあげてください。
今後の構想
今後の構想としては、じゃんけんアプリケーションを盛大に作る、というコンテンツが整理できたので、実装するハンズオンなども企画したいなと思ったりしています。
上にも書いたようにもともとブートキャンプ企画として実施した内容を記事に落としたものなのですが、そういったやり方で興味のある方を探したいなと思っています。
また、今回の企画を考える中で、実は以下のような要素も盛り込むか考えていたりしました。
- フロントエンドの実装
- インフラ (コンテナ・サーバレスなど) の構築
- マイクロサービスやモジュラモノリスの実装
- データ基盤系の話
記事数的にも、自分の時間的な余裕的にも盛り込むことができませんでしたが、今後もこっそり JankenEnterpriseEdition を改善していこうと構想していたりします。
そういった際はまた記事も書いたりすると思うので、見ていただけると嬉しいです。
追走される方へ
実はこの記事の内容を知人数名が実装しながら追走してくれています。
ビルドツールの使い方や細々した修正など、本題ではない箇所の説明を記事の中では省略してきました。
そういった省略と、たまたまそのメンバーが Java のサーバサイド開発にあまり慣れていないことで、追走には結構苦戦しているそうです。
もしこの内容を実装しながら追走するといった方がいらっしゃる場合は、Java である必要は全然ないので、慣れた言語で取り組んでいただければと思います。
個人的には、今回実施したような設計は静的型付け言語の方が相性が良いと思うので、Java、Kotlin、Scala、C#、Go、TypeScript などをオススメします。
参考になる書籍やウェブサイトも Java や C# での実装例が多いです。
Python や Ruby などの言語で取り組む場合は、型ヒント (型チェック) などを豊富に使っていただくと良いかもしれません。
もしも追走で困っている方がいらっしゃいましたら、少なくともしばらくの間はできるだけサポートさせていただきます。
各記事のコメントや Twitter (@oshima_123) などでご連絡ください。
内容の不備について
たくさん記事を書いてきましたが、自分もまだまだ勉強中のことだらけです。
中には間違った記載であったり、不適切な説明もあると思います。
数年後の自分がありえないと思うことを書いている可能性もあります。
記事の内容への指摘や誤字といった小さな点でも、お気付きの方は是非コメントや編集リクエスト、Twitter (@oshima_123) などでの連絡をいただければと思います。
お礼
最後に、このアドベントカレンダーを進める中で関わってくださった方々にお礼を申し上げて締めさせていただこうと思います。
- 記事を見てくださった方
- アドベントカレンダーを購読してくださった方
- LGTM してくださった方 (特に毎日のように LGTM してくださった方)
- コメントや編集リクエストをくださった方
- Twitter 等でシェアしたり知人に紹介してくださった方
ありがとうございました。
正直言って 25 日間毎日記事を投稿するのはかなり大変だったので、見てくださる方がいなければ続けられるものではなかったと思います。
改めて、LGTM や Twitter へのシェアといったものは一番気軽にできるコントリビューションであり、自分も良いと思ったものはどんどん LGTM したり Twitter にシェアしたりしていこうと思いました。
本当にありがとうございました。
-
ここではよくある表現として自動デプロイのことを CD と表現していますが、CD は本来自動デプロイのことではありません ↩