『リファクタリング』第2章 リファクタリングの原則 読書メモ

新装版 リファクタリング―既存のコードを安全に改善する― (OBJECT TECHNOLOGY SERIES)

第1章はサンプルコードをベースにした「体験版」的な内容なので、読書メモは第2章から。

リファクタリングの定義

リファクタリング(名詞):外部から見たときの振る舞いを保ちつつ、理解や修正が簡単になるように、ソフトウェアの内部構造を変化させること。 – p.53

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

リファクタリングの目的は、ソフトウェアのコードを理解しやすく、変更しやすくすること。そのために重要なのが、外的な振る舞いを保つこと。

コードを書く際には、機能追加とリファクタリングという「2つの帽子」のうち、自分が今どちらの防止をかぶっているのか意識すべき。

リファクタリングを行う理由

  • リファクタリングはソフトウェア設計を改善する
  • リファクタリングはソフトウェアを理解しやすくする
  • リファクタリングはバグを見つけ出す
  • リファクタリングでより速くプログラミングできる:優れた設計は開発が進んでも速度が落ちない

いつリファクタリングをすべきか

  • 3度目の法則:同じようなコードを3回書いたらリファクタリングする
  • 機能追加の時にリファクタリングを行う
  • バグフィックスの時にリファクタリングを行う
  • コードレビューの時にリファクタリングを行う

管理者を説得するには

  • 管理者が品質を重視するタイプなら:リファクタリングを行うことでソフトウェアの品質が向上する点を強調する
  • 管理者が品質よりスケジュールを重視するタイプなら:管理者に無断でリファクタリングする

最も速い方法はリファクタリングです。だからリファクタリングをするのです。 – p.61

リファクタリングの問題点

  • データベースのリファクタリングはソフトフェアに比べると非常に難しい
  • インタフェースの変更:「published」メソッドのインタフェースを変えるのは非常に難しい

「published」とは、publicよりもさらに広く公開され、変更が困難なこと。具体的には、一般公開されているライブラリに含まれるpublicメソッドなど、書き手がそのメソッドの使用箇所を全て探しだして変更することが困難な状態になったメソッドのこと。この場合、インタフェースを変更するなら、古いインタフェースを残しつつ新しいインタフェースを提供する、という形式になる。

  • リファクタリングしにくい設計:どんなに間違った設計でもリファクタリングできるか、という問いに対しては、明確な答えはまだない

リファクタリングを避ける時

  1. 変更するよりも最初から書き直したほうが早い時
  2. 納期が迫っている時:リファクタリングによる生産性の向上は後々効いてくるものなので、納期前にリファクタリングをしても速度は上がらない。

リファクタリングと設計

リファクタリングには、設計を補完する役割がある。リファクタリングを行うことで、事前設計を改善していくことができる。

リファクタリングとパフォーマンス

リファクタリングを行うことで、コードのパフォーマンスが低下することもある。一般に、パフォーマンスの最適化には以下のようなやり方がある。

  1. 時間分割:各コンポーネントが使用可能なリソースの上限を決め、その上限を厳守する。組み込み系などで必要となることがある。
  2. パフォーマンスを常に意識する:コードの全体にパフォーマンス最適化を行う。その結果、コードが読みづらくなることが多い。
  3. 90%の法則:全体の90%は読みやすく保ち、パフォーマンスに影響を与える10%をチューニングする。

Webアプリケーションの場合、パフォーマンスを低下させる箇所は決まっているので、90%の法則が適している。

パフォーマンスチューニングで重要なのは、「推測せず、計測せよ」。

リファクタリングの起源

Smalltalkを使っていたWard Cunningham と Kent Beck が中心的人物。Smalltalkには、コンパイルの速さとオブジェクト指向という、リファクタリングに向いた性質があった。

第1章はいきなりサンプルコードが出てきて、それをリファクタリングしていくという、とても具体的な内容だったのに対して、第2章は抽象的な議論が中心だった。続く第3章は「コードの不吉な臭い」について。

『パーフェクトJavaScript』第1章 JavaScriptの概要

パーフェクトJavaScript (PERFECT SERIES 4)

