02设计模式之策略模式

策略模式主要针对一些拓展性特别强的方法进行类封装

今天就来学透策略模式

策略模式的定义

该模式定义了一系列算法,并将每个算法封装起来,使它们可以相互替换,且算法的变化不会影响使用算法的客户。策略模式属于对象行为模式,它通过对算法进行封装,把使用算法的责任和算法的实现分割开来,并委派给不同的对象对这些算法进行管理。

策略模式举例了解

策略模式主要分三步(人陪猫玩):

人和猫是对象,玩是方法。方法有很多种,可以定义多个方法,在调用时写上具体的调用方法;但是这样在维护时会修改代码,违反开闭原则。同时,在大量的不同的行为方式也会导致类的类的体积庞大。此时就可以考虑使用策略模式:

第一步:找到要进行封装的方法

定义Person类

package com.wwj.strategymode;

/**
 * 人
 */
public class Person {
    private String name;

    /**
     * 人与猫玩
     */
    public void playWithCat(){
        
    }
    
    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

抽象玩耍行为为策略接口

package com.wwj.strategymode;

/**
 * 人陪猫玩耍策略接口
 */
public interface PlayWithCatStrategy {

    /**
     * 人与猫玩耍
     */
    void play();
}

实现具体的策略

package com.wwj.strategymode;

/**
 * 用逗猫棒陪猫玩耍
 */
public class StickPlayWithCatStrategy implements PlayWithCatStrategy{

    @Override
    public void play() {
        System.out.println("我逗猫棒逗猫玩");
    }
}
package com.wwj.strategymode;

/**
 * 用红外线陪猫玩耍
 */
public class InfraredPlayWithCatStrategy implements PlayWithCatStrategy{

    @Override
    public void play() {
        System.out.println("我红外线逗猫玩");
    }
}

第二步:调用策略接口,准备利用多态,实现不同的具体策略

package com.wwj.strategymode;

/**
 * 人
 */
public class Person {
    private String name;

    /**
     * 人与猫玩
     */
    public void playWithCat(PlayWithCatStrategy playWithCatStrategy){
        playWithCatStrategy.play();
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

第三步:***最后使用策略模式(三种方式)

1.直接在需要调用的地方new 出从刚才创建的策略行为 注意:此时的策略模式使用单例因为策略模式知识针对行为的模式,在这里单例更为合适

package com.wwj.strategymode;

public class main {
    public static void main(String[] args) {
        Person person = new Person();
        person.setName("张三");
        PlayWithCatStrategy playWithCatStrategy;
        String key = "0";
        if ("0".equals(key)){
            playWithCatStrategy = new InfraredPlayWithCatStrategy();
        }else{
            playWithCatStrategy = new StickPlayWithCatStrategy();
        }        
        person.playWithCat(playWithCatStrategy);
    }
}

2.有的时候直接new出行为还需要写很多层if esle,这是我们就可以采用将所有的策略在java的配置类中进行将全部策略初始化,利用map去避免ifelse的判断,这样在使用时只需要修改配置类中的初始化方法和新增策略类就可以进行拓展

package com.wwj.strategymode;

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

/**
 * 策略模式的配置类
 */
public class PlayStrtegyConfig {
    public static final Map<String,Object> map = new HashMap<>();
    static {
        map.put("0",new StickPlayWithCatStrategy());
        map.put("1",new InfraredPlayWithCatStrategy());
    }

    /**
     * 构造方法私有化
     */
    private PlayStrtegyConfig(){}
}
package com.wwj.strategymode;

public class main {
    public static void main(String[] args) {
        Person person = new Person();
        person.setName("张三");
        String key = "1";
        PlayWithCatStrategy playWithCatStrategy = (PlayWithCatStrategy)PlayStrtegyConfig.map.get(key);
        person.playWithCat(playWithCatStrategy);
    }
}

3.对于经常会发生变化的策略 我们还可以将所有策略写在配置类中,这样更加灵活,同样也是需要将每个策略模式携程单例模式。

读取配置文件类

package com.wwj.strategymode;

import com.wwj.tank.ConfigMgr;

import java.io.IOException;
import java.util.Properties;

/**
 * 获取配置文件信息(单例)
 */
public class PlayStrtegyConfigFile {
    private static final PlayStrtegyConfigFile instance = new PlayStrtegyConfigFile();
    private static Properties prop = new Properties();
    static {
        try {
            prop.load(ConfigMgr.class.getClassLoader().getResourceAsStream("config.properties"));
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    private PlayStrtegyConfigFile(){}


    public static PlayStrtegyConfigFile getInstance(){
        return instance;
    }

    public String get(String name){
        if(prop == null) return null;
        return prop.get(name).toString();
    }
}

配置文件

#玩的策略
0=com.wwj.strategymode.InfraredPlayWithCatStrategy
1=com.wwj.strategymode.StickPlayWithCatStrategy

利用Class类加载对象

package com.wwj.strategymode;

import java.lang.reflect.InvocationTargetException;

public class main {
    public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {
        Person person = new Person();
        person.setName("张三");
        String key = "1";
        //获取配置文件的类型
        String name =  PlayStrtegyConfigFile.getInstance().get(key);
        //将类加载到内存中(利用无参构造的方式)
        PlayWithCatStrategy playWithCatStrategy = (PlayWithCatStrategy)Class.forName(name).getDeclaredConstructor().newInstance();
        person.playWithCat(playWithCatStrategy);
    }
}

最后,策略模式基本限于明显需要很强的拓展性的地方,例如像微信的消息处理、设备的读取数据....等这类需要明显在后期开发中进行拓展时,我们选择策略模式是比较好的

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

推荐阅读更多精彩内容

  • 前言 策略模式属于对象的行为模式。其用意是针对一组算法,将每一个算法封装到具有共同接口的独立的类中,从而使得它们可...
    萨达哈鲁酱阅读 240评论 0 1
  • 设计模式之策略模式 1.意图 根据GOF的定义:定义一系列的算法或操作,并把它们一个个封装起来,并且使它们可以互换...
    dandan的微笑阅读 604评论 0 0
  • 在程序设计中,我们也常常遇到类似的情况,要实现某一个功能有多种方案可以选择。比如一个压缩文件的程序,既可以选择zi...
    yufawu阅读 369评论 0 3
  • 一个阳光明媚的上午,靓仔正在开心的划水摸鱼,耳机里传来音乐“不是吧不是吧,难道单压也算压......” 产品经理突...
    靓仔聊编程阅读 310评论 0 3
  • 1. 介绍 策略模式定义了算法家族,分别封装起来,让它们之间可以互相替换,此模式让算法的变化不会影响到客户端。从概...
    天羽天阅读 296评论 0 0