勉強日記

チラ裏

Clean Code ch6 Objects and Data Structure

www.oreilly.com


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別々にセットできる
  • 実装を隠蔽するとは、抽象化するということである
    • 関数を噛ませればいいというものではない

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

www.oreilly.com


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
      • 操作により期待通りの結果が得られていることをチェック
  • テストの意図をぼかしてしまうような瑣末な詳細は別の関数に押し込める

Domain-Specific Testing Language

  • build-operate-checkパターンを適用し、詳細を押し込めた関数は、テスト用のDSLになる
  • 前もって用意するというよりは、テストコードをリファクタリングしていく中で育つもの

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値であること
      • 通ったか、落ちたか
    • 通ったかどうかの判定を人間が行うべきではない
      • 主観に影響されてしまう
      • 長時間の手作業を要する
  • 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イベント用)


つくったもの

f:id:wand_ta:20200105170210p:plain

f:id:wand_ta:20200105170154p:plain

モチベーション

  • ゆるい自動進行形RTAイベントの模索
    • 運営の負荷をできるだけ少なくし、気軽に開催できるイベントをつくりたい
  • 「走者が好き勝手に枠を予約する感じの仕組みを作ったら需要があるのではないか」
    • @wak_ky氏, @suzuribox氏発案

成果物

github.com

構成

f:id:wand_ta:20200105170251p:plain

Lambda関数の設計

クラス図

  • DataMapperを格納しているMappersディレクトリは、実際にはDomain,Infrastructureと並列に置いてしまったが、依存の向き的に、図のようにInfrastructureに含めたほうが良さそうだ
  • 予約取得(クエリ)と配信ホスト実行(コマンド)でLambda関数を分けたほうが良かったかも
    • SRP違反
      • Google Calendarに変更があっても、あるいはTwitchに変更があっても、コードに修正が必要になってしまう

学び

意図しなかった学び

  • IRC: Internet Relay Chatプロトコル
    • twitchの/host, /unhostコマンド発行は、当初HTTP POSTか何かで行う想定だった
    • 調べてみると、twitchのチャットはIRCらしいので急遽色々調べて触った
      • そういやchattyはIRCクライアントだった
    • tmi.js -- twtich向けIRCクライアントのJS実装

意識してねじ込んだ学び

  • ユースケース駆動モデリング
  • Serverless Frameworkの復習
  • CI/CDを先に整備してから実装を進めた
    • 何もしない最低限のhandler.tsを起き、先にCDを構築した
  • 見積もり
    • trivate estimates続投
      • 2時間ばかりオーバーしてしまった。まだまだ楽観的すぎる
        • 技術検証と謎のバグ追跡が重かった
      • <1%の悲観的見積もりをもっと極端に盛らないといけない

f:id:wand_ta:20200105170941p:plain

Amazon Prime Videoのごちうさ監視システムをサーバーレスで構築した


つくったもの

f:id:wand_ta:20200103224822p:plain
CloudWatch カスタムメトリクスで、Amazon Prime Videoのごちうさの死活を監視している

github.com

背景

f:id:wand_ta:20200103235642p:plain
この世の終わり

f:id:wand_ta:20200103224640p:plain
2018年12月の様子

  • 1年前(2018年末)に観られなくなったときも、「ごちうさが復活してたらメール通知するプログラム」を書いてローカルPCで動かした
  • 今年はクラウドでリメイクした

去年の

インフラ・仕様

問題点

  • PCの電源が点いていないと動かない
  • ごちうさが視聴可能になったら毎日メールが届いてしまっていた
  • テストを書かなかった

今年の

インフラ・仕様

f:id:wand_ta:20200103230604p:plain
構成

  • AWS LambdaをCloudWatch Eventsで定期実行
  • puppeteer不使用。HTTPレスポンスを単純にパース
  • 死活をCloudWatchのカスタムメトリクスとして書き出す
  • 死活の変化を監視し、アラームを発する
  • アラームでSNSをトリガーし、メールを送信する

f:id:wand_ta:20200104000909p:plain
死活の変化でメール通知

改善点

  • PCの電源が点いていないと動かない
  • ごちうさが視聴可能になったら毎日メールが届いてしまっていた
    • -> 死活の変化を監視するので、通知が飛び続けない
  • テストを書かなかった
    • -> まじめに書きました

その他意識して学びをねじ込んだこと

  • テスタビリティを考慮した設計
    • モジュールのインタフェースと実装の分離
    • DI
      • InversifyJS
  • 見積もり
    • trivariate estimation
      • The Clean Coderに書いてあったやつ
      • Optimistic (<1%), Nominal, Pessinistic(<1%)の3通り見積もって分布を算出するやつ
      • 見積もり7時間に対して実作業時間は7時間10分だった。すごい
  • IaC
    • 初めてCloudFormationを使った
      • 直接は使ってないけど…
      • Serverless Frameworkというのを使った
  • JavaScriptのエコシステム周り
    • tslint初めて使った
    • TypeScriptのコンフィグ少し書いた
      • path aliasとか
        • webpackとTSとjestそれぞれに書かないといけないの何とかならないの

