欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Java設(shè)計(jì)模式之策略模式詳解和示例

 更新時(shí)間:2024年01月18日 09:53:44   作者:小白不很白  
這篇文章主要介紹了Java設(shè)計(jì)模式之策略模式詳解和示例,策略模式就是一種行為可能會(huì)因?yàn)椴煌倪壿嬙斐啥鄠€(gè)算法,比如人吃飯,美國(guó)人吃飯用刀叉,中國(guó)吃飯用筷子,都是吃飯的行為但是使用的工具(算法)不一樣,需要的朋友可以參考下

1. 什么是策略模式

策略模式就是一種行為可能會(huì)因?yàn)椴煌倪壿嬙斐啥鄠€(gè)算法。比如人吃飯,美國(guó)人吃飯用刀叉,中國(guó)吃飯用筷子。都是吃飯的行為但是使用的工具(算法)不一樣。而策略行為就是把這寫(xiě)工具封裝為對(duì)象,不同的人會(huì)動(dòng)態(tài)的調(diào)用不同的對(duì)象,來(lái)實(shí)現(xiàn)吃飯這一行為。 ?

2. 策略模式組成

環(huán)境類(lèi)(Context):用一個(gè)ConcreteStrategy對(duì)象來(lái)配置。維護(hù)一個(gè)對(duì)Strategy對(duì)象的引用??啥x一個(gè)接口來(lái)讓Strategy訪(fǎng)問(wèn)它的數(shù)據(jù)。

抽象策略類(lèi)(Strategy):定義所有支持的算法的公共接口。 Context使用這個(gè)接口來(lái)調(diào)用某ConcreteStrategy定義的算法。

具體策略類(lèi)(ConcreteStrategy):以Strategy接口實(shí)現(xiàn)某具體算法。

3. 策略模式UML圖

在這里插入圖片描述

4. 示例

就按照上面提到的例子,按照策略模式UML圖按照策略模式實(shí)現(xiàn)人吃飯這件事情。

4.1 創(chuàng)建Strategy抽象策略類(lèi)

public interface Strategy {
    /**
     * 人類(lèi)怎么吃飯的
     */
   public void eat();
}

4.2 創(chuàng)建環(huán)境類(lèi)

public class Context {
    private Strategy strategy;
    public Context(){
    }
    public Context(Strategy strategy){
        this.strategy = strategy;
    }
    public void  setStrategy(Strategy strategy){
        this.strategy = strategy;
    }
    public void eat(){
        strategy.eat();
    }
}

上面環(huán)境類(lèi)我根據(jù)我是實(shí)現(xiàn)了兩種方式傳入策略類(lèi),可以根據(jù)自己不同的需求就行靈活應(yīng)用給

4.3 創(chuàng)建實(shí)現(xiàn)

 
 /**
 * 美國(guó)人 吃飯
 */
@Component
public class StrategyImplOne implements Strategy{
    @Override
    public void eat() {
        System.out.println("美國(guó)人用刀叉吃飯");
    }
}
/**
 * 中國(guó)人 吃飯
 */
@Component
public class StrategyImplTwo implements Strategy{
    @Override
    public void eat() {
        System.out.println("中國(guó)人用筷子吃飯");
    }
}

4.4 測(cè)試

public class MainTest {
    public  static  void test(){
        Context context = new Context();
        context.setStrategy(new StrategyImplOne());
        context.eat();
        context.setStrategy(new StrategyImplTwo());
        context.eat();
    }
    public static void main(String[] args) {
        test();
    }
}

當(dāng)然了這是簡(jiǎn)單的場(chǎng)景,在復(fù)雜的場(chǎng)景中我們不想經(jīng)過(guò)判斷他是美國(guó)人還是中國(guó)人來(lái)創(chuàng)建對(duì)應(yīng)的實(shí)現(xiàn),設(shè)置到環(huán)境類(lèi)中,我們可以給每個(gè)實(shí)現(xiàn)設(shè)置一個(gè)屬性標(biāo)識(shí),來(lái)標(biāo)識(shí)他是中國(guó)人還是美國(guó)人,然后根據(jù)標(biāo)識(shí)通過(guò)反射創(chuàng)建對(duì)應(yīng)的實(shí)現(xiàn)對(duì)象,再設(shè)置到環(huán)境類(lèi)中。下面我們看結(jié)果。 ?

首先我們加入一個(gè)枚舉類(lèi)(enum) 用來(lái)存儲(chǔ)我們實(shí)現(xiàn)的策略類(lèi)

public enum ManType {
    AMERICAN(1,"American",StrategyImplOne.class),
    CHINESE(1,"Chinese",StrategyImplTwo.class)
    ;
    private Integer code;
    private String type;
    private Class classModel;
    // 定義一個(gè)Map 開(kāi)始的時(shí)候就把這信息存儲(chǔ)到這里面
    private static HashMap<String,Class> map = new HashMap<>(16);
    static {
        for ( ManType manType:ManType.values()) {
            map.put(manType.getType(),manType.getClassModel());
        }
    }
    ManType(Integer code, String type, Class classModel) {
        this.code = code;
        this.type = type;
        this.classModel = classModel;
    }
    public Integer getCode() {
        return code;
    }
    public String getType() {
        return type;
    }
    public Class getClassModel() {
        return classModel;
    }
    // 這個(gè)方法根據(jù)type獲取指定的類(lèi) 通過(guò)反射來(lái) 創(chuàng)建對(duì)象
    public static Class getManType(String type){
        return map.get(type);
    }
}

創(chuàng)建好枚舉類(lèi)后,我們的測(cè)試方法就變?yōu)橄旅娴倪@個(gè)樣子。寫(xiě)的有點(diǎn)粗糙,大家見(jiàn)諒。 ?

public class MainTest {
    public   void test(String manType){
        Context context = new Context();
        try {
            Strategy strategy = (Strategy) (ManType.getManType(manType).newInstance());
            context.setStrategy(strategy);
            context.eat();
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }
    }
    public static void main(String[] args) {
        new MainTest().test("American");
    }
}

其實(shí)也可以不用反射,如果項(xiàng)目是使用的是SpringBoot開(kāi)發(fā)的話(huà) 我們可以把實(shí)現(xiàn)策略類(lèi)在項(xiàng)目啟動(dòng)時(shí)就給通過(guò)@Component 給注冊(cè)到Spring容器中,然后通過(guò)ApplicationContext 從容器中獲取指定的對(duì)象。這樣也是可以的。

我就不一一展示了,感興趣的話(huà)可以自己在下面試一下。 ?

優(yōu)點(diǎn)和缺點(diǎn)

優(yōu)點(diǎn):

1、策略模式符合開(kāi)閉原則。

2、避免使用多重條件轉(zhuǎn)移語(yǔ)句,如if…else…語(yǔ)句、switch 語(yǔ)句

3、使用策略模式可以提高算法的保密性和安全性。

缺點(diǎn)

1、客戶(hù)端必須知道所有的策略,并且自行決定使用哪一個(gè)策略類(lèi)。

2、代碼中會(huì)產(chǎn)生非常多策略類(lèi),增加維護(hù)難度。

3、如果把策略類(lèi)初始化時(shí)就放到Spring容器中,當(dāng)策略類(lèi)太多事也是一種性能消耗。

到此這篇關(guān)于Java設(shè)計(jì)模式之策略模式詳解和示例的文章就介紹到這了,更多相關(guān)Java策略模式內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

最新評(píng)論