Clean Code ch6 Objects and Data Structure
- Objects and Data Structure
- Data Abstraction
- Data/Obect Anti-Symmetry
- The Law of Demeter
- Data Transfer Objects
- Conclusion
- 英語
Objects and Data Structure
- 脳死getter/setterはpublicメンバと同じようなものだぞという話
Data Abstraction
- 二次元座標上の点
public class Point { public double x; public double y; }
public interface Point { double getX(); double getY(); void setCartesian(double x, double y); double getR(); double getTheta(); void setPolar(double r, double theta); }
- 前者は内部表現を暴露している
- 後者は完全に隠蔽している
- 後者はアクセスポリシーも表現している
- getは別々に呼び出せる
- setは
(x,y)
または(r,θ)
を一度に設定することを強制している- cf. 前者は
x
,y
別々にセットできる
- cf. 前者は
- 実装を隠蔽するとは、抽象化するということである
- 関数を噛ませればいいというものではない
Data/Obect Anti-Symmetry
- オブジェクトとデータ構造との違い
- オブジェクトはデータを抽象化の裏に隠蔽して、それを操作する関数を公開する
- データ構造はデータを公開し、意味のある関数(操作)は持たない
- 「全てはオブジェクト」というのは神話
- OOと手続きは相補的
OO | 手続き | |
---|---|---|
データ構造の追加 | 容易 | 大変 (すべての関数に変更が跳ねる) |
関数の追加 | 大変 (全てのクラスに変更が跳ねる) |
容易 |
- 【補】手続き型の特徴はVisitor Patternと同じ感じ
- 振る舞いの追加は容易だが、クラスの種類の追加が大変になる
The Law of Demeter
- デメテルの法則
- ドットがいっぱいあるのは駄目ってやつ
- 隠蔽されるべき内部表現をほじくってるから
Train Wrecks
final String outputDir = ctxt.getOptions().getScratchDir().getAbsolutePath();
- この手のコードは「列車事故」と呼ばれる
- 列車が連なっているようなさまから
- 分けよう
Options opts = ctxt.getOptions();
File scratchDir = opts.getScratchDir().
final String outputDir = scratchDir.getAbsolutePath();
- 【補】FowlerのRefactoring的には、inline function化して前者へとリファクタリングするのでは?
- これはデメテルの法則違反か?
- オブジェクトであるか、データ構造であるかによる
- オブジェクトなら内部表現の暴露なのでデメテルの法則違反
- 後者にはあてはまらない
- アクセサ関数が混乱の元
final String outputDir = ctxt.options.scratchDir.absolutePath;
- publicメンバアクセスならデメテルの法則違反が疑われることはあるまい
Hybrids
- 半オブジェクト半データ構造のハイブリッド
- 悪いところどりなのでやめよう
- 関数の追加もデータ構造の追加も困難になる
Hiding Structure
- オブジェクトから内部表現を引っこ抜いて仕事するのではなく、オブジェクトに仕事させよう
Data Transfer Objects
- 「データ構造」の典型
- publicメンバをもち、関数を持たないクラス
- DB通信、ソケットからのメッセージのパース等で有用
- 生のデータからオブジェクトを構築する際、変換の最初の段階でよく用いられる
- 【所感】最低限の型を担保するバリデーションのような感じだろうか
- ドメインロジック等は「オブジェクト」に任せる
- 【所感】最低限の型を担保するバリデーションのような感じだろうか
- getterやsetterで包んでも特にメリットはない
- 【補】immutableにしたい場合などはあると思う
Active Record
- DTOの特別なやつ
- save()とかfind()とか生えてる
- DBのテーブルや他のデータソースと、データ構造との直接変換
- このデータ構造にビジネスロジックメソッドを載せて、オブジェクトとして扱おうとする開発者がいる
- 前述の、半オブジェクト半データ構造のハイブリッドになってしまうので良くない
- Active Recordはデータ構造として扱い、ビジネスロジックは別のオブジェクトに持たせよう
- 【所感】それActive RecordじゃなくてRow Data Gatewayだと思います
Conclusion
- 新しい種類のデータを柔軟に追加できるようにしたければ、オブジェクト
- 新しいふるまいを柔軟に追加できるようにしたければ、データ構造と手続き
- 偏見を持たず、その時々で適したものを選ぶことが肝要
英語
- unmistakably
- 間違いなく
- sneer
- あざ笑う
- warrant
- 正当化する
- diametrically opposed
- 全く正反対で
- dichotomy
- 二分法
- innards
- 内部、はらわた
- quintessential
- 典型的な
- = typical
- 典型的な
Clean Code ch9 Unit Tests
- Unit Tests
- The Three Laws of TDD
- Keeping Tests Clean
- Clean Tests
- One Assert per Test
- Single Concept per Test
- F.I.R.S.T.
- 英語
Unit Tests
- 昔は「単体テストコード」は書き捨てのものだった
- 今では、テストコードは実装と同じバージョン管理下におかれ、他の人も実行できるように
- 多くのプログラマが自動化単体テストを取り入れるようになった
- が、「良いテストを書く」という観点を見逃しがち
The Three Laws of TDD
- 「テストを最初に書く」というのは氷山の一角
- 三原則
- これらを守ると、30秒そこらのサイクルを回すことになる
- テストとプロダクションコードは一緒に書かれる
- テストが数秒先行するけど
- 日に数十、月に数百、年に数千ものテストを書くことになる
- プロダクションコードに匹敵する物量になる
- ここにおいて、テストコードの管理の問題が生じてくる
Keeping Tests Clean
- プロダクションコードと同様に重要
- 二級市民ではない
- ちゃんと考え、設計し、大事に扱うべきもの
- 汚いテストコードは、テストコードが無いよりも悪いまである
- 新しいテストを追加するのが困難
- プロダクションコードに変更を加えて、既存のテストが落ちたとき、再び通すのが困難
- 結局捨てられたりする
Tests Enable the -ilities
- テストはプロダクションコードに柔軟性・保守性・再利用性をもたらす
- テストが無いと変更には恐怖がつきまとう
- どんなにアーキテクチャが優れていようが、どんなに良く設計してモジュールを分割していようが、変更がバグを埋め込んでいない保証がない
- テストがあると、この恐怖はほとんど無くなる
- カバレッジが高いほど恐怖は少なくなる
- 設計の改善などを恐れることなく行える
- テストが汚いと、この柔軟性等が失われる
- 【補】気軽にテストを追加できない・落ちたテストを再度通せないから
- テストが汚いとプロダクションコードも汚くなる
- しまいにはテストを失い、プロダクションコードは腐っていくことになる
Clean Tests
- 1に可読性、2に可読性、3に可読性
- プロダクションコードにおけるそれよりも重要
- 可読性を高めるには
- 明確さ
- 単純さ
- 表現の密度
- 少ない表現で多くを言いたい
- build-operate-check パターンでテストの構造を明瞭にする
- build
- テストデータの構築
- 【補】モックの準備とかもここ
- テストデータの構築
- operate
- テストデータに対して操作を行う
- check
- 操作により期待通りの結果が得られていることをチェック
- build
- テストの意図をぼかしてしまうような瑣末な詳細は別の関数に押し込める
Domain-Specific Testing Language
A Dual Standard
- テストはプロダクションコードと同様に大事に扱うべきだが、異なる部分も存在する
- 「きれいに保つべき」という点は共通
- 効率面の要求は異なる
- テストコードはプロダクションコードほど高効率である必要はない
- 効率と引き換えに可読性の高いDSLをつくるという選択
One Assert per Test
- 厳守となると辛い
- テストコードが重複してしまう
- まとめるには?
- Template Method Pattern?
@before
とか使う?
- やりすぎでは
- ボブおじ見解: 1つのテスト中のアサートの数は最小限にとどめるべきだが、1つにこだわる必要もない
Single Concept per Test
- 1つのコンセプトあたりのアサート数は最小限に
- 1つのテスト関数あたり1つのコンセプト
- 【所感】dockerコンテナのベストプラクティス「1コンテナ=1関心事」に似てますね
- 1関心事は1プロセスとは限らない
F.I.R.S.T.
- F: Fast
- テストは高速であるべき
- テストが遅いと、こまめに実行しなくなる
- こまめに実行しないと、問題の発見が遅れて、簡単に修正できなくなる
- I: Independent
- テストケース間に依存関係があるべきではない
- 依存関係があると、1つコケると後続もコケて、診断が難しくなる
- R: Repeatable
- 任意の環境で反復可能であること
- 商用環境
- QA環境
- 手元のラップトップ(オフライン)
- さもないと
- テストが落ちたとき言い訳するようになる
- 「テスト用特定の環境」が利用不可能になるとテストを実行できない
- 任意の環境で反復可能であること
- S: Self-Validating
- 結果は2値であること
- 通ったか、落ちたか
- 通ったかどうかの判定を人間が行うべきではない
- 主観に影響されてしまう
- 長時間の手作業を要する
- 結果は2値であること
- T: Timely
- プロダクションコードを実装する直前に書く
- 後から書こうとすると、コードがテスト困難なつくりだったりする
英語
- concoct
- 混ぜて作る
- でっち上げる
- cobble
- つぎはぎして雑に作り上げる
- come a long way
- ずっと進歩する
- nook
- 隅
- cranny -隙間
- join the ranks of
- 仲間入りする
- watchword
- 合言葉
- impunity
- とがめなく、無事に
- hamper
- 妨げる
- inundate
- 押し寄せる
- 氾濫する
- draconian
- 極めて厳しい in a timely fashion
- タイミングよく
twitchの配信ホスト予約システムを作った (ゆるいRTAイベント用)
つくったもの
- Google Calendarに配信ホスト予約を登録しておくと、ホスト用チャンネルが自動ホストしてくれるサービス
モチベーション
- ゆるい自動進行形RTAイベントの模索
- 運営の負荷をできるだけ少なくし、気軽に開催できるイベントをつくりたい
- 「走者が好き勝手に枠を予約する感じの仕組みを作ったら需要があるのではないか」
- @wak_ky氏, @suzuribox氏発案
成果物
構成
Lambda関数の設計
- DataMapperを格納しているMappersディレクトリは、実際にはDomain,Infrastructureと並列に置いてしまったが、依存の向き的に、図のようにInfrastructureに含めたほうが良さそうだ
- 予約取得(クエリ)と配信ホスト実行(コマンド)でLambda関数を分けたほうが良かったかも
- SRP違反
- Google Calendarに変更があっても、あるいはTwitchに変更があっても、コードに修正が必要になってしまう
- SRP違反
学び
意図しなかった学び
- IRC: Internet Relay Chatプロトコル
- twitchの
/host
,/unhost
コマンド発行は、当初HTTP POSTか何かで行う想定だった - 調べてみると、twitchのチャットはIRCらしいので急遽色々調べて触った
- そういやchattyはIRCクライアントだった
- tmi.js -- twtich向けIRCクライアントのJS実装
- twitchの
意識してねじ込んだ学び
- ユースケース駆動モデリング
- Serverless Frameworkの復習
- Prime Videoごちうさ監視システムで使ったので反復練習
- CI/CDを先に整備してから実装を進めた
- 何もしない最低限のhandler.tsを起き、先にCDを構築した
- 見積もり
- trivate estimates続投
- 2時間ばかりオーバーしてしまった。まだまだ楽観的すぎる
- 技術検証と謎のバグ追跡が重かった
- <1%の悲観的見積もりをもっと極端に盛らないといけない
- 2時間ばかりオーバーしてしまった。まだまだ楽観的すぎる
- trivate estimates続投
Amazon Prime Videoのごちうさ監視システムをサーバーレスで構築した
つくったもの
背景
- Amazon Prime Videoでは毎年定期的にごちうさが観られなくなる
去年の
インフラ・仕様
問題点
- PCの電源が点いていないと動かない
- ごちうさが視聴可能になったら毎日メールが届いてしまっていた
- テストを書かなかった
今年の
インフラ・仕様
- AWS LambdaをCloudWatch Eventsで定期実行
- puppeteer不使用。HTTPレスポンスを単純にパース
- 死活をCloudWatchのカスタムメトリクスとして書き出す
- 死活の変化を監視し、アラームを発する
- アラームでSNSをトリガーし、メールを送信する
改善点
- PCの電源が点いていないと動かない
- -> クラウドで常に動いている!
- ごちうさが視聴可能になったら毎日メールが届いてしまっていた
- -> 死活の変化を監視するので、通知が飛び続けない
- テストを書かなかった
- -> まじめに書きました
その他意識して学びをねじ込んだこと
- テスタビリティを考慮した設計
- モジュールのインタフェースと実装の分離
- DI
- InversifyJS
- 見積もり
- trivariate estimation
- The Clean Coderに書いてあったやつ
- Optimistic (<1%), Nominal, Pessinistic(<1%)の3通り見積もって分布を算出するやつ
- 見積もり7時間に対して実作業時間は7時間10分だった。すごい
- trivariate estimation
- IaC
- 初めてCloudFormationを使った
- 直接は使ってないけど…
- Serverless Frameworkというのを使った
- 初めてCloudFormationを使った
- JavaScriptのエコシステム周り
- tslint初めて使った
- TypeScriptのコンフィグ少し書いた
- path aliasとか
- webpackとTSとjestそれぞれに書かないといけないの何とかならないの
- path aliasとか
ソフトウェア設計
- 推移的な依存や相互依存がなくて、結構キレイなんじゃないでしょうか(自画自賛)
- 1年間ダラダラ学んできただけのことはある
- インタフェースに
I
とかInterface
とか付けない試みを試してみた- Clean Code ch2 -- Meaningful Namesより
- 利用側はそれがinterfaceなのかclassなのか意識しないのが望ましいという考え
- 代わりに実装クラス側に
Impl
を付けてみた- これはこれでBridge Patternっぽくてヤダ…
- 言語機構以外のものがどこに位置するかも意識した
- 例: Prime VideoのURL
- これはインフラではなくてドメイン知識といって差し支えないかと
- 例: Prime VideoのURL
- 今回は
Content
クラスは単なるデータストアクラスとしたcontent.isAvailable(): boolean
とか生やそうかと思ったけどやめたContent
にAvailableChecker
をコンストラクタ注入しようと思ったが、InversifyJSでの実現方法がわからず
備忘録
- なにか思い出したら書く
- 書くほどのことはなかった気もする
The Clean Coder Appendix A Tooling
- Tooling
- Tools
- Source Code Control
- IDE/Editor
- Issue Tracking
- Continuous Build
- Unit Testing Tools
- Component Testing Tools
- Integration Testing Tools
- UML/MDA
- 英語
Tooling
- 補助記憶装置がテープドライブだったときの苦労話
Tools
- ボブおじが現在使用しているモダンなツールの紹介
Source Code Control
- OSSがいいぞ
- 開発者による、開発者のためのものだから
- 高価な「エンタープライズ向け」製品もある
- 開発者というよりはマネージャ、役員、「ツールグループ」向けに売り出しているよう
- 目を引く機能めじろおし
- だが、開発者が本当に必要なものではなかったりする
- 「速さ」が筆頭
An "Enterprise" Source Control System
Pessimistic versus Optimistic Locking
- 賢いマージにより悲観ロック時代は終わりを告げた
CVS/SVN
Branching
git
- これからのバージョン管理
IDE/Editor
vi
- viでガチのコーディングをすることはめっきりなくなった
- シンプルなテキスト編集には使う
Emacs
- パワフル
- 向こう数十年は生き残るだろう
- とはいえ用途特化のIDEには及ばない
- コード編集は、汎用テキスト編集ではないのである
- 90年代はEmacsに固執していた
- 他のものを使うなんて考えられなかった
- 2000年代にIntelliJに移って以来、(Emacsに)振り返ることはない
Eclipse/IntelliJ
TextMate
- 学習コスト低い、操作が直感的
Issue Tracking
- いきなりツールを買うのではなく、手を動かすシステムを試してからがいいよ
- 【補】付箋をペタペタやるカンバンとかのことかな
Bug Counts
- チームの規模問わず、機能/タスク/バグリストは数十から数百が妥当
- 数千じゃなくて
- ツール問わず、issueの数が多いとissue "tracking"じゃなくなるぞ
- 追跡不能
- issue dump
Continuous Build
- Jenkinsとか
- 学習コスト低くて良い
- 著者が継続的ビルドに求めること: シンプルさ
- VCSのフックで起動
- 誰かがコードをチェックしたら常に自動でビルドし、チームにステータスをレポートする
- ビルドが常に元気に動いていること
- ビルドが失敗したら緊急事態、すぐ直す
- 壊れた状態を1日以上放置しない
- ビルドが失敗したら緊急事態、すぐ直す
Unit Testing Tools
- 言語ごとにいろいろある
- 満たすべき機能
- 速い・実行しやすい
- 通った/落ちたの可視化
- すぐわかる・あいまいでない
- 自分で2つのファイルを比較しないといけないとかは駄目
- 進捗の可視化
- 途中で止まってしまっていないか確認できること
- テストケース間に依存を生じさせない工夫
- 別々のインスタンスで実行する
- ランダム順番で実行する
- テストケースが書きやすいこと
Component Testing Tools
- ビジネス陣やQAチーム自身が彼らの理解できる言葉でテストを記述できるのが望ましい
The Definition of Done
- 仕事の「完了」の定義
- 「全てのコンポーネントテストが通りました」
FitNesse
Integration Testing Tools
UML/MDA
英語
- judiciously
- 賢明に
- be conversant with
- ...に精通している、明るい
- a small fortune
- 大金
- My condolences.
- お悔やみ申し上げます。
- long in the tooth
- 年老いた、古い
- 歯茎が後退して、歯が長く見えることから
- 年老いた、古い
- austere
- 厳しい
- mind-bender
- びっくりさせるもの
- resurgence
- 復興
- onerous
- わずらわしい
- 「チェックインする前に毎回数十分かけてテストする」とか
- わずらわしい
- ilk
- 同類
- heady
- 性急な、せっかちな
- abject
- みじめな
- rubout
- すり消す
- ASCIIの0x7F(DEL)とか
- すり消す
- forlorn
- 孤独な、しょんぼりした、わびしい
- menagerie
- 見世物
- 雑多な集合体
Clean Code ch5 Formatting
Formatting
The Purpose of Formatting
- コードフォーマッティングは(読み手との)コミュニケーション
- コミュニケーションがプロ開発者の第一級任務
- 「動かすのが最優先」というのは大間違い
- 今日実装する機能は、次のリリース時の変更箇所になるかもしれない
- 可読性が響く
- 書いたコード自体が新陳代謝で無くなっても、スタイルや規律は残る
Vertical Formatting
- ファイルの長さ
- 短いほうが理解しやすい
- 有名なプロジェクトで統計を取ると、だいたい200行くらい
- 多くて500行くらい
The Newspaper Metaphor
- よくできた新聞のようなソースコードを目指す
- 上の方だけ見て、読むべき記事かどうか判断できる
- ソースコードで言うと
- 説明的な名前がついている
- 一番上の部分を読めば、高水準の概念やアルゴリズムがわかる
- 下の方へ読み進めるにつれ、低水準の詳細がわかる
- 新聞は小さな記事で構成させているから読める
- 巨大な一枚岩だったら読めない
Vertical Openness Between Concepts
- 異なる概念の間には空行を空けよう
- import
- クラス定義
- 関数定義
Vertical Density
- 概念的に近いものは空行を空けずに詰める
- 関連深いインタンスメンバ変数とか
Vertical Distance
- 概念的に近いものは上下近くに置きたい
- 別ファイルだと明らかに無理
- protectedメンバ変数を避けるべき理由の一つ
- 別ファイルだと明らかに無理
Variable Declarations
- 変数宣言はなるべく利用箇所の近くで
Instance Variables
- これはクラス宣言の上部で行え
- 設計がまともならクラス中のあちこちで利用されるので、「利用箇所の近く」というのがない
- C++は最下部だったりする
- scissors rule
- よく知られた一箇所にまとまっていることが肝要
Dependent Functions
- メソッドがメソッドを呼び出す場合...
- 上のメソッドが下のものを呼ぶように置く
- なるべく近くに置く
- 上から下の方向に自然に読めるようになる
- 【補】下に読み進めるにつれ、低水準の詳細になっていく
- Newspaper Metaphorに従っている
Conceptual Affinity
- 同名のオーバライド関数とかは近くに置こう
- 互いに呼び出すか否かなどは二の次
- 同じ名前で同じことをするので近くに置く
Vertical Ordering
- 呼び出し先関数は呼び出し元よりも下にいてほしい
- 上から下に読みたいから
Horizontal Formatting
- 行は短いほうがよい
- 有名なプロジェクトで統計を取ると、長い行の出現頻度は指数関数的に減っていく
- モニタも大きくなってきているし一概には言えないが、ボブおじ的には120文字くらいが限度
Horizontal Openness and Density
- 結びつきの弱いものはスペースで区切る
- 結びつきの強いものは区切らない
return b*b - 4*a*c;
Horizontal Alignment
private int width; private int height protected Color backgroundColor; ... width = 10; height = 20; backgrounColor = Color.fromRGB(255, 0, 0);
- このテのフォーマッティング
- 著者は昔取り入れていたが、やめた
- 意図がぼける
- 代入が見えなくなる
- 右辺を一覧したいわけではない
- 自動フォーマッティングで消えてしまう
- 揃っていないのが悪なのではなく、揃えたくなるくらい変数宣言リストが長すぎるのが悪
- 分割して短くすべき
- 意図がぼける
Indentation
- (当然すぎるので省略)
- 「1行だから改行・インデントいらないや」は結局あとで直すことになるのでやめとけ
- 【所感】自動フォーマッティングに委ねるべきでは
Dummy Scopes
while (dis.read(buf, 0, readBufferSize) != -1);
- やめよう
- 末尾の
;
に騙される
- 末尾の
Team Rules
- たとえ気に入らなくてもチームのルールに従え
- 最も避けるべきは、個々人のスタイルのごちゃまぜでコードが複雑化すること
- 【補】APoSDの「複雑性」の定義に合致
- 認知の負荷
- 【補】APoSDの「複雑性」の定義に合致
英語
- disabuse
- 誤りを気づかせる
- precedents
- 先例
- broad-brush
- 大まかな
- as an aside
- ちなみに
- pertain
- に属する
- the last thing ...
- 最もしそうにないこと
- jumble
- ごちゃまぜ
Clean Code ch2 Meaningful Names (by Tim Ottinger)
- Meaningful Names (by Tim Ottinger)
- Introduction
- Use Intention-Revealing Names
- Avoid Disinformation
- Make Meaningful Distinctions
- Use Pronounceable Names
- Use Searchable Names
- Avoid Encodings
- Avoid Mental Mapping
- Class Names
- Method Names
- Don't Be Cute
- Pick One Word per Concept
- Don't Pun
- Use Solution Domain Names
- Use Problem Domain Names
- Add Meaningful Context
- Don't Add Gratuitous Context
- 英語
Meaningful Names (by Tim Ottinger)
Introduction
- 名付けがいっぱい
- なので良い名付けをしたほうがいい
Use Intention-Revealing Names
- 良い名前を選ぶのには時間がかかるが、将来的にそれ以上の時間が浮く
- 名前が答えるべきこと
- なぜそれが存在するか
- それは何をするか
- それはどう使われるか
- コメントが必要な名前は意図を表現できていない
- 避けるべきもの
- 意味のない名前
theList: List<int[]>
- マジックナンバー
- 意味のない名前
Avoid Disinformation
accountList
とかは良くないaccountGroup
,bunchOfAccounts
,accounts
などがよい- スペリングには一貫性を
- 補完のときうれしい
l
,O
はやめよう1
とl
,0
とO
は紛らわしい
Make Meaningful Distinctions
copy(a1,a2)
a1
,a2
はdisinformativeではないがnoninformativesource
,destination
がよい
- ノイズとなる単語を避ける
- data, info
- a, an, the
- 「a/anは局所変数、theは引数」といった取り決めがあるならよい
- 名前被りを避けるためだけに導入するのはNG
nameString
とかもNG- stringじゃないわけないだろ
Use Pronounceable Names
- 人類の脳は話し言葉をうまく処理するように進化してきたので
- 発音できないと、コードに関する会話がまともにできない
Use Searchable Names
- 1文字変数やマジックナンバーは検索性が悪い
- 例外: ごく短いメソッドのループ変数とかは1文字変数でもいい
- 名前の長さはスコープの広さに対応する
Avoid Encodings
- 読むとき「解読」が必要で、精神的な負荷になる
- 発音できないことが多い
- タイプミスしがち
Hungarian Notation
- 昔は必要に迫られたこともあった
- モダンな言語では不要
- リッチな型システム
- コンパイラの型チェック
- 単なる開発の妨げ
- 名前や型を変えるのが面倒
- 片方変え忘れたりする
- 読むのがしんどい
- 名前や型を変えるのが面倒
Member Prefixes
- メンバに
m_
とかつけるやつ - いらない
- いらないくらい、クラスや関数を小さくすべき
Interfaces and Implementations
- 例えば、
Shape
のAbstract Factoryを作るとき class ShapeFactory implements IShapeFactory
は良くない- 利用者はそれがインタフェースであることを意識すべきでない
- 名前をエンコードするにしても
class ShapeFactoryImp implements ShapeFactory
のほうがよい
Avoid Mental Mapping
- 読み手は名前を脳内で変換すべきではない
- 【補】「要するにあれのことか」
- 問題領域/解決領域いずれの語彙も使用していないとおこる
Class Names
- 名詞か名詞句にせよ
Customer
,AddressParser
- 動詞はNG
Manager
,Processor
- 無意味な名詞もNG
Info
,Data
Method Names
- 動詞か動詞句
- アクセサ、ミューテタ、述語はget,set,isプレフィックス
- コンストラクタをオーバーロードするときは、引数名に基づいてstaticなファクトリメソッドを生やそう
- コンストラクタをprivateにすることも検討せよ
Don't Be Cute
- ネタが分からないと理解できない名前を使わない
DeleteItems
の意味でHolyHandGrenade
とかはNG
Pick One Word per Concept
fetch
とretrieve
とget
とか混ぜないcontroller
とmanager
とdriver
はどう違うんだ?
Don't Pun
- ダブルミーニングを避ける
- 例
- 値がなければ生成、あれば追加する
add
が既にあったとする - コレクションへの要素追加の
add
を作らないinsert
やappend
といった単語を使おう
- 値がなければ生成、あれば追加する
Use Solution Domain Names
Use Problem Domain Names
- 解決領域に適切な単語がなければ、問題領域からとる
- コードを読む人はドメインエキスパートに確認をとれる
- 問題領域/解決領域の区別は良いプログラマ/設計者のつとめ
- コードは、問題領域の概念よりも多くのことに関与することがある
- 【補】裏でジョブキューが動く、とかかなあ
- そういったものの名前は問題領域からは線引きして名付ける
- コードは、問題領域の概念よりも多くのことに関与することがある
Add Meaningful Context
- それ単体で意味が十分に伝わる名前はあまりない
- 例:
state
- それ単体で「住所の『州』」だとは伝わらない
- クラスで包むなどして、コンテキストを与えよう
Don't Add Gratuitous Context
- 意図が明確に伝わる限り、名前は短いほうが良い
- アプリケーションのプレフィックスなどを無駄に付けない
- アプリケーション横断的な再利用性も損なわれる
- 住所とMACアドレスとWebのアドレスを区別したくなったら?
英語
- entrenched
- (考え方などが)凝り固まった
- copious
- 大量の、おびただしい
- contrivance
- 考案、発明
- imperative
- ぜひともしなければならない
- crutch
- 松葉杖
- (精神的な)支え
- colloquialism
- 口語
- lexicon
- 語彙
- gratuitous
- 不要な