Cuando estoy programando en Java (o en un lenguaje similar), a menudo empleo una versión simple del patrón de Estrategia, usando interfaces y clases de implementación, para proporcionar implementaciones seleccionables en tiempo de ejecución de un concepto particular en mi código.¿Mejor alternativa al patrón de estrategia en Scala?
Como un ejemplo muy artificial, me gustaría tener el concepto general de un Animal que puede hacer ruido en mi código Java, y quiero poder seleccionar el tipo de animal en tiempo de ejecución. Así que escribiría el código en estas líneas:
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();
...
}
Bastante simple. Recientemente, sin embargo, he estado trabajando en un proyecto en Scala y quiero hacer lo mismo. Parece bastante fácil de hacer esto usando rasgos, con algo como esto:
trait Animal {
def makeNoise:Unit
}
class Cat extends Animal {
override def makeNoise:Unit = println("Meow")
}
class AnimalContainer {
val myAnimal:Animal = new Cat
...
}
Sin embargo, esto parece muy similar a Java y no muy funcional - por no hablar de que los rasgos y las interfaces no son realmente la la misma cosa. Así que me pregunto si existe una forma más idiomática de implementar el patrón de Estrategia, o algo parecido, en mi código de Scala para poder seleccionar una implementación concreta de un concepto abstracto en tiempo de ejecución. ¿O está usando los rasgos de la mejor manera de lograr esto?
Gracias, Daniel! Seleccioné esta respuesta porque es más amigable con el código preexistente (que es más OO que funcional). La respuesta de @VonC también es genial, y probablemente la use cuando trabaje de una manera más funcional. código base – MattK