Java(または同様の言語)でプログラミングしているときは、インターフェイスと実装クラスを使用して、単純なバージョンのStrategyパターンを使用して、コード内の特定の概念の実行時に選択可能な実装を提供することがよくあります。
非常に工夫された例として、Javaコードでノイズを発生させる可能性のある動物の一般的な概念を持ち、実行時に動物のタイプを選択できるようにしたい場合があります。だから私はこれらの行に沿ってコードを書くでしょう:
interface Animal {
void makeNoise();
}
class Cat extends Animal {
void makeNoise() { System.out.println("Meow"); }
}
class Dog extends Animal {
void makeNoise() { System.out.println("Woof"); }
}
class AnimalContainer {
Animal myAnimal;
AnimalContainer(String whichOne) {
if (whichOne.equals("Cat"))
myAnimal = new Cat();
else
myAnimal = new Dog();
}
void doAnimalStuff() {
...
// Time for the animal to make a noise
myAnimal.makeNoise();
...
}
十分に単純です。しかし最近、私はScalaでプロジェクトに取り組んでおり、同じことをしたいと思っています。次のような特性を使用してこれを行うのは簡単なようです。
trait Animal {
def makeNoise:Unit
}
class Cat extends Animal {
override def makeNoise:Unit = println("Meow")
}
class AnimalContainer {
val myAnimal:Animal = new Cat
...
}
ただし、これはJavaに非常に似ており、機能的ではないようです。言うまでもなく、特性とインターフェースは実際には同じものではありません。ですから、実行時に抽象的な概念の具体的な実装を選択できるように、Scalaコードにストラテジーパターン(またはそのようなもの)を実装するためのより慣用的な方法があるかどうか疑問に思っています。それとも、これを達成するための最良の方法は特性を使用していますか?