パネルディスカッション テーマ

「プログラミングにおけるより良い選択とは〜『ソフトウェア設計のトレードオフと誤り』から紐解く設計方法〜」に参加してきました

プログラミングにおけるより良い選択とは〜『ソフトウェア設計のトレードオフと誤り』から紐解く設計方法〜

https://findy.connpass.com/event/300004/

に参加してきたので、聴講メモです。

イントロダクション:書籍『ソフトウェア設計のトレードオフと誤り』について 渋川さん

資料

https://docs.google.com/presentation/d/e/2PACX-1vSsESeR_qEqudzabbZSiUT9qIoowCJt_kH5xMDwLMNd3CFRHY0Zn5pdGLJUSiBPhqyaeP3zQnGWCLuU/pub?start=false&loop=false&delayms=3000&slide=id.p

本の概要紹介

全部で13章あり

  • プログラミングな話
  • 分散システム系な話(分散システムに詳しい人が書いた部分)
  • 日付と時刻の話(この章は結構他と毛色が違う)

のようなことが書いてある

どんな本?

プログラムは書いた通りにもちろん動くが、メンテナンス性や性能や拡張性などの部分は考える必要がある。
様々な業務経験から議論が深掘りされているため、渋川さん自身も発見が多かった。

逆にどんな本ではない?

  • 手っ取り早くコードを読みやすくするとかではない
    • リーダブルコードみたいな感じではない
    • ある程度コードを読みやすくする心得みたいなのは知ってる前提の、初心者を突破した人レベルが対象
  • 正解を求める向け人ではない
    • クリーンアーキテクチャの本とかでもそうだけど、「こうすればいい」を求めてる人向けではない
    • おそらく正解を求める思想の人は、現実ではそんなことはないと感じると思う
  • 現在多く使われているフレームワークを網羅しているわけではない

トレードオフとは?

トレードオフは判断基準によって変わるし、
トレードオフから決断をするときには、更に別な基準が入ってきたりする。

トレードオフは面白い

  • 採用しなかったアーキテクチャも残したらいいのではないか。
    • 他案でどんなものがあったのか。
  • 状況が変わったら採用しなかった他案が参考になるのではないか。
  • 初心者が読んだら参考にもなるのではないか。

パネルディスカッション「渋川さん・松岡さんならどちらを選ぶ?」

トレードオフがある複数の選択肢のうち、お二人なら何を選ぶのかをお話いただきます!

パネルディスカッション テーマ
パネルディスカッション テーマ

コードの重複vsコードの柔軟性

渋川さん

重複は気にしない
DRYの法則でも、3回以上重複するなら改善しようとなっていて、逆に3回までなら良いかなと思う。
最初から重複を排除しようとすると必要以上に複雑になったりもする。

松岡さん

テーマが 〇〇 vs 〇〇 となっているが、スタンスは違うものではないと思う。
重複というより、知識や責務で分けるのが良いと思う。
たまたま同じプロパティだったとしても、
たまたま同じだったユースケースが違うものだったりもする。
それを一緒の扱うようにしちゃうと難しくなる。
クリーンアーキテクチャは難しくて認知負荷も高いが、
社内でも責務を分けるのが大切というのを繰り返し発信するようにしている。

渋川さん

フレームワークによっては、
バリデーションはここに書くと決まってると、自然と責務を分けられるようになったりもする。

Q1

コードの重複について、各クラスに分散してしまっているものはどのように検知していらっしゃいますか?
静的解析で賄える部分もありますが、気付かぬうちに重複が増えてしまっていたケースのコントロールに苦戦してます。。

A1

松岡さん

自動検知はそんなにできなそうとは思っている。
自分たちはパッケージに分けるとかのルールがあって、リファクタをしやすくするようにしている。
みつけたら改善するというようにしている

渋川さん

そもそも重複を排除したほうがいいのかを考えるのもいいかもしれない。

例外 vs 他のエラーハンドリングパターン

渋川さん

このフレームワークや言語ならこういうやり方だよねというのがあるので
それから離れないほうがいいかもしれない。
例えば関数型を学んだからモナド使ってみようかなみたいなのは
他の人からしたらノイズになったりする。

例外の仕方というよりは、例外は最終的に誰が処理するのかを考えたほうがいいかもしれない。
ユーザーにどう対応するのか、社内の誰かがどう例外に対応するのか等を考えて
そこから、最終的にどうするために例外こうしようということを考えたほうがいいかも。

松岡さん

渋川さんに同意。
言語によっては、例外の投げ方をどうするかとかの議論はあると思う。
TypeScript や Kotlin などで、例外を投げるのかエラーを return するのかとか
そういう話が出てくるときはある。

Q2

個別具体の例外ルールが積み重なって負債のようになっており、別管理になっているのですが、例外処理を作りすぎない方がいいなどの目安はありますか?

A2

渋川さん
例外処理を作りすぎというのは、例外の型を作りすぎという意味だとして、
最終的に例外を処理する人が運営の人なのかサポートの人なのかとかだと思うが
その人たちが対応できるように、リストを作っておくといいのかなと思う。
例外はシステム外で対応するという話なので。

流行を追いかけ続けること vs コードのメンテナンスコスト

渋川さん

仕事で選ぶことが多いのは、ある程度歴史がある言語やフレームワーク。
Rust ももう10年くらいたってるので、安心して使えるかもしれない。
ただ、フロントエンドは最新を追いかけてる。
フロントエンドの新しいものは革新的で自分たちの利益になると大きい。

松岡さん

渋川さんに同意。
追いかけるというより、学んでいくといいことがあると思っていて
新しいトレンドを知っていくと、よりよい書き方とかが学べて今後取り込んでいく選択肢になるので
学んでいくのが良いと思う。

Q3

最近の言語は例外がないものが増えてきているのですが、例外を使うメリットは何でしょうか。個人的には解析性やマイクロサービス化が進むことでデメリットのほうが多い気がしています

A3

渋川さん

例外が発生したら一箇所で処理できるのでいいというのが、例外が発明されたときはあったかもしれない。
ただ、いろいろ意見があって例外は例外で扱いづらいところとかはあるかも。