ソフトウェア設計

https://www.plantuml.com/plantuml/png/bLDDQnD16BxlhnXwIj7D3uXbQMYf1Yq4G_KW7YQpasReV2opiuMY7ZOZuj637r1HL7gGWlNWnOF_PWZ-3MUoas6px5eb9EITvtcVUPztdztD5PIgO3H25EOvC8klHlym-gNHbqP_C8kBgeoY3A8JU8p1CCieGL0HmITOdXA4mHFVV5kWEJdAuQ7WH0b9-B65061LkIUumbpbGvwEYoab-VmGAqbGtjkEdjbFk65VC4XuKFLz1n1PaRELuWs098OAUwZ78SCtGI6fKzfiytp7S7ySoN681UKC8kld518AfuGITROtn-W4o_KThdAmHtkeaXoijRS7O2e4nP3VsjJqnhpD89XjslPoUT1xzBWslobVc_ApAL-OyeqfhyQICFo0f5WOVMxqBxFuQK-Fxjzp7M5r8pwJC5UoGAgGxi5uiHQJ8vPH3pVczLZDpnt5w05Mo4ALavaht6blhbXjwu7fHG2nFvWvbtN83kPQEgO2SPpKsL7DuFBYxU_pvwQyNBx_jFpsQhLOR_7XPB9_DvIhtk5u50vg2oolZFwusk5ti_XYj3RwdPl7VRjU012dSTAIy2XgINrioPRzpuymQcIyd_QJ4E01sDhPgVAU95jhAX2n_9yhMgTC6YzN1wijFbtKPfIkkRWj0tRLDK93i85sPgXVzFjFMoTlADRvBUD7xNHdmIUk4Na7XVJzBUBN9d8NyxHWz0y0

  • 推移的な依存や相互依存がなくて、結構キレイなんじゃないでしょうか(自画自賛)
    • 1年間ダラダラ学んできただけのことはある
  • インタフェースにIとかInterfaceとか付けない試みを試してみた
    • Clean Code ch2 -- Meaningful Namesより
    • 利用側はそれがinterfaceなのかclassなのか意識しないのが望ましいという考え
    • 代わりに実装クラス側にImplを付けてみた
      • これはこれでBridge Patternっぽくてヤダ…
  • 言語機構以外のものがどこに位置するかも意識した
    • 例: Prime VideoのURL
      • これはインフラではなくてドメイン知識といって差し支えないかと
  • 今回はContentクラスは単なるデータストアクラスとした
    • content.isAvailable(): boolean とか生やそうかと思ったけどやめた
      • ContentAvailableCheckerをコンストラクタ注入しようと思ったが、InversifyJSでの実現方法がわからず

備忘録

  • なにか思い出したら書く
    • 書くほどのことはなかった気もする

The Clean Coder Appendix A Tooling

www.oreilly.com


Tooling

  • 補助記憶装置がテープドライブだったときの苦労話

Tools

  • ボブおじが現在使用しているモダンなツールの紹介

Source Code Control

  • OSSがいいぞ
    • 開発者による、開発者のためのものだから
  • 高価な「エンタープライズ向け」製品もある
    • 開発者というよりはマネージャ、役員、「ツールグループ」向けに売り出しているよう
    • 目を引く機能めじろおし
    • だが、開発者が本当に必要なものではなかったりする
      • 「速さ」が筆頭

An "Enterprise" Source Control System

Pessimistic versus Optimistic Locking

  • 賢いマージにより悲観ロック時代は終わりを告げた

CVS/SVN

  • CVS
    • 昔のやつ
  • SVN
    • ブランチさえ切らなければ現役で活躍できる

Branching

  • 著者はかつてはブランチ否定派だった
    • SVNユーザなら同意するところ
  • 分散型VCSの登場で様相は完全に一変した

git

  • これからのバージョン管理

IDE/Editor

vi

  • viでガチのコーディングをすることはめっきりなくなった
  • シンプルなテキスト編集には使う

Emacs

  • パワフル
    • 向こう数十年は生き残るだろう
  • とはいえ用途特化のIDEには及ばない
    • コード編集は、汎用テキスト編集ではないのである
  • 90年代はEmacs固執していた
    • 他のものを使うなんて考えられなかった
  • 2000年代にIntelliJに移って以来、(Emacsに)振り返ることはない

Eclipse/IntelliJ

  • IntelliJ
  • Eclipseも似た感じ
  • コード編集特化の機能がすごい
    • リネーム
    • メソッド抽出
    • 継承を集約にほぐす
  • プログラミングはもはや行や文字の編集ではない

TextMate

  • 学習コスト低い、操作が直感的

Issue Tracking

  • いきなりツールを買うのではなく、手を動かすシステムを試してからがいいよ
    • 【補】付箋をペタペタやるカンバンとかのことかな

