设计模式(⼆)--策略模式实践--基于@Autowired注解实现(Autowired集合注
⼊)
以下代码可通过以下链接获得。
什么是策略模式
策略模式指的是对于同样的⼀件事情,根据不同的场景给出不同的策略来解决同⼀件事情。⽐较好理解的⼀个例⼦就是,我们定义⼀个打招呼事件,每个⼈都可以实现打招呼这么⼀个事件。这样我们就定义⼀个打招呼的接⼝,然⽽不同国家的⼈,对打招呼有不同的实现。例如⼀个中国⼈,打招呼的时候说“你好!”,⼀个美国⼈打招呼的时候说“hello!”,⼀个⽇本⼈打招呼说“こんにちは“。假设我们写的是⼀个景区的道路指引系统的欢迎页,那么对于选择了不同语⾔的游客,要给出不同的招呼语。这就是⼀个简单的策略模式。
获取策略时,我们使⽤简单的⼯⼚模式来实现。根据输⼊的语⾔,来获取对应的策略实例。废话不多说,上代码。
代码实现
创建接⼝和实例
⾸先我们创建⼀个打招呼的接⼝,我们定义为GreetService。代码如下
public interface GreetService {
resource和autowired注解的区别// 打招呼⽅法,参数为⽤户名称
String sayHello(String name);
}
接⼝⾥⾯有⼀个打招呼⽅法,然后创建三个实现类,分别是中国⼈,美国⼈和⽇本⼈。
代码如下
中国⼈实现类
public class ChinaGreetServiceImpl implements GreetService {
public String sayHello(String name){
return"你好!"+ name;
}
}
美国⼈实现类
public class UsaGreetServiceImpl implements GreetService {
public String sayHello(String name){
return"Hello !"+ name;
}
}
⽇本⼈实现类
public class JapanGreetServiceImpl implements GreetService {
public String sayHello(String name){
return"こんにちは!"+ name;
}
}
然后我们创建⼀个Context对象,⽤来记录选⽤的策略,以及执⾏策略⽅法。public class GreetStrategyContext {
// 记录策略
private GreetService greetService;
// 选⽤的语⾔
private String language;
public void selectGreetStrategy(GreetService greetService){
}
public String getLanguage(){
return language;
}
public void setLanguage(String language){
this.language = language;
}
public String handel(String name){
Service.sayHello(name);
}
}
然后创建⼀个⼯⼚类,⽤来获取策略实例。
public class GreetStrategyFactory {
/**
* ⾃动注⼊所有的策略实例
*/
@Autowired
private Map<String, GreetService> greetServiceMap;
/**
* 根据语⾔返回对应的策略实例
*
* @param context
* @return
*/
public GreetService getGreetStrategyByLanguage(GreetStrategyContext context){ (Language());
}
}
如果是在spring项⽬中,可以在上⾯的对象上使⽤注解,让spring容器可以扫描到,并加载这些对象。这⾥我们采⽤简单的⼿动查⽅式,可以不⽤启动整个Spring容器。
⾸先需要创建实例,我们通过最常⽤的xml⽅式,创建实例。代码如下
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="/schema/beans"
xsi="/2001/XMLSchema-instance"
p="/schema/p"
schemaLocation="/schema/beans /schema/beans/spring-beans.xsd">
<!-- 打招呼实现类,id使⽤语⾔名称,⽅便查 -->
<bean id="chinese"class="org.designMode.demo.strategyMode.Strategies.ChinaGreetServiceImpl"/>
<bean id="japanese"class="org.designMode.demo.strategyMode.Strategies.JapanGreetServiceImpl"/>
<bean id="english"class="org.designMode.demo.strategyMode.Strategies.UsaGreetServiceImpl"/>
<!-- 创建Context实例 -->
<bean id="greetStrategyContext"class="org.designMode.demo.strategyMode.GreetStrategyContext"/>
<!-- 创建策略⼯⼚ -->
<bean id="greetStrategyFactory"class="org.designMode.demo.strategyMode.GreetStrategyFactory"/>
</beans>
下⾯,我们来创建Demo对象
public class SayHelloDemo {
@Resource
private GreetStrategyFactory greetStrategyFactory;
public static void main(String[] args){
// 创建上下⽂
AnnotationConfigApplicationContext applicationContext =new AnnotationConfigApplicationContext();
// 创建⼀个 definitionReader 对象
XmlBeanDefinitionReader definitionReader =new XmlBeanDefinitionReader(applicationContext);
// 定义 xml 配置⽂件相对路径
String xmlResourcePath ="l";
// 加载
definitionReader.loadBeanDefinitions(xmlResourcePath);
// 启动上下⽂
// 获取策略context
GreetStrategyContext greetStrategyContext =(Bean("greetStrategyContext");
// 获取⼀个⼯⼚类
GreetStrategyFactory greetStrategyFactory =(Bean("greetStrategyFactory");
// 设置策略使⽤的是英语 English
greetStrategyContext.setLanguage("english");
// ⼯⼚⽅法获取策略实例
GreetService greetService = GreetStrategyByLanguage(greetStrategyContext);
// 注⼊策略实例
greetStrategyContext.selectGreetStrategy(greetService);
// 执⾏策略⽅法
String helloWord = greetStrategyContext.handel("jeff");
// 打印结果
System.out.println(helloWord);
// 关闭上下⽂
applicationContext.close();
}
}
运⾏结果
org.designMode.demo.strategyMode.SayHelloDemo
Hello !jeff
Process finished with exit code 0
同样的,我们把使⽤的语⾔改成中⽂和⽇语,再试⼀次可得到对应的结果。
这就是⼀个简单的策略⽅法实例。
题外话
在⼯⼚⽅法⾥⾯,使⽤了@Autowired⽅法的特殊⽤法,集合注⼊。
/**
* ⾃动注⼊所有的策略实例
*/
@Autowired
private Map<String, GreetService> greetServiceMap;
这⾥spring容器会⾃动注⼊所有的GreetService接⼝的实现类,并把实例对象的名称放在map的key中,实例对象放在map的value中。这⾥的名称,即是xml⽂件中指定的id属性。换成name属性,也可以放到map的key中。spring的另⼀个注解@Resource也有同样的⽤法。
使⽤name也⼀样可以实现。
除此之外,集合注⼊还可以⽤List来承载。这样的注⼊,只会把所有的实现类放在list中,不会记录实现类的名称。
spring容器是怎么实现这个功能的呢?实际上是通过spring Ioc的依赖注⼊,按照类型注⼊的⽅式来实现的。因此,可以不使⽤
@Autowird或者@Resource注解,通过xml配置,⼿动配置依赖注⼊,也是可以实现的。
这⾥也提供两种⽅式
直接使⽤autowire属性
并设置为按类型注⼊
<!-- 创建策略⼯⼚ -->
<bean name="greetStrategyFactory"class="org.designMode.demo.strategyMode.GreetStrategyFactory"autowire="byType"/>
使⽤插件
使⽤xml⽂件配置的util插件,具体可以参照Spring官⽅⽂档。
配置代码如下
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论