Java设计模式之策略模式

strategy_logo

在开发中我们会使用很多中间件,开发过程当然是单机配置,可是上生产环境的时候如何快速切换到集群配置,总不能修改代码吧,这里我们就可以结合Spring来使用策略模式。


一、什么是策略模式?

在开发中常常遇到这种情况,实现某一个功能有多方式,我们可以根据不同的条件选择不同的方式来完成该功能。最常用的方法是将这些算法方式写到一个类中,在该类中提供多个方法,每一个方法对应一个具体的算法;或者通过if…else…或者case等条件判断语句来进行选择。
然而该类代码将较复杂,维护较为困难。如果我们把一个类中经常改变或者将来可能改变的部分提取出来,作为一个接口,然后在类中包含这个对象的实例,这样类的实例在运行时就可以随意调用实现了这个接口的类的行为。这就是策略模式。

二、基本的策略模式使用方法

我们直接来看例子:
1.策略接口

/**
 * Description: Strategy Pattern Interface
 * Created at:	2017/12/18
 */
public interface Strategy {
    void testStrategy();
}

2.准备两个实现类

/**
 * Description: 实现类A
 * Author:	lllx
 * Created at:	2017/12/18
 */
public class StrategyA implements Strategy {
    @Override
    public void testStrategy() {
        System.out.println("我是实现类A");
    }
}

/**
 * Description: 实现类B
 * Author:	lllx
 * Created at:	2017/12/18
 */
public class StrategyB implements Strategy {
    @Override
    public void testStrategy() {
        System.out.println("我是实现类B");
    }
}

3.策略执行Context类

/**
 * Description: 策略执行
 * Author:	lllx
 * Created at:	2017/12/18
 */
public class Context {
    
    private Strategy stg;
    
    public void doAction() {
        this.stg.testStrategy();
    }
    /*  Getter And Setter */
    public Strategy getStg() {
        return stg;
    }

    public void setStg(Strategy stg) {
        this.stg = stg;
    }
}

这时候我们准备一个main方法来测试一下他

/**
 * Description: StrategyTest
 * Author:	lllx
 * Created at:	2017/12/18
 */
public class StrategyTest {
    public static void main(String[] args) {
        Strategy stgB = new StrategyB();
        Context context = new Context(stgB);
        context.setStg(stgB);
        context.doAction();
    }
}

运行结果:
strategy_1
实例化不同的实现类可以出现不同的结果。

三、与Spring想结合的策略模式

我们主要利用Spring的核心IOC来实现它,还是使用上面的例子;
由于我们要在Spring的配置文件中来注入Context的实例:

	<bean id="context" class = "top.catalinali.search.service.impl.Context">
		<property name="stg" ref="stgB"/>
	</bean>
	<bean id="stgA" class = "top.catalinali.search.service.impl.StrategyA"/>
	<bean id="stgB" class = "top.catalinali.search.service.impl.StrategyB"/>

这样就可以通过只修改配置文件来更改context的实现类,从而达到策略模式的目的。

四、通过Spring使用策略模式替换中间件的单机与集群配置

在开发环境中,许多中间件使用的是单机配置。可到了生产我们就需要使用集群配置。这里我们就可以通过策略模式来快速改变中间件的配置,现在我们以Redis为例:
1.策略接口
首先我们把Redis方法抽成一个接口

public interface JedisClient {
	String set(String key, String value);
	String get(String key);
	Boolean exists(String key);
	Long expire(String key, int seconds);
	Long ttl(String key);
	Long incr(String key);
	Long hset(String key, String field, String value);
	String hget(String key, String field);
	Long hdel(String key, String... field);
	Boolean hexists(String key, String field);
	List<String> hvals(String key);
	Long del(String key);
}

