Java[策略模式+工厂+配置]与[多态+反射+配置]总结

Hello,I'm Shendi

这次总结一下学习设计模式与之前一些技巧的类似对比(纯手码,如有不对请指正)

多态+反射+配置文件取代多分支结构

这个很简单,易理解,就是定义一个接口,子类实现接口,重写指定方法来实现相同函数不同处理

客户端通过配置方式获取类名,反射调用. 例子:根据用户输入,实现不同媒体的播放

接口:

interface Media {
    //播放媒体
    public void play();
}

mp4和mov格式媒体

public class Mp4 implements Media {
    public void play() {
        System.out.println("mp4播放了");
    }
}
public class Mov implements Media {
    public void play() {
        System.out.println("mov播放了");
    }
}

配置文件(这里我用Properties)

#这里的mp4为键(用户输入的) Mp4为值(对应的实现类)
mp4=Mp4
mov=Mov

main调用(取代多分支对比)

public class Test {
    //纯手撸 个别错误请指出
    public static void main(String[] args) {
        //我这里直接用一个字符串模拟用户输入的
        String input = "mp4"
        /*传统方式 if...else*/
        //------------------------
        if ("mp4".equals(input)) {
            Media media = new Mp4();
            media.play();
        } else if ("mov".equals(input)) {
            Media media = new Mp4();
            media.play();
        }
        //------------------------
        //上述这种方式,如果再来一个媒体 avi 
        //则需要改此代码 新增一个 else if ("avi".equals(input))
        //这样 一个类的代码会非常多... 后果自己体会
        //下面用多态+反射+配置文件(配置文件就叫media.properties吧)实现
        /*多态 + 反射 + 配置文件取代多分支结构*/
        //------------------------
        //加载配置文件
        Properties properties = new Properties();
        properties.load("media.properties");
        //通过用户输入的来取指定类
        String java = properties.getProperty(input);
        if (java == null) {
            //配置文件没有定义此用户输入的指定类
        }
        //通过反射调用 这里应该有异常...
        Media media = (Media)Class.forName(java).newInstance();
        media.play();
        //------------------------
        //通过此种方式 后续如果新增一个avi格式媒体,
        //则只需要新增一个Avi类实现Media并在配置文件内配置就ok了
        //不需要修改源代码了
    }
}

策略模式+工厂+配置文件取代多分支

上述那种模式采用的是反射方式,所以性能会较慢

策略模式: 与上面那种方式差不多,一个接口定义行为,子类实现行为,不过策略模式有个类专门用于操作的

接口和实现与上方一样

interface Media {
    //播放媒体
    public void play();
}
public class Mp4 implements Media {
    public void play() {
        System.out.println("mp4播放了");
    }
}
public class Mov implements Media {
    public void play() {
        System.out.println("mov播放了");
    }
}

 提供一个专门用于调用的类 调用此类

public class Context {
    //持有媒体的引用
    private Media media;
    //设置媒体
    public void setMedia(Media media) {
        this.media = media;
    }
    //获取媒体
    public Media getMedia() {
        return media;
    }
    //执行媒体 不懂策略模式则先学策略模式
    public void run() {
        media.play();
    }
}

 这样可以实现取代多分支结构,但是扩展起来需要修改调用的类,所以需要工厂模式和配置文件的配合

将Context类改动一下,改成工厂类

public class Context {
    //存有策略类的map
    private HashMap<Strign,Media> map = new HashMap<String,Media>();
    
    public Context() {
        //读取配置文件 在初始化的时候读取配置文件将所有对象反射存入map
        //也可以定义一个类来调用此类put方法专门初始化map
        //遍历配置文件代码自行百度...
    }
    public void put(String key,Media media) {
        map.put(key,media);
    }
    //获取媒体
    public Media get(String key) {
        return map.get(key);
    }
    //执行媒体 不懂策略模式则先学策略模式
    public void run(String key) {
        map.get(key).play();
    }
    //这样 新增一个策略只需要新增一个实现类和在配置文件内添加一条就可以了
    //自己总结的区别
    //相比较多态+反射+配置 这个效率会更高,因为在类初始化的时候将所有对象都定义了
}

大致就是这样...

发布了38 篇原创文章 · 获赞 23 · 访问量 9053

猜你喜欢

转载自blog.csdn.net/qq_41806966/article/details/104693350