在很多项目中其实并不需要Spring这样强大的框架,更不需要EJB这样的超级框架.
那么我们怎么实现类和类之间的低耦合那?
从为数不多的项目经验中,以及借鉴各方面的资料,我实现了一个以.properties文件描述类关系的工厂.
PS:本工厂在本人一次集体毕业项目中成功使用.
先介绍下本迷你工厂使用了log4j日志记录器,必须下载Apache公司log4j包.
首先,介绍的是Config类,该类用于对指定资源文件的读取操作.因为采用单例模式,因此只在应用程序启动时读取得资源文件,如需要修改资源文件,必须修改后重新启动应用程序.
package
org.bbs.common;
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
import
java.io.InputStream;
import
java.util.Properties;
import
org.bbs.common.exception.ConfigException;
![](https://i-blog.csdnimg.cn/blog_migrate/a41954a27d6ad96fa2c2cf816e677448.gif)
/** */
/**
* <p>Title: </p>
*
* <p>Description: </p>
*
* <p>Copyright: Copyright (c) 2007</p>
*
* <p>Company: </p>
*
* @author not attributable
* @version 1.0
*
* 该类用于读取.properties文件中,指定字段对应字符串。
*/
![](https://i-blog.csdnimg.cn/blog_migrate/a41954a27d6ad96fa2c2cf816e677448.gif)
public
class
Config
...
{
//资源文件名.
private String configName = null;
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
private Config(String configName) ...{
this.configName = "/"+configName+".properties";
}
//获得Config对象,这里采用的是单例模式.
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
public static synchronized Config getConfig(String configName) ...{
Config con = new Config(configName);
return con;
}
//指定资源文件中,通过key获得value值.
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
public String getConfigValue(String key) throws ConfigException ...{
Properties prop = new Properties();
InputStream is = Config.class.getResourceAsStream(this.configName);
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
try ...{
prop.load(is);
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
} catch (Exception ex) ...{
throw new ConfigException(ex.getMessage());
}
return prop.getProperty(key);
}
}
第二,介绍下ConfigException类,该类是Config的异常类.
package
org.bbs.common.exception;
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/a41954a27d6ad96fa2c2cf816e677448.gif)
public
class
ConfigException
extends
Exception
...
{
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
/** *//**
* CustConfig类的自定义异常类。
*/
private static final long serialVersionUID = 1483970043804403081L;
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
public ConfigException(String massage) ...{
super(org.bbs.common.Config.class+" found error::"+massage);
}
}
第三,介绍下Reflect类,该类的作用用于反射指定调用的类.
package
org.bbs.common;
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
import
org.bbs.common.exception.ReflectException;
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/a41954a27d6ad96fa2c2cf816e677448.gif)
/**/
/*
* 反射实现类.
*/
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/a41954a27d6ad96fa2c2cf816e677448.gif)
public
class
Reflect
...
{
//反射无参数构造对象.
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
public static synchronized Object getObject(String clsName) throws ReflectException ...{
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
try ...{
Class cls = Class.forName(clsName);
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
try ...{
return cls.newInstance();
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
} catch (InstantiationException e) ...{
throw new ReflectException(e.getMessage());
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
} catch (IllegalAccessException e) ...{
throw new ReflectException(e.getMessage());
}
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
} catch (ClassNotFoundException e) ...{
throw new ReflectException(e.getMessage());
}
}
}
第四: 介绍下ReflectException类,该类是Reflect 的异常类.
package
org.bbs.common.exception;
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/a41954a27d6ad96fa2c2cf816e677448.gif)
public
class
ReflectException
extends
Exception
...
{
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
/** *//**
* 反射类的自定义异常.
*/
private static final long serialVersionUID = 6286815905485173564L;
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
public ReflectException(String massage) ...{
// TODO 自动生成构造函数存根
super(org.bbs.common.Reflect.class+" found error:"+massage);
}
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
}
以上四个类组成了本迷你工厂所需要一些工具类.
接下去就是核心--------工厂
package
org.bbs.dao.factory;
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
import
java.io.IOException;
import
java.util.Properties;
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
import
org.apache.log4j.Logger;
import
org.apache.log4j.PropertyConfigurator;
import
org.bbs.common.Config;
import
org.bbs.common.Reflect;
import
org.bbs.common.exception.ConfigException;
import
org.bbs.common.exception.ReflectException;
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/a41954a27d6ad96fa2c2cf816e677448.gif)
/** */
/**
* Dao工厂,使用单例模式,只要通过getObject(String keys)方法,就能获得对应对象.keys是指定资源文件中的key值.
*/
![](https://i-blog.csdnimg.cn/blog_migrate/a41954a27d6ad96fa2c2cf816e677448.gif)
public
class
DaoFactory
...
{
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
private DaoFactory()...{
}
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
public static synchronized Object getObject(String keys)...{
DaoFactory dao = new DaoFactory();
return dao.getDaoObject(keys);
}
//该方法主要调用Reflect类实现对指定类的实例化.
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
private Object getDaoObject(String keys)...{
Object obj = null;
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
try ...{
obj = Reflect.getObject(this.getDaoClsName(keys));
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
} catch (ReflectException e) ...{
// TODO 自动生成 catch 块
e.printStackTrace();
}
return obj;
}
//该方法主要实现调用上述的Config类,寻找指定对象的类.
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
private String getDaoClsName(String keys)...{
String value = null;
Logger logger = Logger.getLogger(DaoFactory.class);
Properties prop = new Properties();
PropertyConfigurator.configure(prop);
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
try ...{
prop.load(this.getClass().getResourceAsStream("/log4j.properties"));
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
} catch (IOException e) ...{
logger.info(e.getMessage());
}
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
try ...{
Config config = Config.getConfig("dao");
value = config.getConfigValue(keys);
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
} catch (ConfigException e) ...{
logger.info(e.getMessage());
}
return value;
}
}
这样一个简单的迷你小工厂就建成了,我们只需要使用DaoFactory.getObject("指定资源文件中的Key值,该值会对应一个Value值,而这个Value值会是一个类");
这样就轻松实现松耦合了,呵呵.当然我们可以根据自己的情况对DaoFactory进行修改.该工场实例主要是为了实现,Dao层和Bo层的送耦合.这样就可以在不断增加的业务需求下,后期移值Spring或者EJB.