この文章みてください。
オレはもう20年以上システム業界にいるけどな、その長い経験から言うと、オブジェクト指向なんてものは、理論としては面白いけど、およそ実用的とは言い難いものだな。まぁ、例えばGUIのコンポーネントとかはオブジェクト指向に基づいて作られているようだから、そういうツールとかを作る人には必要なものなのかもしれない。しかし君たちがいずれ作ることになる業務アルゴリズムにはまったく無縁のものだと思ってもらって間違いない。どうもこの業界、オブジェクト指向でなければダメ、というような風潮がまかりとおっているけどな、オブジェクト指向なんか本当に使っている人はほとんどいないよ。オレも少し勉強してみたけど、カプセル化とかポリ何とかとか、どうにも利点が理解できなかったね。実際、実業務で使ったことなどないしな……
「またお前、オブジェクト指向の話をしてるのか」と思ったかもしれませんが、2010年の架空の開発現場での登場人物の話です。
高慢と偏見(1)隣は何をする人ぞ:Press Enter■:エンジニアライフ
この発言に主人公たちは眉をひそめるのですが、今みると全く当たり前のことを言っているように思います。カプセル化は理解してほしい気はしますが。
そしてstaticを勧める。
「staticを使えばインスタンス宣言などしなくてもいいんだよ。どっちが楽か分かるだろ? いちいちインスタンス宣言するなんておかしいよ」
「staticおじさん」という言葉があります。この物語に出てくる三浦マネージャーのような人をさして、staticだけではなく技術についていけていないことを揶揄するように使われます。
けど、ここでのコードは研修のサンプルコードの話で、例えばフィボナッチを次のように書いてた感じに思います。
public class Fib { public static void main(String[] args) { Fib f = new Fib(); System.out.println(f.calc(5)); } int calc(int n) { if (n <= 1) return n; return calc(n - 1) + calc(n - 2); } }
calcをstaticにしてしまえば「インスタンス宣言」などしなくていいです。Fibのオブジェクトの必要性はないですね。
public class Fib { public static void main(String[] args) { System.out.println(calc(5)); } static int calc(int n) { if (n <= 1) return n; return calc(n - 1) + calc(n - 2); } }
Javaのstaticはクラスをネームスペースとして使う機能で、クラスを拡張版packageとして使う機能といえます。importも使えますね。
この時期、なぜかstaticではなく「インスタンス宣言」したほうがいいという風潮でした。「プロJava」の書評にも「著者が static 好きすぎ」と書かれてたりするので意味なくstaticを忌避する風潮は残ってるようですが。
この後も
「私の経験から言うとコードレビューはデバッグに非常に有効にもかかわらず、このプロジェクトでは月に1回も実施されていないようなので、ここらでビシッと引き締めたいね」
とコードレビューを勧めると
「ここのメンバーはコードレビューが必要なレベルではありません。全員が自分が書くコードの意味を理解しているし、それを実装する能力も十分です。また、それぞれ所属する会社としての文化も違うわけですし……」
と、主人公陣営から反論が来たりしています。
高慢と偏見(2)使徒襲来:Press Enter■:エンジニアライフ
2010年はGitHubもまだ会社ができたばかりで、プルリクエストによるコードレビューは知られておらず、紙ベースでみんなで集まってレビューしていますが、コードレビューについては今では常識になったことを言っています。
そのあとも、変なコード分割をするなとか、割とまっとうなことを言ってるはずですが、主人公たちからは受け入れられません。
GCやバージョン管理システムを知らなかったり、方向性はいいけどツールに疎いという感じではありますが。あと態度が悪い。
けど、主人公たちも「今までやってたから」「良いと言われてるから」くらいしか理由を説明できないにも関わらず、三浦マネージャ不在のときに一気にコードを進めて既成事実化したり、あまりよくない。
主人公たちが「staticだからダメ」「オブジェクト指向じゃないからダメ」という「オブジェクト指向おじさん」になってるようにも見えますね。主人公は女性のようだけど。
「staticおじさん」三浦マネージャの、staticに関する話の元ネタはこれなのかもしれない。
「メンバー関数をstatic宣言すればインスタンス宣言をしなくてもいい」ということ知ってからは、メンバー関数を従来のファンクションのように使っている。共有変数も、pubulic static宣言していまう
実はオブジェクト指向ってしっくりこないんです!:気分はstatic!:エンジニアライフ
この内容も用語の使い方が甘い部分はあるものの、そこまで間違ってないように見える。
ようやく、オブジェクト指向だからよい、オブジェクト指向じゃないからよくない、というような空気が薄れて、時代がstaticおじさんに追いついてきた感じがある。
追記
三浦マネージャも主人公側も変なことを言ってる部分があってどっちもどっちなのに、三浦マネージャのいい部分、主人公側の悪い部分だけとりあげて、オブジェクト推進派への嫌悪感が表れているという指摘があったのだけど、まあ「static好きすぎ」という書評への嫌悪感が表れてしまってますね・・・
「プロになるJava」で例えばこんな感じで、サンプルで出てくるメソッドなどは、インスタンスが必要なければstaticメソッドとして定義しています。
public class Sample { public static void main(String[] args) { foo(); } static void foo() { System.out.println("Hello"); } }
これ別に、Java 21に入った試用機能でmainを簡潔に書くとこう書けるんですね。staticかどうかはJavaコマンドの都合であって本質的ではない。
public class Sample { void main() { foo(); } void foo() { System.out.println("Hello"); } }
既存の機能の範囲でも、無用にインスタンスを作って無理矢理インスタンスメソッドにしているサンプルをよくみかけます。
public class Sample { public static void main(String[] args) { Sample s = new Sample(); s.foo(); } void foo() { System.out.println("Hello"); } }
シングルトンにすると、フィールドもグローバル変数化するのでstaticと問題は変わらなくなるし、DIコンテナ使った場合もコンテナはグローバル変数置き場なので同様です。
そうやって、単に「staticロンダリング」のようなことをして実質はstaticのようなコードを書きつつ「staticじゃないからヨシ」みたいなことしてるんではと思ってたところにstaticおじさんの話題が出てきたので勢いで書いてしまったらこうなった。