Java設計模式之策略模式

strategy_logo

在開發中咱們會使用不少中間件,開發過程固然是單機配置,但是上生產環境的時候如何快速切換到集羣配置,總不能修改代碼吧,這裏咱們就能夠結合Spring來使用策略模式。

1、什麼是策略模式?

在開發中經常遇到這種狀況,實現某一個功能有多方式,咱們能夠根據不一樣的條件選擇不一樣的方式來完成該功能。最經常使用的方法是將這些算法方式寫到一個類中,在該類中提供多個方法,每個方法對應一個具體的算法;或者經過if…else…或者case等條件判斷語句來進行選擇。
然而該類代碼將較複雜,維護較爲困難。若是咱們把一個類中常常改變或者未來可能改變的部分提取出來,做爲一個接口,而後在類中包含這個對象的實例,這樣類的實例在運行時就能夠隨意調用實現了這個接口的類的行爲。這就是策略模式。java

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

咱們直接來看例子:
1.策略接口node

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

2.準備兩個實現類redis

/**
 * 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方法來測試一下他spring

/**
 * 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
實例化不一樣的實現類能夠出現不一樣的結果。ide

3、與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的實現類,從而達到策略模式的目的。this

4、經過Spring使用策略模式替換中間件的單機與集羣配置

在開發環境中,許多中間件使用的是單機配置。可到了生產咱們就須要使用集羣配置。這裏咱們就能夠經過策略模式來快速改變中間件的配置,如今咱們以Redis爲例:
1.策略接口
首先咱們把Redis方法抽成一個接口spa

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.配置文件
咱們使用不一樣的環境只須要把不用的配置註釋掉就好。code

<!-- 鏈接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/st... 版權聲明: 原創文章,有問題請評論中留言。非商業轉載請註明做者及出處。
相關文章
相關標籤/搜索