当我使用 Java(或类似语言)进行编程时,我经常使用简单版本的策略模式,使用接口和实现类,在我的代码中为特定概念提供运行时可选择的实现。
作为一个非常人为的示例,我可能希望在我的 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 代码中是否有更惯用的方式来实现策略模式(或类似的东西),以便我可以在运行时选择抽象概念的具体实现。还是使用特征是实现这一目标的最佳方式?