Closed24

設計とは何か?

たとえば😄たとえば😄

背景: 「設計」の何が問題か?

  • 「設計」という言葉の意味するところが人によって異なっている印象を受け、混乱する
    • コンセプトと完成品の間にある全ての中間成果物が「設計」の対象になっている
    • ある程度具体的である程度抽象的なものは「設計」の対象、くらいのfuzzyさ
    • すべてが設計の対象である、ならいいのだが
  • 設計者は、何をもってして「設計」が順調に進行していること/完了したことを知るのか、がわからない
    • 永遠に完了しないとしても、十分であることをどのように知るのか?
    • それは「設計」ではなくただの「意図」では?と感じることがある
      • 意図された意図の集合は設計だろうが、意図単体では設計ではないだろうと思う
  • 「設計」の良し悪しの評価/良い「設計」を実践すること、は大した問題ではなく(nice to haveの領域だし、文献を読めばいずれできるようになる)、むしろ「設計」が完遂されている or (完遂しているかに見えて)破綻している/欠落している の評価/「設計」を完遂すること、こそが問題ではないか?
    • 設計の良し悪しと設計の成功失敗が同じようなものとして語られているのが気持ち悪い
  • システム開発/ソフトウェア開発における「設計」の対象と範囲がわからない(しばしば明示されない)
  • 「設計」する主体の具体的なイメージが持てない: 彼彼女はどのような信仰と思想を持っている?
  • うまく「設計」しようとする時、人によって目的/意識してる評価軸 が異なっていそう
    • 任意の目的を考慮した準備程度のことを「設計」と言えてしまうことが問題?

調べる前の仮説: 「設計」とは何っぽいか?

  • 開発 = 設計 or 実装 ?
    • 設計とは、開発における実装以外の全て
    • 設計の目的は、実装を完了できるようにすること
  • 開発 = 設計→実装 ?
    • 設計とは、開発における実装の前段階
    • 設計の目的は、実装を開始できるようにすること
  • 設計 = 決定すべき論点に決定を下すこと ?
    • 決定す「べき」論点(の範囲, 深さ, タイミング etc.) は実装者の事情によって定まる
      • 開発の下流側が、開発の上流側の作業に影響する
        • それゆえの難しさがある
  • 設計 = 1. やることとやらないことを決める + 2. やること(責務)の分担を決める こと ?
      1. やることとやらないことを決める
      • 捨てる
      1. やること(責務)の分担を決める
      • 割り振る
  • 設計 = 1. 目的の設定 2. 目標の設定 3. 目標達成のためのコスト面で最も合理的な施策を列挙 4. 施策群を1つの統一的概念の下に整理 ?
    • いわゆるdesignからの連想
  • 設計 = 目的合理的な意思決定 - 実行
    • いわゆるdesignからの連想
  • 設計はレバレッジが効く、ジワジワずっと効果を発揮する
    • 実行はレバレッジが効かない、行動量に比例する
  • 設計とは課題発生の予防である
    • 発生した課題の解決は実行
  • 設計はしばしば構造的だが、非構造的な設計はありうるのか?
    • 設計を記述する言語は?
たとえば😄たとえば😄

仙塲大也『良いコード/悪いコードで学ぶ設計入門』に曰く:

参照

主張

設計の定義

[[設計]]とは、課題を効率的に解決するしくみづくりのこと

ソフトウェアの設計の定義

ソフトウェアにおける[[設計]]とは、なんらかのソフトウェア品質特性の向上を促進するためのしくみをつくること

示唆

  • 設計は仕組みを作る行為を指す
    • 対象(ソフトウェア)それ自体を作る行為は設計ではない
  • 設計の質は課題解決の効率性を指標とする
たとえば😄たとえば😄

仕組みって何?仕組みでないものを作ること、ある?ソフトウェア開発で作られているもののうち、仕組みでないものは何?ドキュメント?じゃあ仕様書作成は設計ではない?

たとえば😄たとえば😄