松岡さん

さっきの Go の panic の話もあったが、本当にシステムとしてどうしようもないみたいなときは
例外を投げてまとめて処理できるともしかしたら良いのかも知れない。
そうじゃないときは分岐させてみたいな使い分けができるといいかもしれない。

Q4

現在プロダクトに残っている例外処理のいくつかが実装当時の意思決定が残っておらず、惰性でそのままなのですが、改善すべきでしょうか?
当時の思想がわからない例外処理の取り扱いのご意見を伺いたいです

A4

状況によるかもしれない。
握り潰しているのかもしれないが、それで困っているなら改善したほうがいいかもしれない。

Q5

コードのメンテナンスにかかるコストを計測されていたりしますか?
属人化されており、現在は良いのですがその方が異動等でいなくなった場合の対処法に悩んでおります。

A5

松岡さん

ここがこのくらいぐちゃぐちゃだと、こう困るよというのを言語化するために計測するとかのほうがいいかもしれない。

渋川さん

コストを計算したものを一概に判断はできないかも。
AさんがやるのとBさんがやるのでかかる時間も違うので。

Q6

昨今のLLMの隆盛から開発に取り入れるべきか悩んでいるのですが、流行に乗ってどんどん取り入れるべきなのでしょうか?
生産性向上の反面、これまでの標準から外れることやメンテナンスコストに見合うか否かの判断はどうお考えでしょうか?

A6

松岡さん

入れるというのも、開発プロセスに入れるのか、プロダクトに入れるのかで大分話が変わる。
プロダクトには合う合わないがあるので、そこを考えるしかないかも。
開発プロセスは、copilot 入れたらアシストしてくれるので、いれてみたらいいんじゃないかなと思う。

渋川さん

プロセスだという前提で、
生成されるコードもレビューをしたりするので、全部おまかせで生成にはならないとおもう。
Javaでも歴史の中で流行りの書き方とかがあって、古い書き方を生成されたりもするので、そういうのは改善するし。
生成が得意なものもあったりするので、熟したものを使うとかはあるかもしれない。

Q7

少人数で開発していた初期フェーズから組織がグロースしていく中で、チーム毎に開発が多様化してコードの重複や書き方が複雑化していくと思っています。
保守コストの高さを許容してでも共通ロジック化を進めるべきタイミングはいつ頃と考えられてますか?

渋川さん

先手先手でやるしかないと思う。

松岡さん

共通化の責務を誰が見るのかが大事かも。
全員自分のコードしかみてないとかだと良くなくて、横串で誰がが責務を持ちますというのがあると良いかも。

クロージング

渋川さん

実は、会社のテックブログを年間200記事近く投稿とかしてます
よかったら見てね
Future Tech Blog好評配信中
https://future-architect.github.io/

松岡さん

社内で、毎週絶対記事出す、更新が止まったらそこで終了というイベントをしている(現在13週目)
https://zenn.dev/p/loglass
質問箱もやってます
https://querie.me/user/little_hand_s?ts=1701151680883

togetter まとめ

https://togetter.com/li/2267188

参加しての感想

渋川さんがおっしゃっていた、採用しなかった設計もドキュメントに残すと良いのではないかというのは自分もそう思っていて基本的に残すようにしている。

採用しなかった設計というよりは、「なぜいまこの設計や選択肢を取ったのか」を記載するようにしていて、その意思決定の材料として「背景として他にこういう選択肢もあったが、こういう比較検討をした結果こちらを採用した」を残すようにしている。

理由は渋川さんがおっしゃっている通りで、将来状況が変わったときに「既存のようになっている理由がそれであるのなら、こういう変更をするのは問題ないだろう」という、将来の変更の助けになるためにしている。

また、イベント開催前にパネルディスカッションテーマを見ていたときに、「vs と書いてあるが、これはどちらが良い悪いとか、排反しているとかではなく、ソフトウェアを変更を容易にするための手段であって、目指してるところは同じの認識」と思っていたが、松岡さんも近しいことをおっしゃっていたように思えて、自分の認識が違ってなさそうで安心した。(イベントのタイトルが「トレードオフと誤り」なので、あえてのディスカッションテーマだったのかも)

「例外はシステム外で対応するという話なので、最終的に誰がどう処理するのかを考えるのが大事」という点で、確かに自分も例外を投げるときは、その後の人での対応はどうするを考えているが、言われてみて「たしかに」と改めて思うところだった。

他の参加者の方からの質問で、静的解析ツールや LLM を使うケースもよくあったなぁと感じた。

自分はその辺りにはまだ疎いので、勉強していきたい。

今回テーマになってる本の存在は知ってたのだけど読んでないので、読みたくなった
「ソフトウェア設計のトレードオフと誤り―プログラミングの際により良い選択をするには」https://www.oreilly.co.jp/books/9784814400317/

「コード品質向上のいろは – 先達に学ぶ実践例 Lunch LT」に参加してきました

コード品質向上のいろは – 先達に学ぶ実践例 Lunch LT

https://findy.connpass.com/event/300912/

に参加した聴講メモです。

LT①『「コードがむずかしい」からの脱却』 株式会社メルカリ 濱村甚平(@jinpeih )

資料

https://speakerdeck.com/jimpei/kodogamuzukasii-karanotuo-que

途中から参加したので、メモは途中から

「コードが難しいから改善したいので時間ください」だけだと、相手には伝わらない。

そのため

  • それはどのくらい悪くて
  • 改善するとどのくらい効果があって
  • どのくらいの時間が必要なのか

などの指標が必要。

複雑度の指標

SonarQube 等のツールがあるのでそういうのを活用した

ただ、だからといって数値が悪いイコール絶対改善!というわけでもない

複雑度が高いからといって、そのコードを滅多に変更しないなら改善してもあまり嬉しくない

また、複雑度はやり方によっては回避できる。

例えばネストさせない代わりに関数を分割させまくると複雑度の数値は下がるが、

それは複雑度の低い複雑なコードなだけである。