Bug Counts

  • チームの規模問わず、機能/タスク/バグリストは数十から数百が妥当
    • 数千じゃなくて
  • ツール問わず、issueの数が多いとissue "tracking"じゃなくなるぞ

Continuous Build

  • Jenkinsとか
    • 学習コスト低くて良い
  • 著者が継続的ビルドに求めること: シンプルさ
    • VCSのフックで起動
    • 誰かがコードをチェックしたら常に自動でビルドし、チームにステータスをレポートする
  • ビルドが常に元気に動いていること
    • ビルドが失敗したら緊急事態、すぐ直す
      • 壊れた状態を1日以上放置しない

Unit Testing Tools

  • 言語ごとにいろいろある
  • 満たすべき機能
    1. 速い・実行しやすい
    2. 通った/落ちたの可視化
      • すぐわかる・あいまいでない
      • 自分で2つのファイルを比較しないといけないとかは駄目
    3. 進捗の可視化
      • 途中で止まってしまっていないか確認できること
    4. テストケース間に依存を生じさせない工夫
    5. テストケースが書きやすいこと

Component Testing Tools

  • ビジネス陣やQAチーム自身が彼らの理解できる言葉でテストを記述できるのが望ましい

The Definition of Done

FitNesse

Integration Testing Tools

  • UIが絡む自動テストは壊れやすいことで悪名高い
  • 必要最小限だけ書こう
    • UI自体のテスト
    • ごく少数のE2Eテスト
  • Selenium, Watir

UML/MDA

  • 図からコードを起こそうという試みは歴史的に失敗に終わった
    • 「コードを書くプログラマが不要になるのでは」という期待があった
    • プログラマが書くのはコードではなく、低水準の詳細だったのである
  • UMLを書くのはアーキテクトではなく、プログラマ自身になった

英語

  • 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

www.oreilly.com


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の「複雑性」の定義に合致
      • 認知の負荷

英語

  • disabuse
    • 誤りを気づかせる
  • precedents
    • 先例
  • broad-brush
    • 大まかな
  • as an aside
    • ちなみに
  • pertain
    • に属する
  • the last thing ...
    • 最もしそうにないこと
  • jumble
    • ごちゃまぜ

Clean Code ch2 Meaningful Names (by Tim Ottinger)

www.oreilly.com


Meaningful Names (by Tim Ottinger)

Introduction

  • 名付けがいっぱい
  • なので良い名付けをしたほうがいい

Use Intention-Revealing Names

  • 良い名前を選ぶのには時間がかかるが、将来的にそれ以上の時間が浮く
  • 名前が答えるべきこと
    • なぜそれが存在するか
    • それは何をするか
    • それはどう使われるか
  • コメントが必要な名前は意図を表現できていない
  • 避けるべきもの

Avoid Disinformation

  • accountListとかは良くない
  • accountGroup, bunchOfAccounts, accountsなどがよい
  • スペリングには一貫性を
    • 補完のときうれしい
  • l,Oはやめよう
    • 1l, 0Oは紛らわしい

Make Meaningful Distinctions

  • copy(a1,a2)
    • a1, a2はdisinformativeではないがnoninformative
    • source, 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

  • fetchretrievegetとか混ぜない
  • controllermanagerdriverはどう違うんだ?

Don't Pun

  • ダブルミーニングを避ける
    • 値がなければ生成、あれば追加するaddが既にあったとする
    • コレクションへの要素追加のaddを作らない
      • insertappendといった単語を使おう

Use Solution Domain Names

  • 読み手はプログラマなので、プログラマにわかる解決領域の単語を使おう
  • 解決領域の語彙がすでにあるのに、わざわざ問題領域の語彙を使わない

Use Problem Domain Names

  • 解決領域に適切な単語がなければ、問題領域からとる
    • コードを読む人はドメインエキスパートに確認をとれる
  • 問題領域/解決領域の区別は良いプログラマ/設計者のつとめ
    • コードは、問題領域の概念よりも多くのことに関与することがある
      • 【補】裏でジョブキューが動く、とかかなあ
    • そういったものの名前は問題領域からは線引きして名付ける

Add Meaningful Context

  • それ単体で意味が十分に伝わる名前はあまりない
  • 例: state
    • それ単体で「住所の『州』」だとは伝わらない
  • クラスで包むなどして、コンテキストを与えよう

Don't Add Gratuitous Context

  • 意図が明確に伝わる限り、名前は短いほうが良い
  • アプリケーションのプレフィックスなどを無駄に付けない
    • アプリケーション横断的な再利用性も損なわれる
  • 住所とMACアドレスとWebのアドレスを区別したくなったら?
    • PostalAddress, MAC, URIクラスを作る
      • 無駄にMACAddressとか長くしない

英語

  • entrenched
    • (考え方などが)凝り固まった
  • copious
    • 大量の、おびただしい
  • contrivance
    • 考案、発明
  • imperative
    • ぜひともしなければならない
  • crutch
    • 松葉杖
    • (精神的な)支え
  • colloquialism
    • 口語
  • lexicon
    • 語彙
  • gratuitous
    • 不要な