課題解決の効率性って何を課題とするかで変わりうるよな、その上にほとんどの課題解決の効率は計測できない、のでこれって結局ソフトウェアの設計の質はコードメトリクスか開発生産性指標か、あるいはビジネス指標で見るしかないみたいな話になりそう、設計はそれほど先行指標として計測しにくいものなのか?

たとえば😄たとえば😄

「ソフトウェア設計とは何か #設計 - Qiita」 に曰く

参照

主張

  • 基本設計と詳細設計を合わせたものが、設計プロセス全体

    • 外部設計/内部設計で分けることもあります

      • 外部仕様を明らかにして文書に落とし込む活動が外部設計

  • 設計とは、ソフトウェアの要求仕様と、実装されるプログラムの間のギャップを埋めるための活動

示唆

  • 設計とは仕様を文書化すること
  • 設計の目的とは、要求仕様書で未決定の事項(残された自由度)を、実装に十分な程度に潰すこと
たとえば😄たとえば😄
  • 仕様が機能するか = 設計が十分になされたかどうかは
    • 実装者が評価する
    • 実装工程にならないと評価できない

ってことか、機能しにくそうだな……

たとえば😄たとえば😄
  • 誰のための、何のための設計か
    • 設計の成果物は仕様書
      • (メモ: xx設計書, xx仕様書, xx定義書 みたいな命名の混乱まじでうざい)
      • 仕様書の役割はセーブポイント
        • 発注者と合意する(合意済みという既成事実を作る)
        • レビューを受ける(レビュー承認されたという既成事実を作る)
        • 思考を外部化する(ここまではfix、とすることで思考のscopeを絞る)
たとえば😄たとえば😄

Robert C. Martin "Clean Architecture"

参照

主張

  • 優れたソフトウェアの設計の目的とは何か?
    それは、私のユートピアの実現にほかならない。
    ソフトウェアアーキテクチャの目的は、求められるシステムを構築・保守するために必要な人材を最小限に抑えることである。
    設計の品質は、顧客のニーズを満たすために必要な労力で計測できる。必要な労力が少なく、システムのライフタイム全体で低く保たれているならば、その設計は優れている。逆に、リリースごとに労力が増えるなら、その設計は優れていない。ね、簡単でしょ。

    • ソフトウェアアーキテクトは、その職務記述からすると、システムの機能よりも構造にフォーカスするものだ。
      アーキテクトは、機能を簡単に開発・変更・拡張できるアーキテクチャを構築するのである。
      アーキテクチャを後回しにすると、システムの開発コストはますます高くなり、システムの一部または全部が変更不能になるだろう。

示唆

  • ソフトウェア開発は上流から下流まで意思決定の連続である
    • 下流に限らず全てが「設計」である
    • アーキテクチャが上流で「設計」が下流なわけではない
  • ソフトウェアには機能の側面と構造の側面がある
    • ソフトウェアの構造的側面をアーキテクチャと呼ぶ
      • アーキテクチャの品質は開発生産性を目的とする
      • アーキテクチャは複雑性/変更容易性を関心とする
たとえば😄たとえば😄

設計の話とずれるが、良いアーキテクチャがあれば長期的に開発が楽ですというのは当然として、1. 良いアーキテクチャを事前に構築することができる 2. 良いアーキテクチャの構築にコストをかけることはペイする のそれぞれが言説としてやや疑わしく感じる 人生に必要なものを前もって知っていれば必ず良い人生になります の類と一緒 前もって知り得ないのでは?知り得たとして、準備できるのか?

たとえば😄たとえば😄
  • 設計は決めること
  • ソフトウェア開発では工程の全てが設計(決めること)である

あたりまえ体操じゃん

たとえば😄たとえば😄

私たちに必要な設計の成果物(仕様書)の形式は

  • どう決まったか(普通の仕様書の中身)
  • なぜそう決めたか
  • 決定は何が起きた場合覆されるか

なんだろうな
全てが(A)DRである、的な

たとえば😄たとえば😄

コミットの総和がコードであるように、コミットログの総和が仕様書である?

たとえば😄たとえば😄