指標を下げることが目的ではないので、あくまで補助的な使い方。

ひとりで書くのは難しい

ペアプロで意図を共有しながらコードを書くと、少なくとも二人の間では意図が通じてる

Q&A

Q1

他の人や他のチームの数値が見えすぎると、良い部分はある反面少し競争のような形になってしまうなとも感じています。

どこまでの人と数値を共有するかなど、意識されたりしていますか?

A1

比較するものではないので、競争とかにならないように数字数字という扱いにしていない。

共有は広く共有したほうが、参考になるのでいいと思う。

Q2

認知的複雑度を数値化してからは、やはり不具合は減ったのでしょうか?

A2

これは簡潔に yes/no かは言えない。というのも、数値化した後にチームを離れることもあるし、

まだ数値化したあとに不具合の数がそれによってどうなったかを追っていないというのもある。

不具合が減った要素はいろいろあるので、そこまで追うのも難しいかも。

ただ、将来的には、不具合を減らしたいから数値化しているというのも目的の1つにはある。

LT②『なぜリアーキテクティング専任チームを作ったのか』 株式会社アンドパッド 白土慧(@kei_s)

資料

https://speakerdeck.com/kei_s/naze-riakitekuteinguzhuan-ren-timuwozuo-tutanoka

現状のアーキテクチャ

中心となる Rails に付随する形で各プロダクトが存在

Rails は8年選手

Rails のライブラリアップデートが滞っていた

  • ライブラリの開発が停止してたりしたが、そのままだった
  • アップデートしようにも、そのライブラリは複数のチームに跨っているので、1つのチームで責務を持ちにくい

これによって、古いライブラリに依存したコードを書かなければならなく、メンテナンス性が低下。

OSSのメリットもあまり受けられない状態に。

リアーキチームの発足

  • 特定のサービス等には責任は持たない。そこは既存のチームが担当する
    • その代わり、チーム目線だと難しい全体目線で考える部分を担当
  • 共通利用されているところとか担当
    • 逆に、特定のチームでのみ使っている部分とかは対応しない

さじ加減

「ライブラリアップデートは、リアーキチームの仕事」としない。

特定の人の仕事ではなく、改善意識は全員が持つべき

Q&A

Q1

お話であったように、エンジニア全員で改善をするというマインドが失われないようにするための取り組みはありますか?

専任チームを作ることで、各自から課題が出てこなくなるリスクもあるなーと

A1

わいわいと「ここ改善したいよね」みたいな話をしたり

リアーキチームに限らず、改善活動するのは良いことである、みたいなのを浸透させるようにしている

Q2

ライブラリアップデート時の影響範囲調査の進め方など、専任だからできるメリットをもう少し聞きたいです

A2

専任チームのいい例は、専門でそこの領域に調査の時間とかとれたり知見がたまるのが良いと思う。

逆にプロダクトチームほど知見がないので、「この挙動ってどうなってる」「こういうテストを考えてるけど抜け漏れないかな?」

みたいなコミュニケーションを取るようにしている。

LT③『10年モノのAndroidアプリのコード品質を改善していく、3つの取り組み』 Chatwork株式会社 奥澤 俊樹(@okuzawats)

資料

https://speakerdeck.com/okuzawats/4de89f92-6dff-4d77-8701-10882ff27be7

なんでコード品質を改善したいのか

  • メンバーやチームが増えた
  • コード品質が開発速度に直結
  • 改善したい

コードレビュー

「自分がコード品質について誰よりも考えレビューすればよい」と思っていた。

が、自分が門番になってしまうと開発速度が落ちると思ったので、そうはしなかった。

自動レビュー

静的解析ツール

  • danger
  • ktlint
  • android lit
  • sonarcloud(今日の話はこれに着目)

メリット

  • コードが怪しいところ(Code Smells)の検出
  • 複雑度を出してくれる
  • 閾値を満たさないと CI が落ちる

勉強会をするようにした

https://creators-note.chatwork.com/entry/code-readability

ガイドラインの作成

Kotlin のスタイルガイドみたいなのを参考にした

できれば Lint がスタイルガイド通りに反応してくれたら嬉しいので、検討中

Q&A

Q1

SonarCloud検討しているのですが、他に検討したツールや自作していたものなどありますか?

また、どういう観点で使う判断をしたか参考に聞きたいです

A1

もともとある程度SonarCloudの知見があったから使った

Q2

ストリームアラインドチームメンバーをどうアサインしたか気になります

A2

それぞれのエンジニアがどういう仕事やキャリアにしたいか等で検討した

LT④『DMMプラットフォームにおけるコード品質を改善する取り組みの理想と現実』 合同会社DMM.com pospome(@pospome)

資料

https://speakerdeck.com/pospome/dmmpuratutohuomuniokerukodopin-zhi-wogai-shan-suruqu-rizu-minoli-xiang-toxian-shi

レガシーシステムのリプレイスをするよ

コードの品質を高く保って、開発速度を改善したい。

品質を高く保つための持論

リファクタリングや静的解析ができても、設計スキルが高くないと品質は上がらない

が、設計スキルが高いエンジニアを雇うのも育てるのも難しい

そこで、レビューシステムの導入

各チームのコードを設計スキルの高いエンジニアがチーム外レビューする取り組み

うまくいく自信があった

が、それだけだとうまくいかなかった

なぜなら、チームによって課題が様々だから

  • リファクタリングの時間確保
  • 良し悪しの判断が難しい
  • 意思決定権持ってる人への、品質に対する理解

まとめ

組織が大きいとコード品質改善は大変。

特に意思決定の部分が大変なので、戦略を持ってやらなければ。

Q&A

Q1

pospomeさんの考える「設計スキルが高いエンジニア」の基準をお伺いしたいです!

業務知識に詳しく、アーキテクチャ図を描ける人、静的解析に詳しい、など

A1

SOLID 原則とか分かってたり、もちろん業務知識も必要

図を書くためのスキルみたいなのはあまり必要ないかも。

Q2

専任チームを作る話が本日多数ありましたが、

