The King's Museum

ソフトウェアエンジニアのブログ。

リファクタリング【第2版】- 第4章:テストの構築

第4章はテストの話。

リファクタリングにテストは必須。ここでいうテストとはいわゆる単体テスト。 リファクタリングは外部からの振る舞いを変えずに内部構造を変えること。 だから常に単体テストを実行して、外部からの振る舞いが変わってないことを確認しながら作業する。

自分が単体テストに入門した著書はこれ。読んだのはもう10年近く前かも。

Pragmatic Unit Testing In Java With Junit

Pragmatic Unit Testing In Java With Junit

たまに「あえてロジックを変えてテストが失敗することを確認する」など、この本と共通する話が多かったな。 そこらへんは今でもちゃんと実践できている気がする。

単体テストはうまくかけばあまり変更することもないんだろうけど、毎回そんなうまく書けるわけもなくて。 コードを変えたときに(特にインタフェースを変えたときに)テストも修正しないといけないということがままあると思う。

でも、そのコストは必要な投資だと思っていて、単体テストがあることで得られるリターンは大きいと思う。 人手を介さず CI で常に回しておくこともできるし。 まぁそれでも大量の単体テストを書き直してるときはけっこうしんどいのは間違いないw

リファクタリング【第2版】- 第3章:コードの不吉な臭い

リファクタリングの第3章。

リファクタリングをいつするべきか、そのタイミングを明確にすることは難しい。 でも、筆者は経験を通してリファクタリングするべきコードの特徴(それを臭いと表現している)をリストアップしている。

  • 不思議な名前
  • 重複したコード
  • 長い関数
  • 長いパラメータリスト
  • グローバルなデータ
  • 変更可能なデータ
  • 変更の偏り
  • 変更の分散
  • 特性の横恋慕
  • データの群れ
  • 基本データ型への執着
  • 重複したスイッチ文
  • ループ
  • 怠け者の要素
  • 疑わしき一般化
  • 一時的属性
  • メッセージの連鎖
  • 仲介人
  • インサイダー取引
  • 巨大なクラス
  • クラスのインタフェース不一致
  • データクラス
  • 相続拒否
  • コメント

名前からすぐに分かる特徴もあれば、名前からでは何かよく分からない特徴もあるな・・・。

今まではリファクタリングする判断を経験と勘に頼っていたけど、こういうリストがあると判断に一貫性が生まれるし他人にも説明しやすくなっていいね。勉強になった。

リファクタリング【第2版】- 第2章:リファクタリングの原則

リファクタリングの第2章。リファクタリングのベースとなる考え方について書かれている。

リファクタリング、とは何か。

リファクタリング(名詞)

外部から見たときの振る舞いを保ちつつ、理解や修正が簡単になるように、ソフトウェアの内部構造を変化させること。

リファクタリングをする、とは何か。

リファクタリングする(動詞)

一連のリファクタリングを適用して、外部から見た振る舞いの変更なしに、ソフトウェアを再構築すること

リファクタリングとは外部から見た振る舞いの変更なしにコードを修正すること。 コーディングしている間、破壊的な変更とリファクタリングの違いを意識して作業するとよい。 これを「二つの帽子をかぶり直す」と表現している。 変更をしやすくするために振る舞いを変えずにコードを修正して変更を加えやすい状態にし、その後、破壊的な変更を加える。

これは CODE COMPLETE の「二回測って一度で切る」の考え方と共通するところがある気がする。

この本でも言及されていたけど、こうやって考えてみるとリファクタリングとはとても小さなステップの集まりなんだよね。 大きくリファクタリングする時間をとるのもわるくないんだけど、理想は普段の機能開発の中に自然と取り入れられているものなのだと思う。

キャンプの古い格言に、キャンプ場を去るときは、来たときよりもきれいにして帰ろうというものがあります。駄目なコードを見かけるたびに少しずつ改善をしていけば、やがて問題はなくなっていくでしょう。

自分もコードを触るときは、そのコードを少しでもよい状態にして去ることを心がけている。完璧じゃなくてもね。

NEC Aterm WG2600HP4 を買ったら自宅のネット環境が改善した

自宅のネットワークの調子がいまいちよくなかったので、NEC Aterm WG2600HP4 を買いました。