設計を設計していないのに(設計とは何かを決めていないのに、設計の成果物の仕様を決めていないのに)設計したつもりになっていることが怖くないのか?

たとえば😄たとえば😄

オブジェクト指向をやる前に、分析と設計……ってなんだっけ? 分析と設計の違いとは。 #ポエム - Qiita

参照

主張

  • 課題が具体的に何かがわかったところでその課題をどうやって解決するか?を考えます。
    それが「設計」です。

  • せっかく設計を考えたのだから「設計書」を書くのも悪くはありません。
    ただこれは設計したものを書き留めておいたり人が読める形にするのが目的であって設計書を書くこと自体は決して目的ではありません。

示唆

  • ソフトウェアによって解決する課題の特定は、設計ではない
    • 課題の特定と詳細化は「分析」と呼ぶ
  • 課題に対する解決方法の定義と詳細化を、設計と呼ぶ
    • e.g.
      • DB設計
      • システム構成の設計
      • 保守設計
      • 運用設計
      • アーキテクチャ設計
      • 実装設計
      • 実装環境の設計
    • どこまで詳細化するか: 言及なし
    • 設計工程は(設計する工程なのではなく)xxを設計する行為の総和を指す
      • xx(対象)がプロジェクト/プロダクトごとに異なる
  • 設計の中間成果物として設計書があるが、設計の最終成果物ではない
たとえば😄たとえば😄
  • コードを書く実装者が自由に決めて良いこととそうでないことがあり
    • 後者を決めることを分析+設計と呼んでいて
      • 課題の内容を定義することが分析で
      • 解決方法の内容を定義することが設計で
    • 前者を決めることを実装と呼んでいる

っぽい

Q. 実装者が自由に決めて良いこと or そうでないこと は何によって/どのように決まる(知ることができる)んだ?

たとえば😄たとえば😄

「【開発初心者向け】Webアプリケーションの設計手順(企画~テストまで) #開発プロセス - Qiita」

参照

主張

  • 設計フェーズであまり時間を取られないようにしましょう。どれだけ綿密に設計をしても、実装フェーズでしか見えてこない課題が必ず出てきます。そのため、ある程度設計ができたタイミングで実装に入るこれは設計の手を抜くということではなく、時間を有効に使うための立派な戦略です。

  • 一般的にシステム開発・構築では以下の順序で制作が進行していきます。
    要件定義
    設計
    開発
    検査

示唆

  • 工程としては設計→実装の順番ではあるが、学びは実装→設計に反映される
    • 実装段階で考慮していなかった課題が出てきたからといって、設計が不十分なわけではない
    • あるいは: 十分な設計など人間には不可能、設計の十分さを目指すべきではない
たとえば😄たとえば😄
  • プロダクトが探索的である限り、設計と実装は常に反復される
    • 設計と実装の反復はフラクタル構造になっている
      • 優れた設計のためのスモールバッチの実装、スモールバッチの実装のためのスモールバッチの設計……
たとえば😄たとえば😄

友人Aが教えてくれたこと、の示唆

  • 設計: 条件の選択
    • 条件: ソフトウェア開発における支配的な要素
      • <支配的-従属的>のスペクトラム
        • 支配的: 不可逆, 影響範囲が大きい
        • 従属的: 変更容易性が高い, 影響範囲が小さい
        • ある領域で、何が支配的で何が従属的かは、必ずしも事前に全てを知り得ない
    • 選択: 決定
      • 選択の質: 実装の自由度を望ましい方向に/大きく下げるのが良い選択
  • 設計と実装は反復しながら向上する
    • 実装者から見れば、設計は実装の前段階である
      • 設計の役割: 自由度を潰すこと
        • 支配的な要素に関して決定がなされ、残る従属的な要素の決定の自由度が渡されている
    • 設計者から見れば、設計は実装の後段階でもある
      • 実装の役割: リリースして学びを得ること
        • 優れた/現実的な設計を知るためにリリースを経ることもある
    • 開発プロセスは直線的ではない
  • なので「十分な/完了している設計」は存在しない
    • 弁証法における知識の扱いと似ているな
      • 一般に: 知識は真理か否かが重要
      • 弁証法: 知識は真理に近づく道具
