2024/07/15 動かない設計と動くナイーブなプログラムの間の埋め方
設計とプログラムの間
抽象的思考
例:Positionを指定することで、Board上のPuttable EmptyにStoneをPutすることができる
クラス・関数の設計
擬似コードを使って行うと洗い出しが上手く行く印象t6o_o6t.icon 例:empty.put(stone)
ここで記述したコードが、直接プログラムとして動作するわけではない
インターフェースを決めるとき、自動テストまで記載する
自動テストによってその先の実装がインターフェースを満足していることを保証する
↑ ここまでは全体的な見方をする
↓ ここからは必ず単一のモジュールだけを見る
動作するプログラムの実装
他クラスに何らかのメソッドを追加したくなったとき
1. メソッドのインターフェースを定義する
Pythonの場合はdef name(arg: ArgType) -> ReturnTypeなどだけ書いておく
def plus(a: int, b: int) -> int
2. 自動テストを記述する
なるべく実装中のクラスに必要な正常系のみを定義しておく
3. 実装中のクラスに戻る
追加先のメソッドは実装しない
動作検証は自動テストのみで行う
スタブを使用しない手動テストを行おうとすると、依存先を実装せざるを得なくなってコンテキストスイッチが起こるため
疑問点
スタブは最終的に他のクラスに置き替える?
スタブで実装した場合、依存先のクラスのインターフェースを完全に満足するようなスタブを作らなければならない
もしインターフェースを満足していなかった場合..
テスト対象のメソッドAの実装の中で、依存先メソッドBを呼び出すようになった時、メソッドB用のスタブを実装しなければならなくなる
外部に対する相互作用を保証したい
外部 = 他クラスとしてよい?
答えが見つからないので、単体テストの書籍などを探したいt6o_o6t.icon
Gitコミットを分けるというのもコンテキストスイッチになるのではないか
初めにコミット内容を考えて作業する?
動かない美麗な設計
大枠を把握するのには有効t6o_o6t.icon
クラス図や日本語を使って表現する
複数の概念を同時に扱いすぎると一種の認知限界に陥るのではないか 扱っている概念数が閾値を超えたとき、
自らが表現しようとしている概念を、既定の数の概念だけで表現できるように試行すると良いのではないか
たとえば既定の概念数を3つとして、Twitterから最新のツイートをJSONに出力するプログラムを考える
「Twitterから」
Twitter APIを
requestsモジュールで
GET
「最新のツイート」
...
「JSONに出力」
設計をプログラムに起こしていく段階がある
このとき、言語の文法などの制約によって、設計を自然にプログラミングすることが難しいことがある
設計の段階で、プログラムをどうするかある程度考える?
初めにプログラムを試し書きしてから設計を行う
このほうが自然ではないか
ある程度の設計は事前に必要である
コンピュータを操作する考え方ではナイーブなプログラムが出力される
これはドメイン言語を中心として構築されるプログラムとは書き進め方が大きく異なる
設計 → プログラム → 設計 ...
設計が100%終わってからプログラムに取り組めば、プログラムもスムーズに100%完了するというのは理想論ではないか
設計とプログラムの間を行ったり来たりしてインクリメンタルに改善していく方が良いのではないか
ナイーブなプログラムをドメイン言語の集積としてラッピングしていく
プログラムと設計の切り替えをするタイミング
扱っている概念やクラスが4個を超えたとき
切り替え時に自動テストを書けるか考えてみる
自動テストを書けるならインターフェースが明確
書けないならその時点で明確にしておく
自動テストが書けない状態で設計を続けると扱いきれなくなる
ボトムアップとトップダウンという話に落ち着きそう
t6o_o6t.icon
設計はトップダウンで行う
設計に擬似的なコードを用いてもよい
認知限界を超えたと感じるタイミングで任意のブロックの実装に移る
コーティングはボトムアップで行う
注意点として、必ず先に自動テストを作ること
ボトムアップで作る場合、書いたコードと本質的な機能の間に距離がある場合があるため
これが原因で、自分が何のコードを書いているのかが分からなくなる
自分のコードが正しいかどうかの判断基準が持てなくなる
自分が書くコードに
複数のクラスを行き来しない
1. ドメイン言語による要件を定義
2. クラスを定義
トラブルシューティング
書こうと思ったが、上手く書けない
書けないと判断した場合、行った設計を技術的・能力的な制約で表現できないと考える
技術的な制約の例
オセロ盤面の高速化したいため、