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

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

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

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/

TEST Study #2「ソフトウェアテストにおける自動化」に参加してきました

TEST Study #2「ソフトウェアテストにおける自動化」

https://forkwell.connpass.com/event/249851/

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

資料を見ながら口頭で説明していただいた部分のメモ

基調講演「ソフトウェアテスト自動化、一歩前へ」

オープニング
オープニング

ソフトウェアテストの自動化

ソフトウェアテストの自動化は広い意味を持っている
日頃どんな部分で関わっているかで、イメージするものが人によって違う
自分が認識している以外の部分も、色々な側面から見るのが大事

テストは領域に分けられて、自動化が適している領域がある

  • チェックの意味
    • 正しい結果を知っていて、その通りになること
  • テストの意味
    • 想定外のことを発見する

自動化が向いているのはチェック

テストピラミッド

ピラミッドでいうところの領域を確認し、その領域に適したツールで領域を絞ってテストすることで、効率よくテストができる

アイスクリームコーンのテスト

画像

効率が悪いので、なるべく避けるべきだと言われている。

他にもモデルはいくつかある

バグフィルター

画像

網目がバグのありかを表している。
Unit テストは網目が細かいが、まかないきれない範囲がある。
逆に下の層に行くほど、網目が大きいが、範囲が広くなる

学び

Unit テストどうしようか、E2E テストどうしようか。ということを考えてしまいがちだが、

全体を通してどうテストしていくかを考えることも大事。

一歩前に進める現実的なやり方

段階的に進める図
段階的に進める図

理想的には自動化したいが、現実的に整備されてなくて、進められない現実がある。

その場合は段階的に進めていくのが良い、という提案をすることがある。

今ある手動実行前提のテストをそのまま自動化しない

人が読む前提で書かれたケースがあるので、そういうのは機械に解釈させるのが難しい場合がある

視聴者Q&A / パネルトーク

Q1. テスト仕様書のようなものを書いた上でテスコードを書いているのですが、テストコードを書くならテスト仕様をドキュメントとして残すのは無駄に感じてしまいます。

テストコードを書く場合でもテスト仕様書は必要なものなのでしょうか?

A1. テスト仕様書を E2E でやっている前提だと捉えると、一概には言えないが、必要だと思う派。

テスト仕様書を残すと、全体としてどんなテストをしてどんな結果だったかを整理してみたい、という目的があったとして、それをするにはテストコードだけでは難しいところがある。
例えばテストコードが、バグのパターンを正しいと思って書いている場合がある。
そうするとプロダクトオーナーに仕様を聞くことになる。
テスト仕様書を書くとプロダクトオーナーの頭の中にある仕様書を表現することになる。


Q2. エンジニアが頑張りテストを充実化させていくことに限界を感じています。

組織を巻き込んでテストを根付かせる方法論をお聞きしてみたいです。

A2. 後半の組織の話になると、実はそれは私も知りたい。

これをやると組織に根付く、というものはない。
まずは、いま苦労しているものが楽になるイメージを持ってもらって、じゃあどうしようかみたいな建設的な会話ができたりする。
そういうソフトスキル面が大事かもしれない。


Q3. E2Eテストの自動化を一定進めたとして、テストピラミッドの形に移行するためにとるべき重要なアクション紹介いただけますでしょうか?

A3. アイスクリームコーンの上の部分を自動化したとして、その後の話だと思うが、その前提で話すと。

E2EテストでテストがNGだったものを洗い出し、それはE2Eテストじゃないといけないのか?ということを考える。
それはUnitテストだよねとか、見つけていったりする。


Q4. 自動テストが少ない既存のプロダクトに対して、自動テストを増やしていく際の人的リソースの配分におすすめの方法はありますか?

例えば専門のチームを組む(開発チーム全体に知識を共有するのが難しそう) or 既存の開発チームが〇%時間を割く(なかなか進まなさそう)など

A4. 難しい問題だと思います。

質問に答えている様子
質問に答えている様子

日頃自分は専門チームで自動化をするチームを組むことが多い。
テストのノウハウを教えるということはあまりない。
自分たちにテストを依頼する現場は切羽詰まっていることが多い。
なのでノウハウを伝える時間はないことが多い。
専門のチームを組むのが難しい場合があるが、専門者がいると進めやすいなと思うことは多い。
兼任でやると中途半端になることが多い。


Q5. 単体テスト、E2Eテストについてはある程度どういったテストを書けば良いのかはわかりやすいのですが、 結合テストについて、どういったテストケースを書けばいいのか悩んでしまいます

どういったテストケースが向いている、こういった観点で書いていけば良いなどありますでしょうか?

A5. まず結合テストとは?

会社によって結合テストでやっていることがバラバラな状態。
自分の中では、サブシステム間のテストと捉えている。
マイクロサービスなアーキテクチャだと、責務が分離されているので分かりやすいが、
結合テストをやりたい部分で何をテストすべきか?が分かりづらいから結合テストが難しいのだと思う。
テストを書く前にリファクタリングできると良いかもしれない。


Q6.協力会社がテストを書かない、かつ自分のチームにテストを書く文化がない状態で、何から始めるのが良いでしょうか…?

A6. ちゃんと契約書に書くとかになってくるが、この問題がある状態というのが、納品されたものに問題がある状態だと思う。

なので、テストを用意してそれがパスしたものだけ納品する、という形もあるとは思う。(幸せになりづらいが)
協力会社に書いてと言って失敗したことがあって、現状テストできるように設計していないので設計しなおす料金はどうするという話になってしまった。
テストがない状態というのは、テストのメリットを分かっていないのかもしれない。


Q7. 自動化の過渡期について チーム内の単体テストを一部ツールで自動化し始めました。

しかし、そのツールの範囲外の部分は従来通りの手法(Excel)で実施することになってしまい、負担が増えてしまいます。 どんどんツールを使ってもらいたい一方で、負担はあまりかけられない、この過渡期を乗り切るポイントが知りたいです。

A7. 現場を度外視した外側からの意見だけでいうと、ツールに問題があるかもしれない。

ツールを変える選択肢もあるが、現実的に変えられないこともある。
過渡期を超える上で、あとどのくらいで過渡期を超えられるというゴールをチームで持って、そこまで頑張るとかかもしれない。


Q8. 自動化によるコストをどう回収できるか、どう判断したら良いでしょうか?

A8. 開発費を含めた経費を計算することだと思う。

また、インシデントをどう防ぐかという話をすると、コストとかじゃなくてやるしかないという話になる。

クロージング
クロージング

参加して個人的感想

  • テストの自動化は、サービスの規模が大きくなってくると途中からやるのはとても大変なので、最初からある程度設計していたほうが良さそう。
    • そうもいかないのが世の常かもしれないが。。
  • 途中から自動化する際は、最初から全部を理想系にするのではなく、部分的かつ段階的に進めていくのが良いのというのは、テストもそうだし、いろいろなことに当てはまりそう。
  • チェックとテストの意味の違いは、なるほどと思った
    • 言葉の定義がどうというよりは、そういうふうに分けて考えるとイメージしやすいよなと思った。
  • テスト自動化を当たり前のように取り入れている環境もあれば、そうではなくまず受け入れられなけばならない環境もあり、組織や文化も関係している。
  • 経営目線の人にテストについて理解してもらう際は、開発が楽になるという話よりは、コストを減らすことができますという会話のほうが、相手にも理解してもらいやすそう。