たとえば😄たとえば😄

友人Bが教えてくれたこと、の示唆

  • 設計は、事前の決定
    • 何の事前か: 不可逆な意思決定の事前
      • 完全に不可逆な場合もあるし
      • 可逆だが、時間をロスるという意味では取り返しがつかない場合もある
  • 設計は、意思決定のジレンマを長期的に解決する
    • 以下のジレンマが存在する
        1. 意思決定は早ければ早いほど良い/早くなければいけない
        • 自由度/不確実性を大きく下げることができる/下げなければいけないため
        1. 不可逆な意思決定のリスクを軽減するために、意思決定の前にリスク/リターン評価フェーズが欲しい、しかしそのコストが意思決定を遅らせる
        • リスク: 取り返しのつかない事態が起こる, 時間と労力をロスる
        • リスク/リターン評価フェーズ: 「想定」に基づいて要素を洗い出し、リスク/リターンの期待値(程度と確率)を評価する
          • この「想定」が難しい
    • 1と2のジレンマの折衷案的解決が「設計」か?
      • 工程の上流においてできるだけ自由度を下げておく = 設計しておく ことが、以降の工程におけるリスク/リターン評価フェーズのコストを圧縮してくれる
  • 設計はPoNR: Point of No Returnを作ること
    • 何かあったらここに戻ってくる、というセーブポイントを作る
      • だからドキュメンテーションを伴う
たとえば😄たとえば😄

設計とは(暫定解)

  • レバレッジが効く選択をすること
    • レバレッジの効き方
        1. 通時的に見て、影響が強い
        • 不可逆な、取り返しのつかない要素に関する選択
          • 効果: 後続する要素の選択の自由度/不確実性が低下する
        1. 共時的に見て、影響が強い
        • 支配的な要素に関する選択
          • 効果: 従属する要素の選択の自由度/不確実性が低下する
たとえば😄たとえば😄
  • ナンセンスな見方
    • 工程としての定義
      • 設計→実装や設計or実装
    • 媒体に由来する定義
      • コードを書いているのは実装、自然言語と構造は設計
たとえば😄たとえば😄

建築関係の本を読んでいて:

示唆

  • 設計 = 要求を満たすoptimalな解を出すこと
    • ※ソフトウェアと建築の違い
      • ソフトウェアは更新を前提とするが、建築物は必ずしも更新を前提としない
        • 建築において建築物は(大抵)最終成果だが、ソフトウェアにとってプロダクトはあくまでもある時点におけるスナップショットである
          • なので、建築では設計段階で最適解を出すための検討コストをかける(スタディ)合理性が高いが、ソフトウェアでは必ずしもそうする必要がないため、最適解を考え抜くことよりも、いつか最適解を出せる/チームが適応的に振る舞えるようにするための「設計」が好まれる、っぽい
            • ああ、だからか……
      • など
      • ※建築における設計でも、ソフトウェア開発を模した手法は提唱/採用されている
たとえば😄たとえば😄

David Thomas; Andrew Hunt "The Pragmatic Programmer(2nd Edition)"

参照

引用

  • ものごとは、それを使う人に適応できる場合にうまく設計されていると言えます。コードの場合、それは変化に対応できなければならないことを意味しています。このため、我々はETC原則を宿じています——Easier To Change(変更をしやすくする)。これがETC原則です。

示唆

  • 設計の良し悪しの主たる関心はユーザーではなく実装者/設計者の便益の側にある
    • なるほど、だからずっと違和感があったのか……
      • なんでこいつらみんなユーザーに届く価値の話を無視して良い設計が云々って言ってるのだろうと思ってた
    • 設計は企業内/チーム内の課題を解いている/未然に防いでいる
      • 結果、長期では、ユーザーに届く価値も大きくなるはずだ、という前提が置かれている
        • 賛成
このスクラップは2025/01/03にクローズされました