良いコ-ドへの道―普通のプログラマのためのステップアップガイド

第3回 スコープを意識したプログラミング―その3 インスタンスメソッドの可視性

この記事を読むのに必要な時間:およそ 2 分

インスタンスメソッドの可視性

インスタンスメソッドとはインスタンスに属するメソッドです。Javaでは,メソッドの可視性もフィールド変数と同じ4つです。メソッドの可視性は最小のprivateから始めて,必要に応じてpackage private,protected,publicと大きくしていくのが良いでしょう。

メソッドの引数の情報量

スコープから少し話はずれますが,メソッドの引数で渡す情報量をどの程度にするのかということも,依存性という面から見ると重要になってきます。

例を見てみましょう。以下はどちらも社員情報を取得するメソッドですが,[1]は引数が社員IDで,[2]は引数が社員オブジェクトになります。この2つのコード,どちらが良いコードだと思いますか?

[1] 引数が社員IDの場合

public Employee getEmployee(Integer empId) {
    return empDao.findById(empId);
}

[2] 引数が社員オブジェクトの場合

public Employee getEmployee(Employee emp) {
    return empDao.findById(emp.getId());
}

一般的に[1]のほうが引数の情報量が少ないので,引数に対しての依存が少なく良いコードであると言えます。[2]は社員オブジェクトが持つすべての情報にアクセスできてしまうため,依存が大きくなります。[1]が依存するのは引数の社員IDのみなので,そこだけに注目してコードを書くことができます。

メソッドを利用する側から見ると,社員IDだけでメソッドを利用できるのと,社員オブジェクトが常に必要なのでは全然違います。しかも,[2]のメソッド内の具体的な処理では,社員オブジェクトの社員IDのみを使って社員情報を検索しています。このことがドキュメント化されていない場合,コードを読まないとその事実はわかりません。引数に余計な情報が含まれていると「社員IDがセットされた社員オブジェクトを渡すべし」といった暗黙的な仕様が生まれやすくなってしまいます。

上記のような問題から,メソッドの引数は必要最低限の情報を持つのが依存性が少なく良いコードであると言えます。

ただし,引数の数が多くなり過ぎる場合は,引数をオブジェクトに変更したほうがよいです。目安として引数の数が5つを超えるメソッドは,引数をオブジェクトに変更することを検討するとよいでしょう。

staticメソッド

staticメソッド(クラスメソッド)はクラスに属するメソッドです。Javaではstaticメソッドは,staticキーワードを付けて宣言します。staticメソッドの可視性はインスタンスメソッドの可視性と同様です。一方で異なる点として,「staticメソッドはフィールド変数にアクセスできない」ということが挙げられます。

フィールド変数から見ると,インスタンスメソッドをstaticメソッドに変更した場合,自分が影響を与えるメソッドが減ることになり,結果的にスコープは小さくなります。フィールド変数にアクセスする必要がなく,オーバライドなどの必要がないメソッドは,staticメソッドにしたほうが良い場合が多いですリスト6~7)。

リスト6 インスタンスメソッドの場合

private int count;
...
private String regexGroup(String regex) { |変数countのスコープ
    // フィールドにアクセス可能
    return "(" + regex + ")";
}
...

リスト7 staticメソッドに変更した場合

private int count;  ┓
...                 ┛変数countのスコープ
private static String regexGroup(String regex) {
    // フィールドにアクセス不可
    return "(" + regex + ")";
}
...     ―変数countのスコープ

COLUMN Javaのアクセサメソッドが冗長である件について

JavaやObjective-C 1.0,Smalltalkなどの言語では,本文で解説したように教科書的にはセッタ/ゲッタなどのアクセサメソッドを書くのが基本になります。しかし,アクセサメソッドは記述が冗長になってしまうため,最近ではほかの言語でサポートされているプロパティやpublicフィールドに対して,以前と比べて肯定的な意見が多く出るようになってきています。

Java 7でプロパティがサポート予定

C#やECMAScript第4版(ActionScript 3.0/JavaScript 2.0),Objective-C 2.0などでは,アクセサメソッドの代わりに言語仕様でプロパティをサポートしています。また,Rubyにはアクセサメソッドを簡単に定義できる構文があります。

Javaの次期バージョンJava 7でも,C#風のプロパティ構文が言語レベルでサポートされます。これにより,冗長だと批判の大きかったアクセサメソッドを書かずに簡潔に記述できるようになります。使い方はリストcのように「propertyキーワード」を使ってプロパティを宣言するだけです。のように,個別に簡略化された形式でアクセサメソッドを書くこともできます。

フレームワークにおけるpublicフィールドのサポート

Seasar2やS2JDBC,Clickなど最近のJavaフレームワークでは,publicフィールドをアクセサメソッド同様にプロパティとみなして動作するような仕様が盛り込まれています。単純な入れ物としてのオブジェクトや,インジェクション用のフィールドに対するアクセサメソッドは特別な処理を持つことがありません。そのため,publicフィールドで直接アクセスしても問題がないだろうというわけです。これは,Java 7のプロパティ構文を先取りしているとも言えます。

リストc Java 7のプロパティ

public property int count1; // 読み書き可能プロパティ
public property int count2 get; // 読み込み可能プロパティ
public property int count3 set; // 書き込み可能プロパティ

// ①ユーザ定義プロパティ
private int count4_;
public property int count4
get {
    return count4_;
}
set {
    count4_ = count4;
};

著者プロフィール

縣俊貴(あがたとしたか)

学生時代にMSXで制限された環境でのプログラミングの楽しさを学ぶ。以来,オープンソースのWiki実装「MobWiki」の開発や受託開発などを経て,現在はプロジェクト管理ツール「Backlog」,ドローツール「Cacoo」など,コラボレーション型のWebサービスの企画と製品開発を行う。また,Webアプリケーションフレームワーク「Cubby」のコミッタを務める。福岡在住。株式会社ヌーラボ所属。

ブログ :http://d.hatena.ne.jp/agt

Twitter:@agata

コメント

コメントの記入