AngularJSについて学んでいると、JavaScriptの理解が不足しているな、と感じることが結構あるので、AngularJSの学習と平行して↑の書籍を読んでいこうと思います。

ちなみに、私が持っているのは紙の本ですが、技評の「パーフェクト」シリーズは最近電子書籍化されました。直販のGihyo Digital Publishingだと、DRMフリーのePub/PDFが入手できるのでオススメです。


JavaScriptの概要

  • JavaScriptは史上もっとも世界を支配するプログラミング言語になろうとしている
  • JavaScriptの登場は1995年(Netscape Navigator)
  • JavaScriptはECMAScript(ECMA-262、ISO-16262)として標準化されている
  • ECMAScript第4版は存在しない(標準化に失敗)
  • 現在、第5版(第3版と大きな差異が無い)が最新の標準で、第6版が策定中
  • JavaScriptの移植性について問題なのは、JavaScript言語処理系の違いよりも、レンダリングエンジンの違い
  • レンダリングエンジンの差異をなくすために、Acidというテストへの準拠が進んでいる

JavaScript実行環境

  • JavaScriptの言語仕様とDOMは独立している
  • JavaScriptの中で取り替え不能な機能を強調するとき、それをコア言語と呼ぶ
  • JavaScriptには実行環境(ブラウザ、サーバ等)ごとの固有のホストオブジェクトが存在する

JavaScript周辺環境

  • JavaScriptライブラリは、2015年1月現在、jQueryがデファクトスタンダード
  • ソースコード圧縮によって転送量の削減と処理時間の低減を図るのが一般的

『AngularJSリファレンス』ビルトインディレクティブ・イベント

AngularJSリファレンス

イベントは、JavaScriptの標準APIにないものを中心に、サンプルコードを動かしてみる。

ngChecked

ng-checked=””に指定した式の評価値が真ならチェックが入る。「まとめてチェック」昨日の実装に便利。

ngSubmit

action属性があるときは通常のformとして動作し、action属性が無い場合は指定されたangular式を実行する。以下のサンプルでは、2つのフォームにng-submit=”submit()”を指定しているが、action属性を指定している方のformではsubmit()は実行されず、通常のformの動作になっている。

その他の組み込みディレクティブ(イベント、input・form、ng-app等)については、本書の解説とサンプルで十分な感じがする(足りなければ公式リファレンスを読めばいい)。『AngularJSリファレンス』という書名だけあって、ひと通り網羅されているので安心感がある。

『AngularJSリファレンス』ビルトインディレクティブ・DOM操作 の補足

AngularJSリファレンス

第2章はAngularJSに組み込みのディレクティブの解説なのだけど、ところどころ説明不足で疑問点を自分で調べる必要があったので、補足を書いてみる。

ngCloak

本書のサンプルコード(p.17)は↓のようになっているが、これだと<p ng-bind="myName"></p>との違いが分からない。

実際のところ、ngCloakはもっと汎用的に使える。たとえば、<body ng-cloak>としてやれば、AngularJSの処理が終わるまで一切画面が表示されない。より推奨される使い方としては、ngCloakを細かな単位に分割して適用し、処理が完了したところから表示していくほうが良い。たとえば、リストの描画完了に時間がかかるときに、リストにだけng-cloakを指定する等。

ngCloakの実際の処理の流れは以下のとおり。

  1. ngCloakが設定されている要素にはCSSでdisplay:noneが指定されるので、画面上には何も表示されない
  2. ngCloakを指定した要素がcompileされるタイミングでngCloakの指定が取り除かれ、画面上に要素が表示される

以下がソースだが、仕組みは超簡単。

