cover|150

  • 1部 ✅ 2025-02-15
  • 2部 ✅ 2025-02-15
  • 3部
  • 4部 ✅ 2025-08-27

Highlight

ロバストとは?

  • 屈強であること
  • システムが「時の試練」に耐えられるようにする コレクション
  • 用途に合ったコレクション型を使う
  • Counter型
  • メンテナがコードを見たときに動きに驚かないようにする
  • 必然的な複雑性と偶発的な複雑性がある
    • ディープラーニングのコードは必然的に複雑
    • 無駄なif文は偶発的に複雑 ダックタイピング
  • アヒルのように鳴くなら、それはアヒルである というやつ
  • 例えばIterableなど
  • 例えば+演算子など
  • コンポーネント性が上がるのでロバストにはなるが、変更の際に呼び出し元全て問題ないかチェックする必要があり諸刃の剣

型制約

  • Optional
    • Union[str, None]と同じ
  • Literal
    • Enumのように使える
  • NewType(str)
    • サブクラスみたいにできる

ユーザー定義型

  • TypedDict
    • 複数の型が入り組んだDictに使う
  • UserDict, UserList
    • Dictをオーバーライドして使いたいとき
    • 例えば削除できなくするとか
    • 継承させるとパフォーマンスのために一部インライン定義されている関数を上書きできないことがあるので、UserDictを使うのが無難
  • dataclass vs
    • TypedDict
      • 基本dataclassを使う
      • 既にDictのものを型付けしたいときや、jsonを扱うときはTypedDict
    • named tuple
      • これも基本dataclass
      • Python3.6までの互換を保ちたいときだけ使う
  • Class, 不変条件
    • コメント良すぎる、これは仕様書
    • 不変条件のビジネル上の理由を書くのが良い
  • protectedは「_」 privateは「__」をプロパティ名に付ける
    • privateは名前マングリングという内部処理が行われて、明示的に変換後の名前を指定しないとには呼び出せなくなる
  • 部分型
    • リスコフの置換原則(LSP)
      • 子インターフェイスは親インターフェイスをすべて含む
      • 引数チェックや親クラスの不変式を変えたりしているとLSPが壊れている予兆
    • プロトコル vs 継承
      • 大前提、どちらもis-a関係
      • 特定のメソッドを持っていることを制限したいだけならプロトコルでいい
      • 振る舞いや特定条件下での操作方法なども制限したいならより強い関係の継承を使う
  • Pydantic
    • yaml等からの読み込みに使う
    • バリデーションではなくパース
      • 出ていくデータが正しいことを保証する
    • zodみたいなことしたいなら良さそう
  • OCP
    • 開放閉鎖の原則
    • 拡張には開放的、変更に対しては閉鎖的
    • 通知の設定
      • 直接通知するんじゃなくて、通知オブジェクトに対して通知を行うと変更対象は通知オブジェクトだけになる
      • ダックタイピングが助けになる

プラガブルにする

  • Template Methodパターン
    • インターフェイスを満たす関数を渡す
  • Strategyパターン
  • Stevedoreでシステム全体をプラガブルにする
    • これDIツールなんかなあ?
    • パッケージも別れるっぽい エラーをシフトレフトする
  • エラーは発見が遅れるほどコストがかかる
  • 本番環境に入る前に気づけると、緊急リリースのコストがなくなる

テスト