f:id:hjm333:20210223110735j:plain

もともと、NURO 光のマンションタイプに加入していて ONU の ZTE F660A に付随している WiFi 機能を使っていた。 たまにインターネットの接続が悪くなる時があって、なんでかなーと思ってて、電波状況は悪くなってなかったからインターネット回線自体の問題かと思ってた。 マンションタイプだから回線が逼迫しやすいのかなーと。 たまに起きる程度だったから我慢してたけど、最近は明らかに接続速度が低下してストレスを感じ始めたので、重い腰を調べて原因を調査することに。

手始めに有線での速度はどんなものかと直接ルーターに繋いで速度を測ったら 1Gbps 出るレベル。はやい笑。 その後、何度測定しても有線だと安定して速度が出たので、ネットワーク不調の原因は WiFi のせいということが分かった。

さっそく WiFi ルーターを買おうと思い、いろいろ調べて NEC の WG2600HP4 を買った。 いざとなったときにメッシュ WiFi が組めるのが一番のポイント。 以前も Aterm 使ってて特に不満なかったし、価格も1万円くらいで特に文句のない範囲。 ただ、WiFi 6 が使えないのでそこが唯一の難点か。そのおかげで価格が抑えられているのだろうけど。

導入して数日経つけど今のところ快適に使えている。 ネットワークが不安定になる事象も解決した。 妻が Fire TV Stick で見ている Disney+ がたびたび読み込みで止まるという原因不明で悩んでた問題も解決した。 同じ Fire TV で見てる Prime Video は読み込みで止まることなかったから、WiFi は疑ってなかったんだけど Wifi が原因だったとはね。

以前から専用の WiFi ルーター買おうかなーと迷ってたんだけど、こんなことならもっと早くに買っておけばよかったな。

『ウォール街のランダム・ウォーカー』を読んで

『ウォール街のランダム・ウォーカー』を読みました。二月の読書。

ウォール街のランダム・ウォーカーは投資について書かれた本でこの界隈では有名みたい。 初版が出版されたのは 1973 年でもう 50 年も前だけど、その後何度も版を重ねていて、原著の最新版は 2020 年に改訂している。 その度に内容もちゃんとアップデートされていて、この第 12 版には仮想通貨の話題も。

この本(というか著者)の姿勢は一貫していて、とにもかくにもインデックス投資をしろ、という。 もう、ひたすらインデックス投資の優位性について書いた本といっても間違いではない(もちろん根拠は挙げながら)。 今でこそインデックス投資はとても一般的になったが、この本の初版が書かれた頃はようやくそういう商品が出始めた時期。 その時代から一貫してインデックス投資を勧めていた著者の先見の明には驚かされる。

本の内容は株式投資の一般的な話がメインでテクニカル分析、ファンダメンタル分析、スマートベータとは何か、みたいな話が載っている。 でも、結局インデックス投資と比較されて「ほら、やっぱりインデックス投資が最強でしょ」となる。 自分も影響されてインデックス投資しようと思った笑。 「世間がインデックス投資しかしなくなったら、市場の効率性が失われてしまうのでは?」と警笛をならしている人もいるようで、 たしかにそういう側面もあるのかーと思ったりした。

最後の方は一般人向けの投資アドバイスが載っていて、投資の心構えとかおすすめポートフォリオが書かれている。 実はこの本を読む前に、同じ著者が書いた『投資の大原則』という本を読んでいた。 そちらの方が内容も簡潔にまとまっていて読みやすいし、iDeCo とか NISA とかやろうと思っている人はこっちをさくっと読むといいと思う。

唯一、気をつけなきゃいけないのはアドバイスがアメリカに住んでいる人を対象にしているところかな。 無リスク利回りが 1% だったり、インフレ率が 2% だったり、自国通貨が世界最強米ドルだったりする国に住んでいる人向け。 でも、それを踏まえても役に立つアドバイスがずいぶんと書かれている本だった。

Kinesis Advantage2 日本語配列を買いました。

Kinesis Advantage2 日本語配列を買いました。

f:id:hjm333:20210211230417j:plain