ngCloakのソース(https://github.com/angular/angular.js/blob/master/src/ng/directive/ngCloak.js)

ng-repeat-start/end

本書(p.27)だと、

ng- repeat-start と ng-repeat-end で、明示的にループ開始と終了を宣言することも可能です

とあるのだけど、これだと何が嬉しいのか分かりづらい(私は分からなかった)。ng-repeat-start/endは、以下のように、複数要素に渡る繰り返しを実装したい時に使う(以下のコードだと、dtとddのペアが繰り返し表示される)。

ng-repeatだと、1要素の繰り返ししかできないけど、ng-repeat-start/endを使うと、dt+ddや、その他様々な組み合わせで要素を繰り返すことができる。

12/30 14:43 追記

動作確認のためjsFiddleのサンプルを追加。

クリックジャッキング対策について調べた

クリックジャッキングとは

クリックジャッキングとは、外見上は無害に見えるウェブページをクリックしている間にウェブ利用者をだまして秘密情報を露呈させる、あるいはウェブ利用者のコンピュータの支配を獲得する悪意の技術である

クリックジャッキング – Wikipedia

要はiframe等を使用してユーザーの意図したものとは異なるものをクリックさせる攻撃手法のこと。具体的な実装例は以下のサイトなどが参考になります。

http://hamachiya.com/junk/cj.html

「秘宝館A」ボタンの上には透明化されたFacebookの「いいね!」ボタンが配置されていて、「秘宝館A」を押すと「いいね!」されてしまう、というような仕組みです。

たとえば、SNSのプライバシー設定が勝手に変更されたりすると、困った事態になるかもしれません。

クリックジャッキングはiframeを利用して行うので、自分が作成しているWebサイトがクリックジャッキング対策を施していない場合、攻撃者によってiframeで表示されてしまうかもしれません。

クリックジャッキングを防ぐには

サイトのiframe内の埋め込みを制御する、「X-FRAME-OPTIONS」ヘッダを、HTTPヘッダに含めます。Microsoftが提案した、HTTPの標準にはないヘッダですが、現在の主要なブラウザであれば対応しています(IE8以降、Firefox 3.6以降、Chrome 4.1以降)。

X-FRAME-OPTIONS: DENYというHTTPヘッダを含むページは、iframe内に表示されません。また、X-FRAME-OPTIONS: SAMEORIGINを指定されたページは、「同一生成元(プロトコル・ホスト名・ポート番号が一致している)」という条件を満たす場合のみ、iframe内に表示可能です。

ちなみに、大手サイトだと、TwitterやAmazonはSAMEORIGIN、FacebookはDENY、楽天はログイン後のページ(ショッピングカート等)のみDENY、といった設定になっています。

具体的な設定方法は以下のとおりです。

1. Webサーバの設定を行う

ApacheやNginxといった、Webサーバのレベルで設定します。サイト全体で指定したい場合はこの方法が確実です。

以下はApache(2.2)の設定例です。

本ブログの場合、ブログ用のVirturlHostの設定の中で「Header always append X-Frame-Options SAMEORIGIN」を指定しています。

以下のようにiframeを使用することが可能ですが、別ドメインからiframeで表示することはできません。

DENYではなくSAMEORIGINにしているのは、使用中のWordpressプラグインの中にiframeを使用しているものがあり、DENYにすると一部プラグインが動かなくなってしまうからです。

2. (PHPの場合)header関数を使用してヘッダを出力する

プログラムでX-FRAME-OPTIONSヘッダを付け足してもOKです。1つ注意が必要なのは、X-FRAME-OPTIONSヘッダは、「厳しくするように上書きはできても、緩めることはできない」という点です。

http://ryo511.info/x_frame_options_sameorigin.phpでは、X-FRAME-OPTIONS: SAMEORIGINを指定しているサイト内で、X-FRAME-OPTIONS: DENYというヘッダを出力しています。

このページをiframeで表示しても、何も表示されません。

逆に、DENYを指定している場合に、SAMEORIGINで上書きしようとしても、DENYの方が優先されます。

参考文献

『PHP逆引きレシピ 第2版』p.782 を読んだのが、本記事を書くきっかけになりました。

PHP逆引きレシピ 第2版 (PROGRAMMER’S RECiPE)

IPAが公開している『クリックジャッキング』に関するレポート(pdf)が、クリックジャッキング関係の日本語文献としては最も充実した内容だと思います。攻撃手法から対策方法、対策を施すべきサイトの特徴から、X-FRAME-ORIGINSでは対応出来ない場合の対策まで載っています。

ちなみに、日本のPHP界では、セキュリティといえば「徳丸本」が定番ですが、本書のクリックジャッキング対策には誤りがあるので注意してください。

あの徳丸本にも間違いはある! 自分で確認することが大切です