状態のないインスタンス化可能なクラスが非常に多いのはなぜですか?


18

C ++とJavaの世界には、状態のないインスタンス化可能なクラスがたくさんあります。

私は本当に人々がそれをする理由を理解することはできません。C++の無料の関数で名前空間を使用するか、Javaのプライベートコンストラクタと静的メソッドのみを持つクラスを使用できます。

私が考えることができる唯一の利点は、後で特定の状況で異なる実装が必要だと判断した場合、ほとんどのコードを変更する必要がないことです。しかし、それは時期尚早な設計の場合ではありませんか?それが適切になった場合に/後でクラスに変えることができます。

これは間違っていますか?すべてをオブジェクト(つまり、インスタンス化されたクラス)に入れないと、OOPになりませんか?それでは、なぜC ++とJavaの標準ライブラリに非常に多くのユーティリティ名前空間とクラスがあるのですか?

更新: これまでの仕事で確かに多くの例を見てきましたが、オープンソースの例を見つけるのに苦労しています。それでも、私は人々がなぜそれをするのか、それがどれほど一般的であるのか疑問に思っています。


2
「とても一般的」を定量化せずに答えるのは難しい。よく見かけるとは言えません。Qを「ivarのないクラスはどのように役立つか」などのように変更することを検討してください。
カレブ

@Calebオープンソースプロジェクトの例を探します。私が働いていたJavaショップで間違いなくよく見かけました。
futlib

@futlib:はい、それは一般的です。stackoverflow.com/questions/4692845/...
ホアンロング

例えばのみを含むクラスを検討しますか。EntityManagerに状態が含まれていませんか?
user470365

回答:


22

C ++とJavaの世界には、状態のないインスタンス化可能なクラスがたくさんあります。

独自のivarなしでクラスを作成するいくつかの考えられる理由:

  • 状態はスーパークラスに含まれるか、含まれる可能性があります。

  • クラスは何らかのインターフェイス実装し、インスタンスを他のオブジェクトに渡すことができるようにインスタンス化可能である必要があります。

  • クラスはサブクラス化されることを意図しています。

  • 関連する機能をグループ化する便利な方法。(はい、同じことをするより良いまたは異なる方法があるかもしれません。)

これは間違っていますか?すべてをオブジェクト(つまり、インスタンス化されたクラス)に入れないと、OOPになりませんか?

OOPはパラダイムであり、自然の法則ではありません。すべてがオブジェクトであるいくつかの言語があるので、あなたには本当に選択肢がありません。他の言語(Cなど)はOOPをまったくサポートしませんが、オブジェクト指向スタイルでプログラミングできます。クラスですべてをやらなくてもOOPを使用できると思いますが、その場合はOOP が少ないと言うかもしれません。


4

CalebとRobert Harveyは、ユーティリティクラスとは何か、および「データレス」クラスを持つ正当な理由をすでに指摘しています。これらの説明はスポットオンですが、肯定的な側面を扱います。

ユーティリティクラスの不正使用は、間違いなくオブジェクト指向のアンチパターンになる可能性があることに言及したいと思います(c2wikiの説明を参照)。この引用はそれをうまくまとめています:

このようなクラスが多数ある場合(特に、メソッドが1つしかないクラス)は、設計者が逆さまに考えていることを示しています。オブジェクトによってできることではなく、オブジェクトに対してできることを考える。

オブジェクト指向設計を実践していると主張しているが、コードベースがほぼ完全にユーティリティクラスで構成されている場合、間違いを犯していると思います。これを言って、機能的なアプローチには同じくらい多くの利点があります、そして、一緒に働くのにも優れていることができます。片方をフォローしていると主張しないでください。もう片方を中途半端に実装してください。


2

JavaおよびC ++のユーティリティクラスは、1つ以上の入力パラメーターを受け取り、結果を返すメソッドのライブラリを維持するために使用されます。値を返すだけであれば、状態を保持する必要はありません。その点で、これらの方法は、そのすべての利点を備えた関数プログラミングの大まかな形式と見なすことができます(1つは、並行性の問題はありません)。

いずれにせよ、これらのクラスは、関連するメソッドを単一のコンテナにグループ化する役割を果たします。これらのメソッドは、適切に動作するためにオブジェクトのインスタンス化を必要としません。このようなクラスの例は、SINEおよびCOSINE(およびその他の数学)関数を含むMathクラスです。


2

これらのクラスの多くは、明示的に含まれていなくても、データとやり取りします。複数の同時インスタンスをアクティブにする必要がある方法でやり取りする必要があります。たとえば、データベースストアドプロシージャとやり取りするステートレスセッションBeanは、着信データをPL / SQLパッケージに渡し、結果を呼び出し元アプリケーションに返します。そのものは複数のインスタンスに存在する必要がありますが、それ自体にはデータフィールドが含まれていません。


0

クラスがオブジェクトではないオブジェクト指向言語では、クラスよりもオブジェクトで多くのことができます。

オブジェクトをパラメーターとして渡すことができ、タイプ互換オブジェクトに置き換えることができ、インターフェースを実装できます(クラスがオブジェクトである言語があると思いますが、これらのいくつかを行うことができますが、いずれにしても...) 。これらはすべて非常に重要なので、デフォルトの決定は通常、クラスをインスタンス化可能にすることです。

一部のクラスでは、インスタンス化によって付与される機能が必要になる可能性は低いようです。たとえば、コサインの実装を別のものに交換する必要はおそらくないでしょう。ほとんどの場合、これらの機能を必要としないユーティリティ関数であるため、インスタンス化できないクラスを持つユーティリティ関数がほとんどです。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.