LoginSignup
21

More than 5 years have passed since last update.

【Java】副作用がないことを明示するためにprivate staticメソッドを利用する

Last updated at Posted at 2016-05-17

概要

privateなインスタンスメソッドをstatic(クラスメソッド)に変更することで、副作用が無いことを明示できるという方法小手先テクニックを紹介します。

どんな場合

例えばこんな感じの汚いインスタンスメソッドがあったとすると、

    private void example(List hoge) {
        String message;
        if (hoge == null) {
            message = "hoge is empty";
        } else if (hoge.size() < 3) {
            message = "hoge is small";
        } else {
            message = "hoge is big!";
        }

        // do something...
    }

リファクタリングでこんな風にメソッド分割をすると思います。

    private void example(List hoge) {
        String message = messageFromHoge(hoge);

        // do something...
    }

    private String messageFromHoge(List hoge) {
        if (hoge == null) {
            return "hoge is empty";
        } else if (hoge.size() < 3) {
            return "hoge is small";
        } else {
            return "hoge is big!";
        }
    }

別にこれでもいいんですが、もしこの分割されたメソッドが実は

public class Example {

    private String fieldA;

    private void example(List hoge) {
        String message = messageFromHoge(hoge);

        // do something...
    }

    private String messageFromHoge(List hoge) {

        fieldA = null; // Oops!!

        if (hoge == null) {
            return "hoge is empty";
        } else if (hoge.size() < 3) {
            return "hoge is small";
        } else {
            return "hoge is big!";
        }
    }
}

このように、フィールド変数に余計なことをしてしまっているかもしれません。
考え過ぎかもしれません。でももっと複雑になっていけば、ついうっかりこんな感じのことをしてしまうかもしれません。

staticにして回避する

ではここで、インスタンスメソッド「messageFromHoge」をクラスメソッドとして定義し直します。

public class Example {

    private String fieldA;

    private void example(List hoge) {
        String message = messageFromHoge(hoge);

        // do something...
    }

    private static String messageFromHoge(List hoge) {

        fieldA = null; // コンパイルエラー!!!!!!!!!

        if (hoge == null) {
            return "hoge is empty";
        } else if (hoge.size() < 3) {
            return "hoge is small";
        } else {
            return "hoge is big!";
        }
    }
}

そうすると、当然ながらフィールド変数へのアクセスはできず、コンパイルエラーになってくれます。

軽い解説

インスタンスメソッドはフィールド変数へアクセスできる可能性がありますが、クラスメソッドではそのようなことはありません。
privateなクラスメソッドは、引数にのみ依存し、外界へ副作用をもたらすことはありません。

つまり、privateメソッドを作成する際、フィールド変数に依存する処理はインスタンスメソッド、フィールド変数に依存しない処理をクラスメソッドとすることで、影響範囲や役割を明示することができます。

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
21