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/
版权声明: 原创文章,有问题请评论中留言。非商业转载请注明作者及出处。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,445评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,889评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,047评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,760评论 1 276
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,745评论 5 367
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,638评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,011评论 3 398
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,669评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,923评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,655评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,740评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,406评论 4 320
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,995评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,961评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,197评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,023评论 2 350
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,483评论 2 342

推荐阅读更多精彩内容

  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,594评论 18 139
  • Spring Boot 参考指南 介绍 转载自:https://www.gitbook.com/book/qbgb...
    毛宇鹏阅读 46,733评论 6 342
  • 一、什么是策略模式 策略模式属于对象的行为模式。其用意是针对一组算法,将每一个算法封装到具有共同接口的独立的类中,...
    雅俗共赏M阅读 460评论 0 0
  • 梧桐 枇杷 桃子 长在眼睛和身体里 黑夜 琥珀 鱼肚 潜伏它山之巅 黎明 纷纷的雪落下 黎明 熙熙的白落下
    Shakuntala阅读 198评论 0 1
  • 时间过得真快转眼就到高二了,我们又要步入新的学习,我总感觉我就像新来的新生一样,不知道要作什么,干什么,心里总...
    成败火阅读 182评论 1 1