最初にチームを組成した時に、他のチームへどのように介入したか、より失敗談や工夫した点などがあれば聞きたいです。

A2

まずはレビューやらせてくれという姿勢で入った。

失敗談の話になるが、結局チームのテックリードや意思決定者を巻き込まないといけないので難しかった。

参加しての感想

各社、ある種似たような悩みを抱えていて、それに対して社内の状況に合わせたアプローチを試行錯誤しているんだなぁと感じた。

そういう意味でも、今回のような会は各社の知見を共有して自社に活かすことに繋がるので良いなぁと感じた。

各社概ね共通していることは

  • 現在の状態を整理
    • 課題は何か
    • 必要であれば静的解析ツール等を使って数値化、見える化
  • 対策を検討
    • どこまで対応するか
    • 専門チームの立ち上げ
    • コードレビュー
    • 品質意識の浸透
  • 対策を実行したり、更にブラッシュアップしたり
    • 指標に対する考え方
    • やること・やらないことを明確に
    • より活用にするためにどうするのが良いか
    • チームの課題に合わせて動くように

などがあるなぁと思った。

当たり前かもだが「これが最近流行ってるやり方!」「とりあえずこれやっとけ!」みたいなのがある訳ではなく

課題が何で、どういうゴールを想定していて、理想の状態にするために何をすればよいかを考え、改善し続けるという、課題解決の基本的な考え方と同じだよなぁと思った。

その中で、テクニカルな部分や参考になる手段として静的解析ツールの導入や、専門チームの設立などがあるなぁと思った。

 

SonarCloudは触ったことないけど、コードの怪しそうな部分(Code Smells)を教えてくれるのが気になった。

「リアーキテクチャことはじめ~事業成長を最大化するための技術選定と登り方~」に参加してきました

リアーキテクチャことはじめ~事業成長を最大化するための技術選定と登り方~

https://flexy.connpass.com/event/259853/

に参加してきたので、そのときのレポートです。

 

レガシーの定義とは?

今回のレガシーの定義では

今回のレガシーの定義
今回のレガシーの定義

と定義します

ここで大事なのが4で、簡単な機能追加に時間がかかってしまうことがある。
そこで、リアーキテクチャが必要になってくるが、
単に「このシステムは今ここがよくないのでこうすべき」というのは誰でも言えるが
将来の事業成長や拡張性を見据えてどうするか、ということも考えられるのが必要になる。


そこで、今日はリアーキテクチャをどのようにやってきたとかの話を事例を交えてする。

各社サービスの背景からみるリプレイスの事例

事例1

事例1
事例1

バージョンアップしたいが、なかなか難しく、負債が高まっていっていたため、リプレイスを検討した。

リプレイスを検討していると
現状のシステムを分析した結果、複数の境界線を跨っていることがわかった
そこで、記載しているような設計にした。
稼働年数10年とあるが、システムをリプレイスするのは稼働年数と同じくらいかかる。
今1.5年ほどリプレイスを進めているが、まだ序の口。

とある業務フローがあり、
伝統的なシステムだと、とあるデータを同じデータとして扱いたいが
業務フローを精査してみると、違うデータとして扱う必要がある。
例えば、セブンイレブンにあるお弁当とかは、全部同じものではなく、店舗によって近い工場で造られている
お弁当の申請をするとそれはパートナーが登録したデータだが、申請されたデータを承認するのは別の工程で行う。
それを処理するには、申請されたイベントから派生させて行うのが良いとなり、そうしている。

事例2

事例2
事例2

最古の commit が 2012 年だが、それ以前にも何かあったらしい。
一番社歴が長い人でも5年前で、その人に歴史を確認しながら進めることもある。
中身を見ていると、名前がおかしなものもちょいちょいある。
改修の際に調査が長引いてしまいデリバリーが遅くなることがあり、リプレイスを検討した

1日30分くらいつかって地道にLaravel に載せ替えることもしていたが、長続きせず頓挫することもあった

現在は本腰をいれてリプレイスを進めている。
いま進めているリプレイスも何年かかるか分からないが、進めている状態

リプレイスする際に、ちゃんと技術選定していかなければならない。
Rust を採用した理由は?と聞かれて「流行ってたからです」となると
未来で困る人がその理由は聞きたくないだろう。

事例3

事例3
事例3

読み取りと書き込みは別要件なので、それぞれ別個に最適化したような設計をした

事例4

事例4
事例4

内部事情を知らないといけないので、入った人が戦力になるまで時間がかかる

コードベースでモジュラーモノリス化した

事例5

事例5
事例5

マイクロサービスアーキテクチャ化をすすめている

マイクロサービスアーキテクチャにするとビジネスが推進されますよという見出しの記事がよくあるが
それを行うには何年単位という時間が必要になる
ドメインを分析したり、業務フローを精査したりなんなら業務フローを変えたりする必要もある
もろもろ全部考えた上で、決断する必要がある。
なんのためにマイクロサービス化するのか、技術ファーストではなく、ビジネスのためにどうするのか、というのを考える必要がある。

Q&A

Q1

リプレイス後のアーキテクチャはどのように決められましたか?トップダウン、ボトムアップなど。また、ボトムアップの場合で、メンバー間で意見があわない場合はどのようにアーキテクチャを決定されましたか?

A1

あらたまさん

トップダウンだった
現場で、どうすればいいか分からないという状態だったので、トップダウンで行った
また、リプレイスというのは向こう数年にわたって投資をしていくという判断なので、経営判断が必要になる
のでボトムアップだけだとうまくいかないと思う。
経営的に、いまここに投資するべきか、という判断をしている

ytakeさん

トップダウンだけでいくというのはあまりやっていない
メンバー間で意見が合わないばあい
スキルセットが合わない人ももちろんいるので、ディスカッションはする。
が、技術レベルを下げることはあまりしない。そこを下げてしまうと、周りが面倒をみる必要が出てくるし、会社の技術レベルが下がってしまう。
ので、習得してもらうようにしている

Q2

言語やフレームワークを大きく変更したとき、メンバーに対するキャッチアップはどのように実施されていますか?(ex. 週1で学習時間を設けているなど)

