エンジニア的なネタを毎週書くブログ

東京でWebサービスの開発をしています 【英語版やってみました】http://taichiw-e.hatenablog.com/

Gunma.web #30 「DDD」に参加してきました! #gunmaweb

Gunma.webさんの勉強会に参加してきました。
テーマはDDDでした。

何故参加したか → 「DDD」が良い「切り方」を教えてくれるんじゃないかと思って…

私は、正しく『切』られたコードは読みやすいコードであり、結果、修正しやすいコードである と考えています。
では、「正しく切る」とは? というのが問題なのですが、DDD=ドメイン駆動設計が、この問いに対する「先行研究」であり、ヒントを持っているのでは…と最近感じています。

このように感じるに至った大きなきっかけが、昨年、『現場で役立つシステム設計の原則』に出会ったことでした。
taichiw.hatenablog.com
今回、著者の増田さんがGunma.webさんで話されるということを聞きまして… 「高崎だったら時間かからないし、小旅行気分で行ってこよう!」と、お邪魔させてもらった次第です。

なお、「ポジペを用意してください」とあったので、自己紹介も兼ねて、何故自分がDDDに興味を持っているのかを振り返ってみました。

  • とんでもないク○コードの影響調査に怯えた日々
  • きれいに構造化されたコードの読みやすさに感動したこと
  • レイヤ構造のお手本としてエリック・エヴァンスがDDD本で低減しているレイヤ化アーキテクチャを参照したこと
  • その難解なDDD本をわかりやすく解説している本に出会ったこと

が自分の中ではきっかけになっていたようです。

何を得られたか

増田さんの基調講演より → 「やらなきゃ!」がたくさん

今日でDDDの真髄を見極めた! …となるわけはなく(当然)、「できてない!やらなくちゃ!」がたくさん見つかった場でした。

ドメインが理解できているか?は「言葉がしっくり来るか」で確認できる → やばい、チーム内でしっくりしていない言葉がある!

小さな子供が言葉を覚えていく過程のように、
 試しに単語を使って話してみる → なんか違う → また試してみる → 話が通じた!
というトライアンドエラーを繰り返すことで、ドメインの知識がついていく、という話がありました。

この話を聞いて、「ああ、開発チーム内でもうまく統一できてなかった用語がいくつかあったな… なんとかしないとな…」ということを思い出しました。

DDD本読まなきゃ…!

エヴァンスさんの本は

  • 難しい
    • 訳のせいなのか原文が複雑なのか、表現が難解でなかなか頭に入ってこない
    • 実際の設計の問題だと思って、自分の手で図でも書きながら出ないと、なかなか何を言っているのかわからない
  • 長い
    • サラッと読める分量ではない

…と、なかなか辛いのですが、やはり、DDDの根本の考え方を理解する上で大事な、そして良いことが書いてある本なんだと思います。 …多分。
今回の発表では、増田さんの私見も交えながら、各部・章の要点をご説明頂きました。
その話を聞きながら、特に3章、6章、7章あたりを読まないとやべーな… と 危機感を抱いたようで… 勉強会後に読んでみました。

結果
3章 …からリンクされていた14章
→ 今週、自分が話題にしていたような、「検索と買い物かごに乗ってる商品って同じなの?別物なの?」のヒントが書いてあった!
 (しかも1-2ヶ月前にも同じ理由で読んでいる)

6章
→ 昨日自分が話題にしていた、「どこまでが(DBにアクセスする)リポジトリの責務なんだろう…」 のヒントが書いてあった!

…やっぱり、「ちゃんと読む」と良いことたくさん書いてあるなぁ、この本。ちゃんと読むのが大変なんですが…。

質問ができた!

今日も話しに出たのですが、
開発者は開発を通して徐々にドメインナレッジがついてくるので、クラスやメソッドの切り方、設計方針を見直したくなる、見直すべき時が開発中に来る。
という話。
これに対し、以前から一つの疑問を持っていました。

「メソッドの入出力をテストするようなユニットテストを書いていると、このような、クラス設計を見直すようなリファクタリングの邪魔になるのでは?」

