From Tokyo, Japan. Web-Developer. Write some codes by Go/Scala And thanks everything around my self.

Goアプリケーションの構成についての所感 / Thinking about constitutions of Go application

Goアプリケーションの構成についての所感 / Thinking about constitutions of Go application

前提

この記事は以下の記事を読んだ上で、Goでアプリケーションを開発する際のアーキテクチャ等選定における僕自身の所感を記述しています。

Goのpackage構成と開発のベタープラクティス

この記事で何かを否定するつもりはないです。別な答えも示しません。難しい記事が増えると言語に対しても構えちゃう人が増えたりするし、それもあれなんであれしました。あれです。あれ。

基本的には、当然ですがみなさんが信じる道を歩けば良いので、これを読んで「うーん」となる必要は無いでしょうし、以降書くような内容を強いる意図も全くありません。現場レベルでうまくいくやり方なら問題ないので、そこに関しては皆さん自信を持ってやっていっていただければ良いのではなかろうかと思います。

要するに

※ 個人の感想

です。ポエムの範疇なのでサンプルコードを書いたりもしません。ありがとうございます。

TL;DR

  • GoはDDDに向いていないと思っている
  • DDDをきちんとやりたいならオブジェクト指向言語でやるべきだと思っている
  • 特定の言語をやりたいのか、特定の開発スキームをやりたいのか、という点は選定の段階でとても重要だが、スキームと言語の相性というのも考えた方がいいんだろうなと思っている

Goにおけるアーキテクチャ選定について

Go言語で「Java的な」ドメイン駆動を模したアプリケーションを構築するのは非常に割に合わないと僕は考えています。

そもそもドメイン駆動開発はオブジェクト指向プログラミングを前提とした手法だと「僕は」捉えているので、「あくまでもオブジェクト指向ではない」Go言語でそれをやろうとしてもどこまでやっても完全なものは完成せず、細分化されるパッケージングやJavaのそれを誤用したインタフェース定義によって、

  • 設計の将来的な破綻
  • 開発チームへの参加におけるランディングコストの上昇

といった問題を招き、ひいては管理コストの肥大化や開発スピードの低下を招く大きな要因となってしまうように思っている部分があります。

一方でどのようなスキームを取ったとしても恒常的な改善意識を持たない限りはどのようなアプリケーションであっても上記の問題は容易に引き起こすので、現場レベルで統制が取れていてその場の開発としてはうまくいくのであれば、あとは満足感の問題でしか無いからみんな好きにやればいいとも思っているので、それをしてはいけない、というコンテキストでは無いということだけは何度も言っておきます。

ドメイン駆動に近づけるとしても、レイヤードアーキテクチャを模した構造を作るところまでで止めておくのが、相互理解を前提とした可読性の向上を目的とした場合の限界かなというくらいの感覚でいます。

きれいに書きたいな、と思ってアーキテクチャを寄せに行くんですが、大体最終的には「泥臭くやったほうがいいな」という結論に落ち着くのがGo言語かなという所感です。単純に、納得できる形の実装を今のところ見たことがないというのが原因かもしれません。

個人的には、きれいにドメイン駆動をやりたいならJVM系の言語で書いたほうがきれいに書けると思いますし、オブジェクト指向言語でやるべきだと思います。Scala書くのも楽しいのでScala書いたら良いんですよ。Scalaいいぞ。

Go言語におけるDIについて

同様にGoでDIするのもあまり筋が良くないかなとは思っていて、どこまでをDIと呼ぶかという話でもあるのかもしれませんが、ぼく個人としてちょうどいいなと思っているのは

  • Intefaceを定義して
  • Interfaceの受け渡しあるいは埋め込みによってモジュール間の結合度を下げる

くらいまでです。実体をFactoryMethodパターンを実装したようなStructにアサインさせるところまではやります。

完全にDI コンテナまでやってしまったりするのは何か違うな、という感じを持ったので2年位前に会社で相談の上GoでのDIは基本的に上記くらいまでしかやらないことにしました。

GoとJavaでのInterfaceのニュアンスの違い

ここから更にポエムみが増しますが、

最近社内でもGoへの移行が少しずつ動き出していて、色々なコードをレビューしているのですが、一番気になるのがGoにおけるInterfaceの扱いをJavaのそれと同一もしくは近い形で認識している命名であったり、ふるまいの定義であったりするように思います。

個人的にはGoとJavaではInterfaceに対するニュアンスがそのものの言葉、あるいは説明の言葉としては似通っていても、本質としては異なっていると考えていて、それはJavaが実装宣言(implements)が必要なのに対しGoはIntefaceに定義された関数を備えてさえ入ればそのInterfaceと呼ぶことができるようになるという言語仕様の違いからもそれを感じていて、EffectiveGoでは命名においても、Javaでは「〜able」だったのがGoでは「〜er」となっていることからもそれがわかると思います。ニュアンスレベルでは、「権能」のような形としてのJavaでのInterfaceに対して、Goでは「行為者」あるいは「動作」を主観とした捉え方になっているように思います。

終わりに

飽きたし誰も読んでないと思うのでこのへんで終わりますが、こういう話が活発にもっとなって、良い感じの構成が見つかれば良いなーと思っています。最近はみんな結構DDDとか取り入れた構成をやりたい事が多いように見えたりもしますが、そういった記事が増えることで不安に思う人や入り口で難しそうだなとかハードルを高く感じる人もいそうだな、と思ったので書きました。

みんなでGo書いていこうな

Flutter用のWidgetパッケージを自作して公開してみた / Created and published a widget package for flutter

Flutter用のWidgetパッケージを自作して公開してみた / Created and published a widget package for flutter

仕事でScalaを書いている / I write scala codes at work

仕事でScalaを書いている / I write scala codes at work