A2

あらたまさん

輪読回をしたりしている

ytakeさん

技術習得が難しい人もいるし、本だけだとわかりづらいところもあるので、質問があれば自分が噛み砕いて答える、ということをやっている
エンジニアだけに限った話じゃないが、技術習得のアップデートというのは当たり前ではあるので、そういうのを自主的にやっていけると良い

Q3

リプレイス中に仕様変更がある場合、どのように取り込んで開発していますか?

A3

あらたまさん

リプレイス中の使用変更はブロックするようにする

ytakeさん

やらないといけないことあやるようにしている

Q4

退職者が多いことによる辛み=技術的負債とした時に、リプレイスに時間が数年かかるとなると今作っているものを以下に負債にしづらくするかというのが大事だと思っています。そこに対する取り組みとかありますか?(ドキュメントは工数がかかりすぎたり、陳腐化する懸念がありどう考えているか伺いたいです)

A4

あらたまさん

ドキュメントはコンフルエンスとかにたくさん書くだけではなくて、コードコメントとかも大事なドキュメント
細かくドキュメントを残していけるかが、システムの寿命にもなると思う

ytakeさん

陳腐化するのか防げないので、定期的に確認する必要がある。
書いた人の考えていることの一部を読んだ人が得られるので、劣化した情報が伝わっていくので陳腐化は防げない
ので、定期的にメンテナンスする必要がある。

まとめ

ytakeさん

作るものだけを考えるのではなく、技術ファーストではなくビジネスのことも考えよう

あらたまさん

サービスや事業に対する理解を社内の人とたくさん話をして解像度を上げていく必要がある
自分の考えた最強のシステムを作りたくなる気持ちもあるが、そこを抑えて考えていく必要がある

参加しての感想

イベントの中でも出てきましたが、リプレイスはしなくて良いのであればしないほうがよく

日頃の業務の一部をリプレイスに投資するという判断をしなければならないので

ある程度ストレスがかかることもあると思います。

また、リプレイスをするというのは現状の負債と立ち向かうものなので、作業自体にも結構な負荷がかかると思います。

全体的にですが、そんな話を笑いも交えながら話をしてくれてとても安心しながら聞けました。

また、リプレイスは単発で終わるものではなく、数年かけて行うこともあるので

何をどうするということをしっかり決めたり、どういうプロセスでやっていくのかという計画を立てたりすることが重要だとあらためて感じました。

何度か出てきましたが、技術ファーストで考えるのではなくビジネスのことも考えていこうというのはとてもうなづけました。

いまのレガシーなシステムでつらいことを感じることもありますが、それだけの理由でリプレイスしたいというのは目線が自分に向いているので、ビジネス目線でどうなのか、ユーザー目線でどうなのか、ということまで考える必要があると、改めて感じました。(つらいのを許容するべきという意味ではない)

 

設計ナイト2020に参加してきました。

設計ナイト2020

https://kichijojipm.connpass.com/event/191220/

に参加してきたので、そのときのレポート

正直、設計に関して疎くて内容の 1 割くらいしか分からなかったのでメモ程度です。

かとじゅんさん発表

資料

https://speakerdeck.com/j5ik2o/event-sourcingwojie-shuo-suru

今日は、分散システムの設計パターンの話をします。

CQRS の話

DDD によるクエリサイドのペインについて

  • クエリ要件を満たすことでリポジトリが複雑になる
  • レスポンス用 DTO をリポジトリで組み立てるため、N + 1 クエリが発生しやすい
  • ドメインオブジェクトから DTO への変換が非効率

※これらのペインを飲み込めるのであれば、CQRS を採用する必要はない。

CQRS とは

リポジトリがステートを書くのではなく、イベントを書く

イベントをどう使うのか?

イベントというのは、そのとき起こったできごとを保持している

e.g. カートが作られたとか、誰が作ったとか。

そういうのが、git の commit log のようにどんどん溜まっていく

その歴史が大量になってくると、apply する等のときにコストが大きくなる。

イベントソーシングでない CRUD の場合はレイテンシが悪化しやすい。

なぜ C/Q を分けるのか?

一貫性/可用性

この表でも分かるように、扱いが違う

スケーラビリティ

コマンド
一般的な web サービスだと、write よりも read のほうが多い

CQRS の利点と欠点

利点

  • 最悪 write 系が落ちていても read 系が生きていれば、障害にならない。
  • 障害点が分離できる
  • コマンドとクエリを別々にスケールできる。

欠点

  • コストがかかる
    • 構成要素が多くなる
  • CQRS は複雑と言われることが多いが、従来モデルよりもある意味シンプルになる

CQRS でモデルがどう変わるか?

CQRS では、ドメインオブジェクトはドメインロジックを実行するためのシンプルなモデルとなる
ただし、全体の構造は複雑になる

非Event Sourcing での CQRS は色々難しい

CQRS/ES 対応分散システムフレームワーク

  • Akka
  • Akka.NET
  • proto.actor
    • リアクティブシステムが作れそうなのは Golang のみ

境界を引かない=非 CQRS にする

コストをかけてまで恩恵を受けられる想定がないのではれば

CQRS を避けるのも手段としてはあり。

Q & A

Q.

境界を引かない方法って、CQが混じった方法とどこが違うんでしょうか?

A.

極端な話すると、リポジトリをクエリ側で使わないようにする状態のこと

CQRS を使わない方針に倒したほうがいいということ

大まかな C/Q の役割はあるんだけど、明確に分けなくていいよということ

qsonaさん発表

資料

https://hackmd.io/@jnl1y8gDTkq7ywsLXpa6GQ/HkDGObSOP

GraphQL を利用したアプリケーションの設計パターンの話

GraphQL とは

web api を定義するための言語のようなもの

rest api の代わりになるようなもの

サーバー側では、1 つの目的に対して 1 つのエンドポイントがあるが

GraphQL ではエンドポイントは 1 つになる。

クライアントがクエリを宣言する = クライアントが自分で取得するデータを定義している

クライアントサイドの設計