2.单机和集群两个实现类
这里我们准备单机和集群两个实现类:JedisClientPool和JedisClientCluster。实现上面的JedisClient接口,分别使用单机和集群的代码来实现这些方法。因为代码冗长就不在这里贴出来了。
3.配置文件
我们使用不同的环境只需要把不用的配置注释掉就好。

	<!-- 连接redis单机版 -->
	<bean id="jedisClientPool" class="top.catalinali.common.jedis.JedisClientPool">
		<property name="jedisPool" ref="jedisPool"></property>
	</bean>
	<bean id="jedisPool" class="redis.clients.jedis.JedisPool">
		<constructor-arg name="host" value="192.168.72.121"/>
		<constructor-arg name="port" value="6379"/>
	</bean>
	<!-- 连接redis集群 -->
	<!-- <bean id="jedisClientCluster" class="cn.e3mall.common.jedis.JedisClientCluster">
		<property name="jedisCluster" ref="jedisCluster"/>
	</bean>
	<bean id="jedisCluster" class="redis.clients.jedis.JedisCluster">
		<constructor-arg name="nodes">
			<set>
				<bean class="redis.clients.jedis.HostAndPort">
					<constructor-arg name="host" value="192.168.25.162"></constructor-arg>
					<constructor-arg name="port" value="7001"></constructor-arg>
				</bean> 
				<bean class="redis.clients.jedis.HostAndPort">
					<constructor-arg name="host" value="192.168.25.162"></constructor-arg>
					<constructor-arg name="port" value="7002"></constructor-arg>
				</bean> 
				<bean class="redis.clients.jedis.HostAndPort">
					<constructor-arg name="host" value="192.168.25.162"></constructor-arg>
					<constructor-arg name="port" value="7003"></constructor-arg>
				</bean> 
				<bean class="redis.clients.jedis.HostAndPort">
					<constructor-arg name="host" value="192.168.25.162"></constructor-arg>
					<constructor-arg name="port" value="7004"></constructor-arg>
				</bean> 
				<bean class="redis.clients.jedis.HostAndPort">
					<constructor-arg name="host" value="192.168.25.162"></constructor-arg>
					<constructor-arg name="port" value="7005"></constructor-arg>
				</bean> 
				<bean class="redis.clients.jedis.HostAndPort">
					<constructor-arg name="host" value="192.168.25.162"></constructor-arg>
					<constructor-arg name="port" value="7006"></constructor-arg>
				</bean> 
			</set>
		</constructor-arg>
	</bean> -->

这样在我们开发时只需要注释掉连接集群的配置,而在上线时注释掉单机的配置就好。

参考文章

spring与策略模式


本文作者: catalinaLi
本文链接: http://catalinali.top/2017/strategyPattern/
版权声明: 原创文章,有问题请评论中留言。非商业转载请注明作者及出处。

已标记关键词 清除标记
1) 优秀的程序应该是这样的:阅读时,感觉很优雅;新增功能时,感觉很轻松;运行时,感觉很快速,这就需要设计模式支撑。<br /> <br /> 2) 设计模式包含了大量的编程思想,讲授和真正掌握并不容易,网上的设计模式课程不少,大多讲解的比较晦涩,没有真实的应用场景和框架源码支撑,学习后,只知其形,不知其神。就会造成这样结果: 知道各种设计模式,但是不知道怎么使用到真实项目。本课程针对上述问题,有针对性的进行了升级 (1) 授课方式采用 图解+框架源码分析的方式,让课程生动有趣好理解 (2) 系统全面的讲解了设计模式,包括 设计模式七大原则、UML类图-类的六大关系、23种设计模式及其分类,比如 单例模式的8种实现方式、工厂模式的3种实现方式、适配器模式的3种实现、代理模式的3种方式、深拷贝等<br /> <br /> 3) 如果你想写出规范、漂亮的程序,就花时间来学习下设计模式吧<br /> <br /> 课程内容和目标<br /> <br /> 本课程是使用Java来讲解设计模式,考虑到设计模式比较抽象,授课采用 图解+框架源码分析的方式<br /> <br /> 1) 内容包括: 设计模式七大原则(单一职责、接口隔离、依赖倒转、里氏替换、开闭原则、迪米特法则、合成复用)、UML类图(类的依赖、泛化和实现、类的关联、聚合和组合) 23种设计模式包括:创建型模式:单例模式(8种实现)、抽象工厂模式、原型模式、建造者模式、工厂模式。结构型模式:适配器模式(3种实现)、桥接模式、装饰模式、组合模式、外观模式、享元模式、代理模式(3种实现)。行为型模式:模版方法模式、命令模式、访问者模式、迭代器模式、观察者模式、中介者模式、备忘录模式、解释器模式(Interpreter模式)、状态模式策略模式、职责链模式(责任链模式)<br /> <br /> 2) 学习目标:通过学习,学员能掌握主流设计模式,规范编程风格,提高优化程序结构和效率的能力。<br /> <div> <br /> </div>
相关推荐
©️2020 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页