読者です 読者をやめる 読者になる 読者になる

akimachoのはてなブログ

ICTとデザインのためのブログ

リファクタリングメモ - タイプコードの置き換え

プログラム Jav 読書

はじめに

結城 浩『Java言語で学ぶリファクタリング入門』のタイプコードの置き換えを勉強したので、メモです。

Java言語で学ぶリファクタリング入門

Java言語で学ぶリファクタリング入門

クラスによるタイプコードの置き換え

Replace Type Code with Class

基本型(プリミティブな型)をタイプコードとして使ってしまうと、コンパイル時の型チェックを受けることができません。すると、以下のような危険を孕みながらプログラムを実行することにになります。

  • タイプコードが扱わない範囲外の値が使われる
  • ほかのタイプコードと混同する

基本型を使う危険性 = タイプセーフではない、型チェックが効かない

リファクタリング方法

基本型をオブジェクトでラッピングして、カプセル化しましょう。

メリット

タイプコードの型チェックが可能になる。つまり、IDEが関数の間違えを事前に指摘してくれたりします。あと、コードの可読性も向上しますね。


サブクラスによるタイプコードの置き換え

Replace Type Code with SubClasses

タイプコードの種類に応じてオブジェクトに異なる振る舞いをさせます。

サブクラスによるタイプコードの置き換えでは、以下のようなケースに対応できないのです。その場合は、State/Strategyによるタイプコードの置き換えを検討します。

逆にいえば、以下のケースでない場合はこのパターンが使えます。

  • タイプコードが変化する
  • 対象となるクラスがすでに他のクラスのサブクラスになっている(多重継承OKな言語は例外)

RubyJavaは単一継承のみOK。C++Pythonは多重継承が許されています。

リファクタリング方法

  1. タイプコードをカプセル化
  2. Factory methodでタイプコードをもとにインスタンスを作る
  3. タイプコードごとにサブクラスを作る

メモ

オブジェクトを識別して処理を振り分けるコードは、多態なメソッドに置き換えてみましょう。

switch文やinstanceof演算子は不吉な匂いがする!

以下、クラス図(p.163、Fig.8-2を参考に作成。一部改変)

f:id:akimacho:20160727234113p:plain


State/Strategyによるタイプコードの置き換え

Replace Type Code with State/Strategy

以下の2つの場合に、この置き換えを使います。

  • タイプコードが変化する
  • 対象となるクラスがすでに他のクラスのサブクラスになっている

サブクラスによる置き換えとの違い

  • 共通点
    • 振る舞いをオーバーライドしたメソッドで記述する
  • 相違点
    • 状態(タイプコード)を利用するクラスが保持するか、外に持つか否か

リファクタリング方法

タイプコードを状態オブジェクトに置き換える


おわりに

結城 浩『Java言語で学ぶリファクタリング入門』ではJava言語を使ったサンプルコードですが、Swift言語ではどうでしょうか?

Swiftのenumは柔軟なので、簡単かつ安全にタイプコードを使うことができるのではないでしょうかね。

次回はこの検討をしてみたいと思います。