リポジトリ層を作らない理由としては

GraphQL のメリットを殺してしまうから。

また、そもそもクライアントの read リポジトリは作りにくい。

Appllo Stack

colocation

子供のコンポーネントにも、GraphQL の フラグメントを持つ。

そうすると、親のコンポーネントが肥大化しなくて済む。

サーバーサイドの設計

rest api とそこまで変わらない。

Hasura

一言で言うと、PostgreSQL(など)のテーブル定義をするだけで GraphQL API が使える

Service to Service GraphQL

マイクロサービスとかやってると、サーバーで api 作ったけど

どこから使われてるから消しにくいみたいなことがある。

が、それを解決してくれる。

【アーキテクチャ ディスカッション Vol.1】に行ってきました。

アーキテクチャ ディスカッション Vol.1

https://istyle.connpass.com/event/97862/

に行ってきたので、そのときのレポート

 

ディスカッション形式のメモです。
発言に対する発言を1つインデントするようにして書いています。

※正直、うまくまとめられている自信がないので、会話を追って雰囲気が伝われば幸いです。

 

ビジネスロジック層のモデリング

  • active record を使ったときのモデリングが難しい。どうモデリングをするかで分離の仕方が変わる。
    • DB を一回忘れるのはどうか?
    • DB のことは一旦忘れるけど、どこまでを考えるのかが重要になりそう。
    • それって DB を最初が存在している前提では?ソフトウェアの内部構造って、オブジェクトの意味やライフサイクル単位で作っていくと良いのでは?あまり、テーブルに引っ張られて考えるのはよくないかもしれない。
      • その分析ってどうやって始めます?
        • 業務フローから考えます。業務をプログラムに落とし込むにはどうしたらいいのかを考える。
        • この言葉はどういうカテゴリなんだろうとか。
          あまりプログラミングというか、サービス仕様だったりデータのカテゴリわけをする

          • この場合のデータってなんですか?
            • 仕様に出てくる言葉のこと。
            • モデリングっていう言葉の意味が幅広いので、焦点はここだよっていうのを考えるようにする。
            • エンジニアが使うことばっていうのはいろいろな意味があるので、その意味を付箋で貼ってみたりとかもする。
              部分部分でやっていかないといけない。業務の一番重要なところはどこなのかを聞いて、そこに焦点をあてるようにしている。

              • ドメインというのは、答えが出た時に、どういうことをやったんですか?
                • 僕らが行ったこととしては、経済活動という古くから使われているものをドメインとおくことにした。
                  入荷なのかなのかの単位を人それぞれだったが、少しずつリファクタリングすることで擦り合わせていった。
                  図書館アプリを練習で作ってみようとなった時に、
                  会社は貸し借りが大事なのか?いや、在庫管理が大事だ。となって、在庫管理をドメインとして初めて行った。

Clean Architecrue を採用した話

  • 最初始めたときは、どうしてもこの形にならなかった
    presenters を使わない人もいて、translater を使う人もいた。
    スクラップ  &  ビルドを繰り返して、最終的にはこの形になった。
    大事なのは UML 図だった。

    • entity はきっとトランザクション管理でもよいのだと思った。
      ヘキサゴナルアーキテクチャがきて、そのあとこの形になったと思っている。
      オニオンアーキテクチャはただ単にドメイン駆動設計のことを行っているだけなので、use case の部分。
      僕はこれ、浸透させるために教育させるのは無理だと思った。
      なので、ツールを作った。
      WEB のときは、 presenter のときはいらないと思った。
      非同期処理は contorller が返してくれたほうが都合がいいときが多い。
      なので、WEB の場合は presenter はいらないが、GUI ツールのときはいると思っ

      • 教育は諦めた的なことを言っていて、ツールを作ったという話があったが、
        こういう手順でやってねということをやると、考えずにやってしまう人が出てきそうだが、どう思うか?

        • ツール使った方が早くできるよ、というメリットを提示して納得してもらった。
          保守フェーズをやったことがないエンジニアって、伝わらないからつらい。運用する辛さが伝われば話も伝わる。
          そういう意味では、モノリシックで1000行ぐらいあるメソッドの保守とかしてもらったほうがいいかもですね笑(会場でも笑いが起こる)
  • presenter について最近本を読んでて思ったことがあるが、
    本では、presenter はテストしにくい部分とテストしやすい部分を分けましょう、という話が23章であった。
    その中では、 view はテストしにくいが、viewmodel まではまだテストできるという内容だった。
    プログラミング言語中で、日付オブジェクトというものを view に渡したときに
    文字列に変換しなければいけない。
    日付オブジェクトを文字列に変換するのが presenter
    その文字を活用するのが view という感じにしていたので、
    presenter は必要なのでは?と思った。

    • dto を使っていて、テストするので、そこは問題ではないと思った。
  • clean architecture に乗っ取ってるかを管理する CI ツール気になる。
    • それは取り組みをやっている。構文を解析してチェックするようにしている。
      java で gladle を使ってやっているが、導入も簡単なので良い。
      ドメインの依存すべき方向とは逆方向になっているときなど、そういうのはすぐに検知できる。

DB に入れるときに レポジトリって入れると思うが、何を引数に渡している?

  • DB の方は基本的にイベントを保存するようにしている。
    失敗談で、entity を渡すっていうようにしていたら、
    レポジトリの中で新しい entity が渡されたときに、古いものとの差分をとって DB にインサートとかしていたので、その管理がつらくてやめた。

    • 僕もentityというか集約をインサートしている。
      • それってentityとテーブルに差がない状態になる?
        • いや、差がある。
        • DDD のいいところが、イベントをインサートするとDBは肥大化するが、ドメインは綺麗に保てることができるのでそこがいいと思っている。

