※ 本記事は未完成 です。
まだ自分の中に落とし込めていないのですが、他の人の役に立つこともあるかと思い、投稿します。
誤っている箇所がありましたら、遠慮なくマサカリを投げてください。
「staticメソッド」とは?
直訳すると「静的メソッド」です。「クラスメソッド」ともいいます。
対義語は「インスタンスメソッド」です。
staticメソッドのメリット
①インスタンスを生成せずに呼び出せる
インスタンスを生成せずに呼び出せるのが一番のメリットです。インスタンス生成にかかるオーバーヘッドがなくなるので、 インスタンス生成に時間がかかるクラスに有効 です。
そのため、頻繁に呼び出されるユーティリティメソッドはよくstaticメソッドとして実装されます。
また、自クラスのファクトリメソッドのように、 インスタンスの生成前に実行すべきメソッド はstaticにするしかありません。
②インスタンスごとに動作が変わらないことを保証できる
インスタンスを複数生成しても、そのインスタンスが持つstaticメソッドの処理はどのインスタンスも同じ動作になります。
③状態に依存しないことを保証できる
基本的にはインスタンス化しないと状態を持てないので、状態に依存しないことを保証できます。
具体的には、 与えられた引数のみでメソッドの挙動が決まる ことが保証できます。
その逆も然りで、状態を変更しない、いわゆる 副作用が起きない ことも保証されます。
ただし、これは「基本的には」です。
グローバル変数という インスタンス化しなくても状態を持てる変数がある場合は話が変わる ので注意です。
staticメソッドのデメリット
DIしにくい
言語にもよりますが、staticメソッドを持つクラスはDIしにくいです。
つまりモック化して単体テストしにくいということです。
staticメソッドの使い分け
①インスタンスごとに持つ意味があるかどうか
メソッドの意味を考え、インスタンスごとに持つ意味がなければstaticメソッドにし、あればインスタンスメソッドにすべきです。
たとえオーバーライドされる予定がなく、状態に依存していなくても、インスタンスごとに持つべきであればstaticメソッドにしてはいけません。
例: 犬
クラスの 吠える
メソッドにはstaticを付けない。吠えるのは個々の犬だから
→わかりづらいかも、、
②オーバーライドされる予定がない
言語によるかもしれませんが、例えばC#はstaticメソッドをオーバーライドできません。
オーバーライドを前提としたメソッドは、インスタンスメソッドとして定義する必要があります。
③状態に依存しない
属性の参照・変更がなく、引数と戻り値のみで完結する場合のみ使うべきです。
staticな属性は参照・変更できますが、望ましくありません。
使いみち
私はファクトリメソッドとユーティリティメソッドしかstaticにしません。(今思いつく限りでは)
他に有用な使いみちがありましたら、教えていただけると嬉しいです。
①ファクトリメソッド
TBD
static void create {
}
②ユーティリティメソッド
TBD
static string {
}
おまけ: privateメソッドをstaticにするかどうか
状態に依存しないprivateメソッドをstaticにするか迷ったことはありませんか?
privateメソッドの呼び出し元がstaticの場合はstaticにしなければいけませんが、インスタンスメソッドから呼び出す場合はstaticにしなくても言語仕様上は問題ありません。
状態に依存しないことを保証するため、privateメソッドをstaticにするのは有用です。
しかしstaticメソッドは同一クラスから呼び出す場合でもクラス名を省略できない言語が多いです。
私はスッキリ書くことを優先し、 必要でない限りはprivateメソッドをstaticにしません 。
まとめ
TBD