設計模式——策略模式

1、引言

  十一黃金週,對於像咱們這些屌絲來講,確實是個不錯的出遊時機,惋惜的就是這個假期是public的,並非我等屌絲獨佔的。真是有種生前活在人堆裏的感慨,這時候選擇交通工具是異常的重要,筆者回家須要通過深汕高速,每逢節假日,高速基本都會成爲免費停車場的,加之國慶免費,真是雪上加霜啊。今天我所寫的就是以選擇交通工具爲題闡述一下策略模式吧。java

2、策略模式

  1. 定義:定義一組算法,將每一個算法都封裝起來,並使他們之間能夠互換。算法

  2. 類圖:【以下圖所示】設計模式

  3. 類圖說明:ide

    3.1 ITransport:策略抽象類,定義每一個算法必須具備的方法和屬性。    工具

    3.2 Plane,Train,Car:策略中一組算法。this

    3.3 Context:上下文角色,封裝算法提供客戶端調用的。    spa

3、策略示例代碼

  1. 策略抽象類設計

package com.pattern.stratgy.core;

/**
 * 策略接口——交通工具
 * @author yemaoan
 *
 */
public interface ITransport {
    
    void buyTicket();
}

  2. 具體策略(算法)code

    2.1 選擇火車對象

package com.pattern.stratgy.core;

public class Train implements ITransport {

    @Override
    public void buyTicket() {
        System.out.println("選擇坐火車,硬座還比較划算");

    }

}

    2.2 選擇飛機

package com.pattern.stratgy.core;

public class Plane implements ITransport {

    @Override
    public void buyTicket() {
        System.out.println("選擇坐飛機吧,快速,便捷,關鍵啊,是不會塞車...");

    }

}

    2.3 選擇汽車

package com.pattern.stratgy.core;

public class Car implements ITransport {

    @Override
    public void buyTicket() {
        System.out.println("選擇坐汽車,堵就堵吧");

    }

}

   3. Context封裝角色

package com.pattern.stratgy.core;

/**
 * 封裝角色
 * @author yemaoan
 *
 */
public class Context {

    private ITransport transport;
    
    public Context(ITransport transport) {
        this.transport = transport;
    }
    
    public void buyTicket() {
        this.transport.buyTicket();
    }
}

  4. JunitTest

 

package com.pattern.strategy.test;

import org.junit.Test;

import com.pattern.stratgy.core.Context;
import com.pattern.stratgy.core.ITransport;
import com.pattern.stratgy.core.Train;

public class TestStrategy {

    @Test
    public void testStrage() {
        //生平就差火車,動車沒坐過了,讓我也過一下火車癮吧
        ITransport transport = new Train();        //生成策略對象,這樣Client就知道得太多了,不該該啊,這是病,得醫~
        Context context = new Context(transport);
        context.buyTicket();
    }
}

4、策略改進方法

  其實單純的策略模式的弊病已經在上面的代碼中表現得很明顯了,在客戶端調用時已經把當前的策略暴露出去了,怎麼解決?讓工廠幫一下忙吧,讓咱們看一下下面的一段代碼。

  1. 策略工廠

package com.pattern.stategy.factory;

import com.pattern.stratgy.core.ITransport;

/**
 * 設計模式老朋友了——策略工廠類
 * @author yemaoan
 *
 */
public class StrategyFactory {

    public static <T extends ITransport> T getTransport(Class<T> cls) {
        ITransport transport = null;
        try {
            transport = (ITransport) Class.forName(cls.getName()).newInstance();
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
        return (T) transport;
    }
    
    public static <T extends ITransport> T getTransport(String code) {
        return (T) getTransport(new ContentService().get(code));
    }
}

  2. 算法值映射類

package com.pattern.stategy.factory;

import java.util.HashMap;
import java.util.Map;

import com.pattern.stratgy.core.Car;
import com.pattern.stratgy.core.Plane;
import com.pattern.stratgy.core.Train;

/**
 * 算法映射
 * @author yemaoan
 *
 */
public class ContentService {

    private Map<String, Class> contentMap = new HashMap<String, Class>();
    
    public ContentService() {
        contentMap.put("train", Train.class);
        contentMap.put("plane", Plane.class);
        contentMap.put("car", Car.class);
    }
    
    public Class get(String key) {
        return contentMap.get(key);
    }
}

  3. JunitTest【Client】

package com.pattern.strategy.test;

import org.junit.Test;

import com.pattern.stategy.factory.StrategyFactory;
import com.pattern.stratgy.core.Context;
import com.pattern.stratgy.core.ITransport;
import com.pattern.stratgy.core.Train;

public class TestStrategy {

    @Test
    public void testStrage() {
        //生平就差火車,動車沒坐過了,讓我也過一下火車癮吧
        ITransport transport = new Train();        //生成策略對象,這樣Client就知道得太多了,不該該啊,這是病,得醫~
        Context context = new Context(transport);
        context.buyTicket();
    }
    
    @Test
    public void testStrategy() {
        ITransport transport = StrategyFactory.getTransport("train");    //讓工廠模式幫了我一把
        Context context = new Context(transport);
        context.buyTicket();
    }
}

5、總結

  1. 本文是對策略模式的一個闡述,策略其實也算是一個比較好理解的模式吧。固然單純的使用策略模式是不太現實的,由於它會把算法徹底的暴露給調用者,兵家之大忌啊。

  2. 針對策略模式的一些不足,筆者採用了工廠模式去解決,使得客戶端調用時,只須要根據特定的code來獲取相應的算法策略,而避免直接new算法策略。

相關文章
相關標籤/搜索