レポジトリにおいて、参照系と更新系で分けている人はいますか?

  • 参照系だとオーバーヘッドが大きいと思うが、参照系でもユースケース層もあったほうが便利だよねという面もあって、みなさんの事例を聞きたい。
    参照系と更新系を同じレポジトリで管理するか否か?ということ。

    • Clean Architecure の場合は、ユースケースがインターフェイスになるので、レポジトリ使わないパターンで行った。
      • レポジトリはそのまま経由させて、書くのは RDS を使って読むのは Elastic Search とかを使ったりもしている。
        • たしかに書くのは多くなる。DB の先って何年か後に違うのにしようという話が出てくるので、そういう風にしている。
        • 両方とも同じように扱いたいので、レイヤを挟まないようにしている。
          • 逆に、レイヤを分けるようにしている人いますか?
            • 挑戦はしている。ドメインを守りたいみたいな方向でそういう風にしている。
            • 読む先と書く先が違うからという理由があるが、
              キャッシュが落ちた場合って、DBに取りにいくと思うが
              そういう場合はインターフェイスは同じだが、中身は違うようにしている。

キャッシュって、みなさん(Clean Architectureの)図でいうとどこに入れていますか?

  • DB のところに入れている。
    ただ、ドメインをまたぐときに困る。

Clean Architecture って、人と会話するのが苦手な人にとっては苦痛かもしれない

  • 人と会話して、こっちの人は商品って言ってるけど、こっちでは違うことを言っていて、
    そこの分析をやるのが楽しい。
    逆にそこを分析してからでないとコードに落とし込めないと思う。

    • お金をもらって、人に本当に必要なものを作るためには、人と会話ができないといけない。

ドメイン駆動をやっていると、自分の言語がプログラムになってくるのでプログラムを英語で書くのが辛くなる。

  • 逆に日本語のローマ字で書くと良いと、結構読みやすくて良い。

Clean Architecture の本を読んで思ったが、実践に使うには大きなサービスでないとやりずらい。ただ、実際に手を動かさないと習得しずらい、みなさんはどのようにしていますか?

  • 教育を2週間、題材を用意してやってみた。
    すると、完璧に理解するのは難しくても、コピペすればなんとかできるという状態には持っていけた。
  • 個人的には、小さいサービスを作ってみて練習している。
    自分の中で鉄板のお題(RSSリーダーを作るみたいな)を作ってみるというのをやっている。

    • その時って実際に業務でやるときとのレベル感というのが出てきてしまうと思うが、
      どうやってその差分を埋めてますか?

      • 埋まらないですね。ただ、どうしても抑えておきたい部分(例えば例外ハンドリングの仕方とか)はやるようにしている。
  • うちの会社ではレビューで学んでもらうようにしてますね。小さい単位で業務を任せて、レビューして教えたりする。

Flux アーキテクチャって Clean Architecture に似てるって思った人います?

GUIを組んでるときに思ったんだが、形的に似ているなと思った。
そのとき思ったのが、サーバーを介さなければ同じ形になるのかな?と思った。
特に思った人がいないので、この話はやめます笑

ゲームアプリのエンジニアも Clean Architecture に興味あるらしいですよ。

  • ゲーム全体をそうするのはしんどいかもしれないが、一部分だけ Clean Architecture にしてテスト可能にするのは良いと思う。

みなさんどういった経緯で設計とかアーキテクチャに興味を持たれましたか?

  • 僕の場合は 13 年続くでかいサービスを一人で保守していて、そこでアーキテクチャが必要だと思うようになった。
  • 自分でクソコードを生み出して保守しきれなくなって、あるべき姿ってどんなんだろうと思ったのがきっかけ。
  • コアなモデルのほうに興味があったのが一つと、学生のときに設計やアーキテクチャの情報がたくさん入ってきたので、そこがきっかけ。
  • オブジェクト指向から始まって、すごい人が言ってるからいいものに違いないと思って勉強から入った。
  • DBに興味がもともとあった。データモデルが出発点になって、それがきっかけ。
  • 入社したときに、Android が世に出たときくらいだった。一番最初の Activity に何千行もあるアプリを保守しなければいけなくなった。
    そこをどうにかしなきゃねって思って、アーキテクトの考え方になって言った。保守しやすいアプリケーションを突き詰めたら、今に至った。
  • 炎上しているPJがあって、どうにかしてくれというふわっとしたオーダーがあった。
    そういうもののセオリーってテストを書いて始めていくのだが、どうせだからドメイン駆動設計(というのがあるらしいレベルだった)を突っ込んでみたのがきっかけ。
    炎上PJってもしかしたらチャンス(新しいことに取り組める)なのかなと思った。
  • 他者が作ったが放り出したものと同じものを作ってくれと言われた。
    それが、ループが17段あったりもした。
    そういう過酷な状況の中で生き残るためには設計が必要だと思った。
  • 会社が、一人で作って一人で運用している人が多く、アーキテクチャを知っていないと自爆してしまうことがあるので、それがきっかけになった。

分析系の処理を書く(マイクロn秒)ときには、Clean Architecture は採用しないことが多い。

  • なぜかというと面倒臭いから。
    速く返さないといけないときとかは一つのファイルにたくさん書いたりする。

    • それはそれでいいと思う。
      そのソフトウェアが求められている関心事による気がする。
      人が運用する上での複雑性を解決するのが Clean Architecture だったりするし、
      速く返さないといけないとかだと技術的なアプローチが必要になるので、そのときどきにあったアプローチが必要
      Clean Arhitecture は万能薬ではないので、適材適所なアプローチが必要になってくる。

本の内容に関して

「本当の重複」と「偶然の重複」があって、

  • 重複を排除すれば無条件で良いと思っている人がいるが、そこについて書かれているのが嬉しかった。
    • このコードを重複させるべきかどうかという点を考えた時に、
      テストできるコードが設計ができるコードというわけではないと言われたりもした。

