美文网首页
Spring反射+策略模式替代switch/if-else

Spring反射+策略模式替代switch/if-else

作者: 那我懂你意思了_de16 | 来源:发表于2019-01-16 01:56 被阅读0次

如果switch/if-else分支不固定,或将来有可能改,可以采用反射+策略模式来替换switch/if-else语句。例如动物,随着种类变化,我们需要不断增加switch分支,这样我们就可以使反射+策略模式,使之更加灵活。

if-else方式:

Animal animal = new Animal();
if("dog".equals(type)) {
    animal = new Dog();
} if else("cat".equals(type)) {
    animal = new Cat();
}
animal.eat();

switch方式:

Animal animal = new Animal();
switch (type) {
    case "dog":
        animal  = new Dog();
        break;
    case "cat":
        animal  = new Cat();
        break;
}
animal.eat();

Spring反射+策略模式:

Animal接口(抽象策略角色):

public interface Animal {

    void eat();
}

Cat实现Animal接口(具体实现策略):

@Component
public class Cat implements Animal {

    @Override
    public void eat() {
        System.out.println("猫吃鱼");
    }
}

Dog实现Animal接口(具体实现策略):

@Component
public class Dog implements Animal {

    @Override
    public void eat() {
        System.out.println("狗啃骨头");
    }
}
  • @Component:将bean实例化交给spring容器管理。或者使用.xml配置文件<bean id="" class=""></bean>方式等等。

AnimalFactory类(环境角色):

@Service("animalFactory")
public class AnimalFactory implements ApplicationContextAware, InitializingBean {

    private Map<String, Animal> animalMap;

    private ApplicationContext applicationContext;

    @Override
    public void afterPropertiesSet() throws Exception {
        Map<String, Animal> animalMap = this.applicationContext.getBeansOfType(Animal.class);

        this.animalMap = animalMap;
    }

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        this.applicationContext = applicationContext;
    }

    public Animal getAnimal(String beanName) {
        return this.animalMap.get(beanName);
    }
}
  • 由于AnimalFactory类实现ApplicationContextAware接口,Spring容器会在创建AnimalFactory类之后,自动调用实现接口的setApplicationContextAware()方法,调用该方法时,会将ApplicationContext(容器本身)作为参数传给该方法,我们可以在该方法中将Spring传入的参数ApplicationContext赋给AnimalFactory对象的applicationContext实例变量,因此接下来可以通过该applicationContext实例变量来访问容器本身。
  • 实现InitializingBean接口,该接口提供了afterPropertiesSet方法。spirng容器在初始化bean的时候会执行afterPropertiesSet方法,我们可以在该方法中调用applicationContext接口提供的getBeansOfType方法获得实现Animal类的Bean,将之存储至map集合中。
存储bean

测试类:

@RunWith(SpringRunner.class)
@SpringBootTest
public class DemoApplicationTests {

    @Autowired
    private AnimalFactory animalFactory;

    @Test
    public void test() {
        Animal animal = animalFactory.getAnimal("dog");
//        Animal animal = animalFactory.getAnimal("cat");
        animal.eat();
    }

}

输出:

狗啃骨头


以后需求变更,只要增加实现类即可。

相关文章

网友评论

      本文标题:Spring反射+策略模式替代switch/if-else

      本文链接:https://www.haomeiwen.com/subject/exhpdqtx.html