Scala が Singleton アンチパターンを言語サポートしているのはなぜですか? Scala がstatic
Java からキーワードを継承していた場合、キーワードの正当な使用例としてどのようなものobject
が残されるでしょうか?
4 に答える
少なくとも、object
Scala の an は実際にはオブジェクト (つまりインスタンス) であり、クラス自体で呼び出されるメソッドである Java とは異なります。
これは、シングルトンに関する主な不満の 1 つを回避することを意味します。これはインスタンスであるため、渡してメソッドに接続することができ、テストなどで他の実装と交換することができます。シングルトンの推奨される代替手段 -getInstance()
デフォルトの単一インスタンスを返すメソッドを持つクラスを持つ。
とはいえ、Singleton のアンチパターンは、言語機能というよりもデザインに関するものだと思います。モノリシックな依存関係がほとんどのクラス全体に暗黙的に配線されるようにコード ベースを構成すると、言語機能に関係なく、コード ベースを変更する際に問題が発生します。
objects
Scalaには正当な使用例があります(たとえば、 Actors へのメッセージにcase objects
使用したり、それらのいくつかを enumsの代わりに拡張したりする)。言語機能は悪用される可能性がありますが、私の考えでは、Java の よりも悪用されにくく、より便利です。sealed trait
static
状態のないシングルトンはそれほど悪くありません。オブジェクト (scala 内) は、関数 (動作) を配置するためのモジュールと見なされます。
オブジェクトを使用して状態を保持する場合、それはシングルトンが災害であるケースです。これは、それをクリアする方法がない可能性があり、それがアンチパターンであるシングルトンの代表的な例の 1 つであるためです。ミュータブルな状態を持たず、純粋な関数を持つオブジェクトは、この点で痛みを引き起こす可能性がはるかに低くなります。以下に例を示します。
object StringSerializer extends Serializer[String] {
// Implementation goes here.
}
この場合、Serializer のインスタンスを新たに作成する必要はありません。これにより、コードが単純になり、パフォーマンスが向上する可能性があります。
たとえば、型クラス。静的クラスとシングルトンの違いは、シングルトンはオブジェクトであり、パラメーターとして渡すことができるということです。たとえば、次のコードは静的クラスで構築できませんでした。
trait TypeClass[A] {
def method(x: A): A
}
implicit object IntTypeClass extends TypeClass[Int] {
def method(x: Int) = x*x
}
def foo[A](x: A)(implicit tc: TypeClass[A]) = tc.method(x)
scala> foo(2)
res0: Int = 4