文档章节

编写工厂类和配置文件

 骚年锦时
发布于 05/23 13:48
字数 1081
阅读 0
收藏 0

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

(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就可以进行实例化了。

© 著作权归作者所有

粉丝 6
博文 28
码字总数 70387
作品 0
长沙
私信 提问
学习Spring(七) -- Spring中的Factory用法

静态工厂 首先,要有一个静态工厂来生成对象,编写一个Car类和一个StaticCarFactory类: package cn.net.bysoft.lesson5; public class Car { public Car() { } public Car(String name) { t...

杰克鹏仔
2016/04/20
63
0
用PHP实现简单的IoC控制反转

我们讨论了关于IoC控制反转的设计原则,现在我们用PHP来实现IoC设计原则,加深对这个概念的理解。 首先编写 Fruit 的 POJO 和 Fruit 接口。继承 Fruit 接口生成两个类 Apple 和 Banana,这两...

雾渺
2012/05/02
0
0
方法工厂模式

在简单工厂模式中我们发现一个问题就是我们的工厂是比较死的,如果我们新增一个产品,就需要改变工厂模式的判断条件 很明显这是不符合我们要求的。 方法工厂模式中我们有四种角色: 抽象产品...

zheng_pat
2015/09/26
93
0
一步步编写简单的PHP的Framework(六)

不好意思,由于最近事情比较多,昨天的确没有时间写,今天刚好还有接近一个小时的时间,所以就继续写一篇。 不知道大家注意到没有,之前我们导入一个配置文件是通过include CONFIGS_PATH . ...

NateHuang
2016/07/28
6
0
day33_Spring学习笔记_01

零、蓦然回首 Struts2:web层,比较简单(难点:ValueStack值栈、拦截器) Hibernate:dao层,知识点杂(学了不用,默认设置够用了) Spring:service层,重要,(讲多少用多少) Spring课程...

黑泽明军
2018/07/22
0
0

没有更多内容

加载失败,请刷新页面

加载更多

Oracle:本地表空间管理,字典表空间管理

本地管理表空间 一、概述 1、理解本地管理表空间的由来 2、理解什么是字典管理表空间及工作原理 3、理解本地管理表空间的优势(为什么要使用本地管理表空间) 4、理解本地管理表空间的内部结...

突突突酱
21分钟前
1
0
深度剖析Spring Boot源码,看完薪资敢要30K!

1 实例化SpringApplication SpringApplication.run(BootifulApplication.class, args); public static ConfigurableApplicationContext run(Class<?> primarySource, String... args) {ret......

Java架构资源分享
24分钟前
4
0
tornadofx控制台输出“三门问题”,蒙特卡洛算法

import tornadofx.*fun main() { val wins = intProperty() val lose = intProperty() val Msg = stringProperty()// 1000万次 val n = 10000000 (1..n......

oschina4cyy
30分钟前
1
0
你可能不知道的MySQL中的定点数类型

定点数类型 正因为用浮点数表示小数可能会有不精确的情况,在一些情况下我们必须保证小数是精确的,所以设计MySQL的大叔们提出一种称之为定点数的数据类型,它也是存储小数的一种方式: 其中...

爱编程的浪子
33分钟前
2
0
第十讲:Python爬取网页图片并保存到本地,包含次层页面

上一讲我们讲到了从昵图网的首页下载图片到本地,但是我们发现首页上面的大部分链接其实都可以进入到二级页面。 在二级页面里面,我们也可以同样进行图片的下载,通过层层循环我们可以把网址...

刘日辉
39分钟前
4
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部