最近、少し右手首が痛むようになってきて、このまま痛みが強くなって仕事ができなくなると困るな~と感じていた。 右手の薬指でバックスペースを押す癖があって、そのせいで右手の甲に余計な力が加わるのが理由の一つ。 あと、在宅勤務で家のデスクが小さいのでトラックパッドの位置がよくなくて、手に負担がかかる形で作業しているのも影響してそう。 (もしかしたら、単に下の子を抱っこするせいで手首を痛めているだけかもしれないが)

そんなことがあって、手首の負担を軽くするセパレート型のキーボードを探し始めた。 探し始めて分かったんだけど、セパレートタイプのキーボードって日本語配列がほとんどないんだよね。ほとんど US 配列。 そんなときに Kinesis のキーボードに日本語配列が出ていることを知った。

大学時代の担当教授が使っていてとても目立っていたので Kinesis のキーボードの存在は知っていたけれど、明らかに普通のキーボードと違うから慣れるコストを考えて今まで少し敬遠していた。 10 年以上 REALFORCE を使っていて打ち心地にとても満足していたから、なかなかキーボードを変える気にならなかった。 でも、明らかに手の負担はセパレートキーボードの方が少ないし、まだまだ現役でいたいから身体のことを考えて思い切って Kinesis に挑戦してみることにした。

日本語配列 with Mac の制限事項

早速買おうと思って調べていたら、日本の代理店のサイトに気になる一文が。

日本語Windowsでのご使用を想定した日本語配列キーボードです。 MacOSでは従来の米国配列モデルのご使用をお勧めいたします。

ref: https://www.edikun.co.jp/kinesis/advantage2_jp.htm

基本的に仕事で使うつもりなので Mac で利用できないとなるとさすがに買えない。 具体的にどのような不都合があるのか、この点はクリアにしておかないといけないと思ってメールで問い合わせてみた。

問い合わせたらすぐに回答をくれてとても助かった。 回答をここに貼り付けても別に問題ないと思うので貼っておく。

■Windows特有キーの利用

日本語配列モデルはWindows利用を想定したキー配列となっており、 半角全角、変換、無変換など、Macには存在しないキーがいくつか配置されております。 上記のキーはMac上では正常にご利用いただけませんのでご注意ください。 MacOSでのご利用をご検討の場合には、その他のキーをリマップするなど 別のキーとしてのご利用を推奨いたします。

■装飾キーに関して

Command、optionなどのMac用装飾キーは付属しておりません。 Windowsキーはcommandキーとして代用利用は可能ですが、 キーキャップの交換が行えませんのでご注意ください。 なお、英語配列モデルではMac利用も想定し、 Mac用装飾キーの付属がございます。

■日本語配列モデルの注意点

利用OSに関わらず、日本語配列モデルはキーボードプログラミングソフト SmartSet Appと互換性がありません。 なお、キーボードに搭載されているリマップ・マクロ機能は同様にございますので、 SmartSet Appを用いない設定方法は可能です。

結論からいうと特に問題はなさそうだ。 まだほとんど Mac では使ってないけど、ちょっと使ってみた感じ大丈夫そう。

キートップが交換できないのが残念だけど、REALFORCE を使ってたときからキートップ問題はあったからあまり気にならないかな。

実際使ってみて

まだ一日しか使ってないけど、思ったより慣れるのは大変じゃなさそう。 公式のマニュアルにも数日でもとの 80 %くらいのパフォーマンスは出せるようになると書いてあったし。

Kinesis で打ち始めて自分のタイピングに少し癖があることが分かった。 "B" を右手で打つ傾向がある。これは直していかないといけないな。 それ以外は特に変な癖はないかも。中学生の頃、それまでの無理やりタッチタイピングをタイピング練習ソフトで強制した甲斐があった。 あとはぜんぜん位置が違うエンターキーとかブラケットとかの位置はどうしても慣れが必要。 最近は JavaScript 書くことがおおいからブラケット問題は辛い…。練習して慣れるしかない。

Kinesis のいいところってキーボード上で簡単にリマップできるところだと思うけど、なるべくデフォルトで使おうと思っている。 最低限、次のところをリマップした。

f:id:hjm333:20210211232558j:plain

  • スペースは左手で押したいので、バックスペースと入替
  • 変換・無変換を一般的な日本語配列と同じになるように入替
  • A の横に CTRL はお約束

