博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
编写工厂类和配置文件
阅读量:6866 次
发布时间:2019-06-26

本文共 3034 字,大约阅读时间需要 10 分钟。

为了满足“开闭原则”,大部分设计模式都引入了抽象层,如工厂方法模式、抽象工厂模式、适配器模式、桥接模式、命令模式、策略模式等等。客户端代码针对抽象层编程,而在程序运行的时候再指定其子类,根据“里氏代换原则”和面向对象的多态性,子类对象在运行时将覆盖父类对象。如果需要对系统进行扩展或修改,只需修改子类类名即可。在具体实现时,通过引入配置文件可以使得用户在不修改任何客户端代码的前提下增加或替换子类,其基本实现过程如下:

(1)客户端针对抽象层编程,客户端代码中不能出现任何具体类类名,即客户端不直接实例化对象;

(2)引入纯文本格式的配置文件,通常是XML文件,将具体类类名存储在配置文件中;
(3)通过DOM(Document Object Model,文档对象模型)、SAX(Simple API for XML)等XML解析技术获取存储在配置文件中的类名;
(4)在客户端代码中通过反射(Reflection)机制根据类名创建对象,用反射所创建的对象替换父类对象的引用,程序运行时,将调用子类方法来实现业务功能;
(5)如果需要扩展功能,只需增加一个新的子类继承抽象父类,再修改配置文件,重新运行程序即可;如果需要替换功能,只需用另一个子类类名替换存储在配置文件中的原有子类类名即可。无论是扩展还是替换都无须修改既有类库和客户端源代码,完全符合开闭原则。

新建一个对象来获取配置属性:

package com.atomview.signalgateway.config;import org.springframework.beans.factory.annotation.Value;import org.springframework.stereotype.Component;/*** Created on 2018/10/9.*/public class StreamServerProperties {@Value("#{propertiesReader['state']}")private String m_ConnectState;@Value("#{propertiesReader['server.ip']}")private String m_StreamserverIp;@Value("#{propertiesReader['server.port']}")private String m_StreamserverPort;public String getConnectState() {return m_ConnectState;}public String getStreamserverIp() {return m_StreamserverIp;}public String getStreamserverPort() {return m_StreamserverPort;}}

这里面定义了5个IImageSelect接口的子类,通过定义好的泛型ImageSelectClientMode来决定实例化哪个子类,现在遇到这么一个问题,如果添加到第6个子类的话,那就必须要更改ImageSelectFactory类以及枚举ImageSelectClientMode,虽不说影响不影响什么开闭设计原则,但是有个情况你可成想到,你这个类要打包发布给别人的话,别人在没有源码的情况下如何扩展呢?这里就需要我们动态的通过配置文件来加载实现类了。

通过读取本地的.properties文件来获取我们需要实例化的类,然后通过反射来生成对象,这样当你把发布出去的时候,使用者只用更改配置文件就可以让工厂去实例化自己后来才写的实现类,我们看看实现方式:

通过读取本地的.properties文件来获取我们需要实例化的类,然后通过反射来生成对象,这样当你把发布出去的时候,使用者只用更改配置文件就可以让工厂去实例化自己后来才写的实现类,我们看看实现方式:

public static class ImageSelectFactory {        public static IImageSelect createIImageSelect(String type) {            IImageSelect mIImageSelect;            //实例化Properties对象,用于读取.properties            Properties properties = new Properties();            InputStream is = null;            try {                is = ImageSelectClient.class.getResourceAsStream("ImageSelectClient.properties");                //装载ImageSelectClient.properties文件                properties.load(is);            } catch (Exception e) {                e.printStackTrace();            } finally {                try {                    is.close();                } catch (IOException e) {                    e.printStackTrace();                }            }            try {                //根据key获取value,value即为将要实例化的类                Class
aClass = Class.forName(properties.getProperty(type)); //使用反射进行实例化 mIImageSelect = (IImageSelect) aClass.newInstance(); } catch (ClassNotFoundException e) { e.printStackTrace(); } catch (InstantiationException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } return mIImageSelect; }

我们就可以随便实现子类,然后在.properties文件中添加对应的包路径,然后通过ImageSelectFactory就可以进行实例化了。

转载于:https://blog.51cto.com/14295469/2397866

你可能感兴趣的文章
python 图
查看>>
Unity应用架构设计(13)——日志组件的实施
查看>>
今天无意中发现的WWW.threadPriority
查看>>
js23---工厂模式1
查看>>
[转] Asp.Net 导出 Excel 数据的9种方案
查看>>
如何在Linux中用命令行工具管理KVM虚拟环境
查看>>
CSS 的优先级机制[总结]
查看>>
保证一个类仅有一个实例:单例模式
查看>>
JVM-ClassLoader装载class的流程
查看>>
redis实现分布式锁——核心 setx+pipe watch监控key变化-事务
查看>>
android 50 进程优先级
查看>>
软件设计之多边形区域内找点
查看>>
Medoo个人修改版
查看>>
Linux 上使用 Gmail SMTP 服务器发送邮件通知
查看>>
Linux下的定时任务Crontab
查看>>
动态规划之矩阵连乘问题
查看>>
电视剧《奋斗》能叫奋斗吗?
查看>>
关于在Windows Mobile下今日插件使用WTL的问题
查看>>
不用第三方之C#实现大容量报表系统
查看>>
[翻译]ADO.NET Entity Framework Beta2(三)/实体框架入门
查看>>