こちらの質問をさせてもらった所、
- 静的型付け言語の場合、メソッドごとのテストは不要だと思っている
- ユニットテストの「ユニット」≠メソッド
- 処理の単位で書く (ケント・ベックのTDD本のMoneyクラスのイメージ
とのこと。

この、メソッドに対してテストを書くのか、それとも意味のある振る舞いに対してテストを書くのか という所、
昨年チームの中でも話題になったのですよね…。

これも勉強しなきゃだなぁ。

後悔:本当に興味のある話題に持っていけなかった → LT用意していれば…

冒頭、「正しく切る」と書きましたが、特にいま興味があるのが、プロダクト全体を複数のシステムに分割した時に(所謂Microservice的な)、どこで切るのが良いのか ということについてです。
ずっとここ最近もがいている点であり、実際の日々の業務の中でも行ったり来たりしているところなので是非他の方の意見を聞いてみたい… と思っているのですが

他方、うまく人に伝えられるほど自分の中でいまいちまとまっていなく。

今回Gunma.webさんはLTを絶賛募集していたのでそこに用意できればよかったのですが、結局間に合わず。

せっかくチャンスだったのにうまく物にできず、もったいなかったな、と思います。

次のチャンスに向けて準備しておかないと…! これも「やるべきこと」。

Gunma.webさんの雰囲気

順番前後しますが、今回お邪魔させていただいたGunma.webさんについて。
cafe あすなろさんでの開催で、おっしゃれーな雰囲気!


f:id:taichiw:20180121014034j:plain

f:id:taichiw:20180121014459j:plain

しかもコーヒーまでいただけました。

f:id:taichiw:20180121014508j:plain

また、LTが中心のイベントだったのですが、LT終了後、会場その場で一時間弱の懇親会(飲食なし)というのも斬新でした。今聞いたLTを中心に語らえるの、良いですね。

本日は大変ありがとうございました。また機会がありましたらお邪魔したいです!

おまけ 本日のメモ

f:id:taichiw:20180121015138j:plain
f:id:taichiw:20180121015154j:plain

「エンジニアで有り続けたい」って

大した努力もしていないのになんとなく言い続けてるのって、

夢を追い続けているミュージシャン

と一緒だわな…

 

本気で一生エンジニアやろうとしている人や、「でも自分はこっちのほうが適正はあると思う」な仕事(人じゃなくて仕事そのもの)に対して失礼極まりない話だ。

 

 

…ということに今更ながら気づきました。

どんな道を選んでも努力が必要なことには変わりないので、苦手だで済ませずに面と向かう覚悟が必要だな。

(さもなくば、「それはやらない亅宣言。)

Baseball Play Studyで発表してきたんだけど一応ささやかながら技術的な勉強もしているのよ という記録 #bpstudy

今年も野球バカの発表を
Baseball Play Study 2017 冬 野球振返りスペシャル(BPStudy#124) - connpass
でさせていただきました。
資料はこちら。*1

野球にご興味ある方には、是非内容も見てご一笑いただければ幸いなのですが、このブログでは「一応発表の過程で勉強した」技術的なことを書き残したいと思います。

Java

クラスってどう切るのが良いですかね

  • f:id:taichiw:20171223164349p:plain
  • f:id:taichiw:20171223165121p:plain

ってな感じで、
taichiw.hatenablog.com
よりも前に書いていたコードを、上記の本の実践によってリファクタする良い機会になりました。
なにせ、元が勢いで書いたコードなんでクソまたクソ。リファクタの題材としては我ながらとても素敵でした。

Parallel Stream たのしー

taichiw.hatenablog.com

パラレル処理が威力を発揮するとき
最後に、parallelStreamの速さの実験。YahooFinanceが提供している株価APIを連続でコールして、最も株価が高い銘柄を求めるというものでした。
通信が絡むため繰り返しによるオーバーヘッドが大きい処理です。
これをparallelStreamを使って並列化することでめっちゃ速くなる!という例。

以前はこういった処理を記述するためにはマルチスレッドで意図的に書く必要がありましたが、今後は非常にシンプルに書くことができるようになるようです。

これを4年越しで実践…

最近は「何でもかんでもParalellStreamにするものではない。かえって遅くなることもある」といわれているようですが、少なくともスクレイピングを簡単に高速で回すには速かったで!*2

Non-Java

久しぶりにPython使ってみたぞ

こういうグラフが描きたくてですね

なんか適当なオンラインツールとか無いかな-… と思っていたんですが

  • f:id:taichiw:20171223170655p:plain
  • f:id:taichiw:20171223170711p:plain

と、教えていただきまして、観念して(?)Pythonで書いてみました。
github.com

コードを書くの自体はちょっとググりながらで1~2時間程度だったんですが、きれいなグラフを描くのが予想以上に難しくて。
計算を始めるときのノードの初期位置に結果がかなり依存してしまうようで、実行のたびにグラフの絵が変わってしまう、という状況でした。

そんなわけで上のスライドの右下にもある通り、パラメータいじりながらの、何度も試しながらのの中で得られた、「奇跡の一枚」ですw

ソーシャルコーディング(?)たのしー

本来の単語の使い方と違う気がしますが…
上にもキャプチャ貼ったとおり、今回はあれやこれやとSNS上でつぶやいたり相談させてもらったりしまして、
たくさんの方から(主に技術的な)アドバイスを頂きました。*3

普段のお仕事だと、社内で似たようなことはできたとしても、どうしてもフルオープンでやるわけにはいかんので… 
こうやってオープンにワイワイやれるの、楽しいですね。

*1:SlideShareの再アップロード機能がなくなってしまったので、Speaker Deckに引っ越す。(比較表もあるよ) - エンジニア的なネタを毎週書くブログで書いたとおり、Speaker Deckに上げてみました

*2:当然、やりすぎると攻撃になってしまうので程々に…

*3:本当はLTのネタ自体も事前にレビューしてもらってブラッシュアップしたいところなんだけど… レビュアーとして最適な皆さんが、当日の一番の「お客さん」なのが悩みどころw

SlideShareの再アップロード機能がなくなってしまったので、Speaker Deckに引っ越す。(比較表もあるよ)

プレゼン資料のアップロード。
もともとSlide Shareを使っていたため、ちょっとイライラする事があったり、「イケてるエンジニアの人のSpeaker Deck率高いなぁ…」と思いつつもSlide Shareを使い続けていたのですが、
何やら技術的な理由*1によって再アップロード機能を廃止したとのこと。

www.linkedin.com

私も技術屋の端くれなんで、

You will still be able delete your older SlideShare files and upload new presentations.

って言いたくなる気持ち、わかります。「更新」って意外とメンドウなんだよね。単なる新規登録に比べて。

…とはいえ、これは利用者としては受け入れられねーわ。
自分が発表した後に、ブログからリンクしてもらったり、埋め込んでもらったものを全く変えられないというのは辛い。

…ということで、Speaker Deckに移行しようと思います。

このタイミングなら誰か検索で来てくれそうな気もするので
自分の目で見たところの比較表でも書いておこうかと。

アカウント

  • SlideShare
    • 独自アカウント
    • LinkedIn アカウント
    • facebook アカウント
  • Speaker Deck
    • 独自アカウント
    • GitHubアカウント

どちらもよく使う、覚えているアカウントが使えるのでまぁOK.
SlideShareFacebookアカウントでログインできるのが地味に便利ではありましたが…。

スマートフォンでの閲覧

以前から、人様のスライド on SpeakerDeckをSNSなどで見つけて見る時にちょっと気になっていた点。見られないほど苦痛ではないけど見やすくもない。*2
一方、SlideShareのアプリはアプリで、結構問題があって、ストレスの一因ではあったのですが…(Webより機能が落ちていたりとか、何故か真っ黒でスライドが全然前表示されない時があったりとか)

アップロード

  • SlideShare
    • PDFの他、パワーポイントのファイル(pptx)が直接アップロード可能
  • Speaker Deck
    • PDFのみ

SpeakerDeckはパワポ、上げられないんですね。
とは言え今時は、Windowsパワポからでも普通にPDFが吐けるので、大して問題ではないです。
強いて言えば、SlideShareはpptxファイルの置き場そのものとしても使えたんだけど、SpeakerDeckの場合は別で管理しなきゃだなーと。

再アップロード

  • SlideShare
    • できない
  • Speaker Deck
    • できる!!!

ここまでの項目は見ての通りSlideShareに未練タラタラ感あるのですが… これは譲れねーわ。

*1:この辺のブログを見ると、以前からSlideShareさんの中では再アップロードが問題になっていた模様です。 http://did2.blog64.fc2.com/blog-entry-396.html

*2:Androidで勝手アプリを発見しましたhttps://play.google.com/store/apps/details?id=com.unosk.speakerdeck&hl=ja

新しいサービスを引き継ぐにあたって「ドメインナレッジ」は必要か

今年の二月ころ、ある会議の中で、
ドメインナレッジが不要なプロダクトを作りたい」
と発言した。

他の参加者の皆さん(偉い人多め)からは、総じて「ポカーン」とされてしまった。

実は、その時の私は、なぜ「ポカーン」とされているのか、よくわからなかった。


正直に言うと、二月のその会議で、一体自分は何を言いたかったのか、
その時は自分の中でもうまく言語化できていなかった。

それがついさっき、急に、ちょっとだけ分かった気がしたので、忘れないうちに言語化しておきたい。


私は、

ほぼドメインナレッジを持たない状態のエンジニアが
初めてそのプログラムを読んだ時に(あるいはコンポーネント図などシステム全体の構成を知った時に)
システムの設計からドメインナレッジ(どういうビジネスを代行するシステムなのか)を知ることができる

そういうプロダクトを作りたかったのだと思う。



いま同僚と、こちらで紹介されている、オブジェクト指向エクササイズに取り組んでいる。
qiita.com

お題になっている自動販売機のソースはこんな感じ。
https://gist.github.com/i-takehiro/3ccb2ece25c89d4ed41c

(エクササイズのお題として)非常に素晴らしいコードだ。
このコードを見て、
自動販売機とは何か
・そもそもこのプログラムが何をしたいのか
理解するのはかなり難しいと思う。


「ポカーン」とされた、会議の話に戻る。
当時の私は二年ほど、上記のような「自販機」のメンテナンス(新規の追加機能開発含む)をしている状況だった。

意図が全くわからないコードに対して手を入れなければならなかった。

作った人たちは既にほとんどいなかった。あるいはいらっしゃっても(失礼ながら)元の業務を知らないか、忘れているか だった。
(あるいはご存知なのに私が決めつけて聞かなかった時もあったかも。この点は反省)

業務に詳しい人はいたので、どういうビジネスモデルなのかは教えてもらえた。
しかし、そこから当時のエンジニアが何をどう思って今のコードに至ったのか
そのコードに手を加えるとしたら何が正しいのか

は必死に過去のエンジニアの考えに想像を巡らせる必要があった。


過去に作られたシステムの運用なんて大体そんなもんかもしれない。
とは言えその時私が見ていたシステムはあまりにビジネスそのものとプロダクトが複雑で、自分のキャパを超えていて、正直辛かったし病んでいた。


それでも。
私は、

私が作ったシステムを引き継ぐ人がほぼ背景の知識が0であってもシステムの意図を理解でき、その後変更が加えられる

そんなシステムが理想的だと思う。

当然、そんなシステムを開発するためには
・背景にあるビジネスへの理解
が欠かせなく、
更に、
・そのビジネスを「理解できるシステム」に落とし込むことができる設計力が必要だ。


だから、「ドメインナレッジが要らないシステム開発」のようなことを言って「ポカーン」とされたんじゃないかな、と
今になってみれば思う。


おまけ:当時見ていた「自販機」はこんな感じ

「自販機」はすごく複雑なものだ。

・「喉が渇いたな- 甘くて冷たいのが飲みたい」というユーザのリクエストを受け…
・まずは原料を調達。香料や砂糖などを生産している会社に在庫を問い合わせ、仕入れる。
仕入れてきた材料を混ぜ混ぜして製品を作成。コーラとか、ソーダとか、お茶とか いくらかの商品が完成する。
・商品を陳列。ユーザに選んでもらう

というような機能を持っていた。

なお、
・材料を生産・売っている会社
・ジュースを作る会社
・ジュースを販売する会社
は全部違う会社で、それぞれの会社が利益を出すために会社間の取引の際に
 ・原価に利益率を掛けて卸したり
 ・販売戦略に合わせて原価割れするくらい値引きしたり
するのだけど、この3社の、そういったお金に関する計算も全部一台の自動販売機がやっている。

「境界づけられたコンテキスト」なんてクソ食らえな、スーパー自販機だ。

※そんな自販機、今日も元気に稼働しています。毎日ぼくのお給料を稼いでくれてありがとう。
 そしていまメインで見てくださっている担当者の皆さん、本当に有難うございます。

非同期処理の成否をクライアントが追いかけるのは良くない

何かのサービスを非同期で実行する場合。

運悪く、サービスダウンなで実行されなかった場合に、どのように検知・リカバリを行うか。

 

サービスダウンによる再送をクライアントにしてもらうのはよろしくないので、

サービス提供側がキューを用意して、再送処理なりなんなり自分でハンドルすべき…

 

と思ったのですが、じゃあキューが落ちてたらどうするの?というところでふりだしに戻る…。

 

やっぱり送信側がハンドルするしかないかな…。

 

キューを冗長化するのはありなのかな。

 

一番厳密にやるなら、あとで付け合わせる方法がベストなんだろうけど、これは密結合になりやすいからあんまりしたくない…