ラベル Design Pattern の投稿を表示しています。 すべての投稿を表示
ラベル Design Pattern の投稿を表示しています。 すべての投稿を表示

2013年8月3日土曜日

Out parameter, collecting parameter, visitor pattern

『Effective Java (第二版)』の「項目15 可変性を最小限にする」では不変オブジェクト (Immutable object) を推奨している。これは状態を持たないから、シンプルに扱える。反対に状態を持つ可変オブジェクト (Mutable object) は、扱いに気を遣う。扱おうとしているときにどういう状態なのか意識しないといけない。状態に起因したバグがあったら、最悪、状態が変更されている場所を全て確認しないといけない。

これに真っ向から対立しているのが、Out parameter。状態を変えるために渡す可変オブジェクトのことを指す。Webを検索してみると、アンチパターンとして紹介されている記事が見つかる。

でも、"Collectiong parameter"として『実装パターン』や『パターン指向リファクタリング入門』で紹介されていたりする。また、『パターン指向リファクタリング入門』では、その延長線上に"Visitor Pattern"を適用したパターンも紹介されている。

確かにこちらの方が合理的なケースもありそう。でも、基本的にはあまり使わない方がよさそう。コマンドとクエリは分離するのが原則だ。使うなら、Javadocに明記するなりしないと混乱を呼びそう。C#のoutキーワードに相当するものがJavaにはないから、引数の状態を変えるかどうか宣言だけから読み取れない。

ところで、out (C#)に使用例として「メソッドが複数の値を返すようにする場合に便利」だなんて書かれている。同時に扱いたい複数の値があるなら、クラスとしてまとめた方が読みやすくないだろうか。原則として、入力を与えたら戻り値が返ってくる関数として考えたい。

References

2013年3月1日金曜日

インスタンスを生成するメソッドの名前

インスタンスを生成するメソッドの名前について、よく迷うのでまとめておく。

まずは、スタティックファクトリメソッド。"Effective Java (2nd Edition)"の"Item 2: Consider Static Factory Methods instead of Constructors"に倣って使うようにしているけれど、感覚で名前をつけてしまうことがあるので、気をつけないと。
  • valueOf: パラメータと同じ意味合いの値を持つインスタンスを返す。Integer#valueOf(int)はじめ、型変換メソッドが典型例。
  • of: valueOfと同じ。EnumSetで使われている。
  • getInstance: 指定したパラメータから組み立てたインスタンスを返す。Singletonパターンでよく使われる。
  • newInstance: getInstanceと同様だけれど、必ず新しいインスタンスを返す。だからSingletonパターンでは使えない。
  • getType: getInstanceと同様だけれど、ファクトリメソッドが他のクラスにある場合に使う。Typeは返値の型名で置き換えて使う。
  • newType: newInstanceと同様だけれど、ファクトリメソッドが他のクラスにある場合に使う。Typeは返値の型名で置き換えて使う。

続いて、インスタンスの型変換メソッド。つまりインスタンスを元に別のクラスのインスタンスを作っているメソッドの名前についてもまとめておく。いずれもTypeは変換後の型名で置き換えて使う。こちらは"Item 56: Adhere to Generally Accepted Naming Conventions"の一部。
  • toType: 異なった型の独立したオブジェクトを返す。例えば、Object#toString() 。
  • asType: そのオブジェクトの異なる型での表現を返す。adapter パターン (Effective Java ではView) で使う。例えば、Arrays#asList(T... a)。
  • typeValue: プリミティブ型を返す。例えば、Integer#intValue()。

References