変換・無変換に関してはあえて一般的な配列と変えているらしい(開発者のブログ)。開発者の好意を無駄にしてごめん…。

このブログは Kinesis で書いているけど、確かに手首への負担は少ないと感じる。 あとはやっぱり浪漫みたいなところはあって、このキーボードでプログラミングしてるとハッカー感があっていい。 あの Martin Fowler も使ってるみたいだし。

最大のデメリットはかなり高いところ。 税込でほぼ五万円に近い。 本当に使いこなせるか分からない状態でこれを買うには度胸がいる。

今回、実は会社の経費で買っていて、今の会社はこういう備品を申請なしでほぼ自由に買うことができる。 お金で解決できるなら積極的にそうしてくださいという文化があって、生産性が高まる可能性があるなら冒険的な買い物も積極的に推奨している。 こういう制度はとてもありがたいですね。

これを機にトラックパッドもやめてトラックボールにしようかなとも思っているけど、まずは Kinesis に慣れてから考えようかな。

リファクタリング【第2版】- 第1章:リファクタリング - 最初の例

マーティン・ファウラーの『リファクタリング』を読み始めました。

初版が出たのが 1999 年。いつか読みたいと思っていたけど、さすがに内容が古いのかなと思って読んでいなかった。 第2版が出たと聞いて調べてみたら、コード例が JavaScript になって今風になったということで読んでみることにした。

毎日ちょっとづつ読み進めていって章ごとに記事にまとめようと思う。 時間はかかるけど、この本にはそれだけの価値があるはず。

第1章: リファクタリング - 最初の例

第1章は JavaScript で書かれたコードを実際のリファクタリングによって改善していく様子が書かれている。 理論を説明するための前準備として「実例を出す」というのが著者のスタンスらしい。

請求書を発行する JavaScript の 100 行ほどのコードが例になっている。 ここではいくつかのリファクタリングのテクニックが用いられている。

  • 関数の抽出
  • 問い合わせによる一時変数の置きかえ
  • 関数宣言の変更
  • 変数のインライン化
  • ループの分離
  • ステートメントのスライド
  • フェーズの分離
  • 関数の移動
  • ポリモーフィズムによる条件分岐の置きかえ

それぞれの詳細な説明については第2章以降に書かれている。 これらのテクニック一つ一つはとても単純なもので自分もコードを書くときに使っているものもある。

でも、『問い合わせによる一時変数の置きかえ』と『変数のインライン化』はあまり使わないかもしれない。

これは、

for (let product of producst) {
  let thisAmount = getAmount(product);
  ...
  result += `${format(thisAmount/100)}`; 
  totalAmount += thisAmount;
}

というようなコードがあったときに、変数を用いずに次のようにすることだ。

for (let product of producst) {
  result += `${format(getAmount(product)/100)}`; 
  totalAmount += getAmount(product);
}

後者の方が、変数がすくなくて状態が一つ少ないという点、関数の抽出がやりやすくなるという点が有利である。

ただ、個人的には一時変数にいれておいたほうが値がラベリングされていて見やすいんじゃないかと思う。 この時、変数が可変(let)じゃなくて不変(const)になっていることが条件だけど。 関数呼び出しがあるとどうしても副作用を気にしてしまってコードを読むスピードが少し落ちる。自分の場合だけど。

関数呼び出しを二回することでパフォーマンスの方を気にする人がいるかもしれないが、個人的にはこのケースならパフォーマンスは気にしない。 この点は本でも言及されている。

ここで指摘したいのは、この変更はパフォーマンスに大きな影響を与えないし、たとえそうであっても、コードが整然としていれば後からチューニングが容易にできるということです。

--

自分は何かの修正があるとき、修正の内容を意識しながらまずはリファクタリングしてコードを整えてから修正を加えるようにしている。 この方が変更がシンプルになりやすいし、コードレビューしてもらう時に差分が分かりやすいからだ。

構造的に機能を加えにくいプログラムに新規機能を追加しなければならない場合には、まず機能追加が簡単になるようにリファクタリングをしてから追加すること。

このやり方だと作業時間は少し長くなりがちでデメリットもあるんだけど、この本と意見が同じで少し安心した。 まぁリファクタリングの本だし当然といえば当然か。

(c) The King's Museum