組織の形態がアプリケーションに反映されてしまうという法則がある。

  • 組織の形態はなかなか変わらないが、アーキテクチャはよりよいものにしたいと思うときがあるが、みなさんどうしていますか?
    • うちは microservice を採用していて、新しく入った人にはローテーションして多くを触ってもらうようにしている。
      そういう風に知識を蓄えてもらうようにしている。
  • 組織変えなきゃなと思いながらコードを書いたりもしている。
  • 何かサービスを作ろうとなったときに、新しく部署が生まれてそこで作るような文化になっている。
  • スクラッチで作られるサービスがたくさんあるので、横軸で共通で使えるようなライブラリとかプラットフォームがあったらいいと思うが、
    いまのところ組織と同じ形になってしまっている。
  • アーキテクチャ設計と組織設計って同じだと思っていて、組織設計やる気持ちがないとアーキテクチャ設計できないと思う。
    組織設計はマネージャーがやるというマインドだとできないと思う。
  • 結論、組織設計から逃げない。

【システムを構築するときに気をつける10のこと】に行ってきました

【サポーターズ勉強会】システムを構築するときに気をつける10のこと

https://supporterzcolab.com/event/233/

に行ってきたので、その時のレポート

資料

基本的に、このスライドに書かれていることをなぞって講演していただいたので

このスライドをみればだいたいイベントの内容が分かります。

ただ、口頭で説明のあった箇所などはメモをとっていたので

下記に記載します。

まえおき前提

web業界において、スピード重視でサービスリリースするような開発

アジャイル開発などを対象に今回の講演をします。

登壇者の方がよく思うことが、

サーバーサイドエンジニアから受ける質問として

「この機能作りたいんですけど気をつけることありますか?」

と聞かれることがあるのだが、気をつけることはいっぱいある。

だが、書籍とかで気をつけるべきことの情報は見つけにくい。

それで、今回ざっくり説明をしていただける。

安定稼働にはコストとリソースがかかる

設計とかで、結構時間がかかる。

オンプレで動いてたものをクラウドで動かすとかだと、

どのくらいの費用がかかるのか、どういう設計にするのが良いのかが検証してみないとわからない。

例えば、クラウド環境で冗長化するとして、

マシンを1台で動かしてたものを2台にするとかだったら、2倍料金がかかる。

1台が死んだら2台目に切り替わるという仕組み作りの検証もしておかないといけない。

運用体制コスト

誰が通知を受けて、、誰がエスカレーションして誰が対応するのか

とかとかのマニュアルが必要。

ディザスタリカバリを考え、日頃から訓練する。

オペミスとかでデータが消失したときの対策

これは結構難しい。

設計はしたけど、日頃訓練しておかないと

いざ障害が起こったときに、うまく動けないことがある。

擬似的に障害発生させて訓練しよう

システムが落ちたという報告を誰が誰にエスカレーションしないといけないのかを決めておく

例えば、上司に報告して、上司はお客さんに報告するとか。

モニタリングのメトリクスは細かく取る

こういうのを細かくとっておくと、

障害が発生したときとか、スケールするときに情報になる。

ただし、メトリクスをとりすぎると逆にマシン負荷になるので注意が必要

代表的なメトリクスはグラフにしたりしておく

また、そのメトリクスの意味を理解しておく

query/sec というメトリクスってなんのクエリなんだっけ?」とか。

システム全体がスケールできる

ネットワークのスループット

例えばデータセンターだったら、外から入って行くるのが1本だったら、それに耐えられるのかとか。

外部連携

例えばBIツールを使っているときも、外との連携でスケールできるんだっけとか。

設計/選定した技術には責任を持つ

使ったけどちょっと違ったかなというときは

ちゃんと自分で負債を返していかないといけない。

技術選定が間違っていたとかいうこともあるが

それをちゃんと返して行こう

そのためにも、採用した技術には一番詳しくなっておこう。

仕様やデータ構造の変更は必ず発生する

仕様とか技術は変わっていくので

変わってもいいように設計を考えておきましょう。

データの保管場所は塾考する

例えば、クラウドからオンプレに持って行きたいとなったときに

データ量が多いと、転送時間に時間がすごくかかるので気をつけないといけない。

データレイクというのが最近注目されている

データレイクとは、1箇所に全てのデータを集めて使えるようにしましょうという考え方。

セキュリティ対策は必要だが、コストと時間がかかる

権限管理はすごい大変

ここはちゃんと設計しておかないと行けない。

権限の設計が必要

 → しかも、変更が入るので、柔軟な設計が必要

誰が管理して、だれが付与して・・・

転職とか退職とか、人の入れ替わりがあって、権限の管理が大変

クラウドを信頼しすぎない

クラウドはだいぶ安定・安心できるが、100%の安定では決してない。

EC2の場合、メンテナンスのために強制的にシャットダウンされることがある。

だが、EC2の中でvmが動いていて、vmの中のメモリでアプリケーションが動いていて、

シャットダウンさせるには、メモリにのっているデータを退避させないといけないとかの状況の場合もある。

だが、シャットダウン日は10日後に迫っていてつらい。。みたいな状況もある。

謎のサービスレベルの低下

AWSに質問した。

回答は、他で使われているインスタンスの負荷で、それに引っ張られてますとかの回答がきた。

結局、言いたかったこと

優先順位を決めよう

セキュリティが重要だったらそれからやろう。

スケールが大事だったらそれからやろう。

全部やれるにこしたことはないが、時間もないので。

Q & A

Q.どんなメトリクスで区切るとかコツはある?

A.僕(登壇者の方)の場合は低レイテンシーが求められているので、

 1msec, 4msec, 10msec, …. とかで返したクエリとかでメトリクスを切っている

 そのときのメモリの使用量とかを分析できるので、目的別でメトリクスを区切るようにしている。

 

Q. おすすめのメトリクスツールは?導入が簡単とか。

A. saasサービス

   New Relicとか。

   Datadogをリソースの管理で使っている。

   Datadogは楽。

   どちらも外部サービスなんで、アラート飛んできたらどこにいても見れるとかのメリットはある

   ただし、セキュリティに厳しい会社だとそれができないかも

   zabbixとかも、サポートが手厚い。

   

Q. 外部のメトリクスサービスを使うのではなく、逆に自分たちで作らないといけないときの条件は?

A. KVSとか、高速にクエリを処理したいときとか。

 AirSpace?というKVSと使っているがDatadogとかだと対応していなので

 分析用のシェルを自分でつくって、それをDatadogに投げるとかのことは自分でしないといけない。