public interface Animal {
void speak();
}
public class Dog implements Animal{
void speak (){
System.out.println("This is dog.")
}
}
public class Cat implements Animal{
void speak (){
System.out.println("This is cat.")
}
}
@Module
public class Module{
@Provides
@Named("Dog")
static Animal providesDog() {
return new Dog();
}
@Provides
@Named("Cat")
static Animal providesCat() {
return new Cat();
}
}
public class AnimalOrchestrator {
@Inject
Animal animal;
public void speak(String type) {
if(type.equals("dog")
(Dog) animal.speak();
else
(Cat) animal.speak();
}
}
在运行时我们确定 Animal 对象应该转换为哪个 Dog/Cat 对象时,这种类型转换是否可能?
以下是实现此类功能的其他一些方法。
public class AnimalOrchestrator {
@Inject
Dog dog;
@Inject
Cat cat;
public void speak(String type) {
if(type.equals("dog")
dog.speak();
else
cat.speak();
}
}
上面的代码有一个缺点,我们需要创建狗和猫的对象,尽管只会使用上面的其中之一。
另一种方法如下:
public class AnimalOrchestrator {
Animal animal;
public void speak(String type) {
if(type.equals("dog"){
animal = new Dog();
animal.speak();
} else {
animal = new Cat();
animal.speak();
}
}
}
有了这个,我们必须使用我想避免的 new 运算符创建这个对象,以便利用依赖注入。
第一个解决方案可能吗?如果是的话,哪个更好?
在回答这个问题之前,我应该注意到我没有使用@Inject Annotation,但我认为代码可以与它一起使用。
现在您要求的是复合模式。
使用类型变量来确定哪种动物是猫还是狗违反了开闭原则。您的代码可供修改。将来每当您需要新动物时,您都将添加新的类型检查代码。这意味着您的 AnimalOrchestrator 会发生很多变化,并且可能会导致很多错误。
现在答案是这样的;
public interface Animal {
void speak();
}
public class Cat implements Animal {
@Override
public void speak() {
System.out.println("This is Cat");
}
}
public class Dog implements Animal {
@Override
public void speak() {
System.out.println("This is Dog");
}
}
public class Mammals implements Animal {
private List<Animal> animalList;
public Mammals(Animal... animals){
this.animalList = Arrays.asList(animals);
}
@Override
public void speak() {
for(Animal animal : this.animalList){
animal.speak();
}
System.out.println("This is Mammals");
}
}
请注意,您的 AnimalOrchestrator 类将以这种方式成为我的 Mammals 类