プログラミングにおける設計の難しさについて考える

前提

この記事における設計は主に以下の4点をイメージして書いています。
(具体的にどうこう、という話は出てきません)

  • REST設計
  • レイヤー設計
    • MVCとかDDDにおけるレイヤーみたいなやつ
  • クラス/インターフェース設計
    • どういう処理/データを持たせるのが適切かとか
  • コード設計
    • for文で書くかeach使うかとかそういう細かい話

目的

  • 設計に悩んだり微妙な設計をすることがあって改善したい
  • 設計に関する本を読んでいる中で、私にとってなぜ設計が難しいのか見えてきたので勢いで書き出す
  • あくまで現時点での私が思う難しさなので、1年後は別の原因で難しさを感じてるかもしれない

設計の何が難しいか

以下の要素により明確な正解がないからではないかと感じています。

  • 選択肢がいくつもある
  • 選択肢が浮かばない
  • 判断基準がいくつもある
  • 捨てる決断が必要なことがある
  • 技術的負債を恐れる

難しい要因1: 選択肢がいくつもある

プログラミング覚え立ての頃は数少ない方法でコードを書きます。

  • (Javaから入ったので)繰り返しといえばfor文を回すだけ
    • whileは無限ループ怖いので理由がない限り書かない
  • 再代入バリバリ
  • メソッド/クラスを分けない
  • クラスの責務を分けない
  • 変数名/メソッド名/クラス名が適当

他人が見れば汚いコードですが、少なくとも書いている本人は設計で迷うことは少なかったはずです。
設計していなかったので。
迷うのはアルゴリズムというか手続き的なところで、単純に「どう書けば仕様を満たすのか」という点でした。

それが経験や学習を経て、色々な方法を学んでいきます。

  • map/filter/reduceなどを覚える
  • 変数は不変を保つ。再代入とか辞めてほしい
    • ifが文ではなく式である言語に喜びを覚える
  • 「このクラス/メソッドの責務って何だ」を考え始める
    • 名前を考えるのに時間を費やす

携わる仕事は大概ありがちなCRUDなので難しいコードを書く事は少ないです。
ただ昔と違い色々な手法を知ってしまったため設計に時間がかかるようになっています。
ちなみにコード寄りの例を出しましたが、コードに限らず設計全般です。

たぶん中途半端に色々知っている状態のため判断に迷っているのだと思います。

難しい要因2: 選択肢が浮かばない

ざくっとした言い方ですが。

  • 経験として何か良くないのは分かる
    • いわゆるコードの臭いとか
    • コードじゃなくても、何となくこの設計イケてないよなあ感
  • けどどうしたら良いかが分からない

これは単純に経験に知識が追いついていないのでしょうね。

難しい要因3: 判断基準がいくつもある

※以下に出している例は例であって、今の現場がそうだということではありません

  • 現メンバーのスキル
    • OOPを知らない/好まないチームでOOPで書くべきか
      • 教える/議論するコストもあるし
  • 今後保守するかもしれない人のスキル
    • xx言語が向いているけど、書ける人が少ないのにxx言語で社内ツール作るべきか
  • 既存コード(アーキテクチャ)との調和
    • xxの方が良い設計なんだけど、そうすると既存の他の部分と統一性がなくなるとか
    • 統一性を重視してそっちに合わせるか、ゼロベースでの最善を取って良い設計にするか
  • 予算
    • カスタマイズしやすいようにオンプレがいいけど予算がとか
  • 人的リソース
    • 単純に人が足りない
  • 時間リソース
    • 単純に時間が足りない
  • タスクの優先度(重要度)
    • 急ぎでやるべきなものは「とりあえず」でやりがち
      • 「あとでやる」はまずやらない
      • やらなくて困らないならそもそも不要だったのではという考えもある
  • 難易度
    • 簡単なものほど飛びつきやすい

難しい要因4: 捨てる決断が必要

上記判断基準と併せて。
多くの場合において捨てる決断が求められます。
上記と重複する部分がありますが、捨てる理由としては主に以下の3つが浮かんでいます。

  • 人が足りない
    • 増やせばいいってものではないですが
  • 時間が足りない
    • さっさとリリースしたいねんという圧力
    • 緊急時の対応
  • 知識/経験が足りない
    • xxがいい気がするけどやったことないから怖いね
      • もしくは時間がかかるね
    • xxという簡単な解決策(手法、ソフトウェア、サービスなど)があるのに知らない

難しい要因5: 技術的負債を恐れる

苦悩の末に決断をしてそれがその時の最適解だったとしても、
時が経ったり新しく入ってきた人からするとそれは技術的負債になり得ます。
自分が関わった部分を指して「これはひどい」とか言われたくなくて、
見えない未来に思いを巡らせてあれこれ悩むのかもしれません。

プロとしてのありかた

こういった難しい要素に対して、私のプロ像はどう振る舞うだろうかというのを考えてみます。

色々なケースで最適解を出す

正解はない(と思う)けど、最適解は必ずある(と思う)。
その場その場で、色々なコストを考慮して最適解を出せる人がプロ。
幅広い知識と多くの経験と理路整然とした思考が必要。

責任を持つ

理想を語るのは簡単です。
理想を振りかざして既存のコードをけなすのは簡単ですし、
自分が高尚に感じるし、責任から逃れられているような感覚になります。
(参画した時点で自分もコードの責任者だと思う)

ですがきっとプロはグチグチ言わない。その方がモテるから。
プロはアウトプットで語る。
変えられるなら変えていくだろうし、
それが出来ないなら「これが今出来る最高の状態」と決断に誇りを持つ。

設計の難しさにどう立ち向かうか

  • チームとしての立ち向かい方
  • 個人としての立ち向かい方

チームとしての立ち向かい方

  • レビューを挟む
    • 自分が見えていない観点で指摘してくれるかもしれない
    • 人に説明することで抜け漏れに気付きやすいかも
  • 議論は前提の認識を明確にしておく
    • お互いが見ているもの、目指しているものが違うと議論もすれ違う
    • 「こっちの方が開発が早い」と「こっちの方が保守性が高い」みたいなことを言い合っても平行線
    • 「急ぎでやる必要あるの?」「一度しか使わない機能で保守性とか必要?」みたいなところから認識合わせるとか

難しい要因のほとんどはチーム内レビューとか相談で解決する気がします。
そのためにチームでもありますし。

ですが、出来ることなら自分一人でも最適解を出せるようにはなりたい。
「最適解の判断に迷う」という相談ではなくて、
「こういう理由でこれが最適解だと判断したのだけどどう思う?」という相談にしたい。

個人としての立ち向かい方

  • 知識を増やす
    • 悩まないという点では知識は少ない方がいいかもしれない
    • でも最適解を出すには知識は必要
  • 経験を増やす
    • 「知っている」と「やったことがある」では全然違う
  • 常に考える
    • 本やネットの知識を鵜呑みにして受け売り野郎にならない
    • 手法やサービスなどについて何がいいのか、何故いいのかを自分の言葉で説明できるようにする

感想

何が難しいと感じているかは分かった気がして書き出してみたけど、
個人については結局勉強しろという当たり前かつ抽象的な結論しか出ていなかった。