一般情况下软件应该尽量遵循以下的设计原则:
开闭原则(OCP)
- 对扩展开放,对修改关闭
里氏替换原则(LSP)
- 任何类出现的地方,子类一定可以出现(is-a)
依赖倒转原则(DIP)
- 尽量依赖抽象,不要依赖具体
接口隔离原则
- 接口尽量小,不要提供大的接口,使通信尽可能窄
合成复用原则
- 尽量采用合成和聚合的方式达到利用,而不要使用继承的方式达到利用
迪米特法则
- 一个软件实体尽可能少的与其它实体发生作用
抽象工厂:实现多个产品的创建
优点:对产品的增加支持OCP原则
缺点:对产品系列的增加不支持OCP原则
抽象工厂的示意图如下:
下面是一个抽象工厂生产Manager和DAO的示例:
在classpath下创建一个xml文件bean_config.xml,当我们每建立一个Manager和DAO时就在这里配置类信息
<?xml version="1.0" encoding="UTF-8"?> <bean> <manager-class> <manager id="gd.hz.manager.ItemsManager" class="gd.hz.manager.ItemsManager"></manager> </manager-class> <dao-class> <dao id="gd.hz.dao.ItemsDAO" class="gd.hz.dao.ItemsDAO"></dao> </dao-class> </bean>
创建工厂BeanFactory(接口省略),使用dom4j读取配置文件:
package gd.hz.util;
import java.io.InputStream;
import java.util.HashMap;
import java.util.Map;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
public class BeanFactory {
// 使用单例
private static BeanFactory beanFactory = new BeanFactory();
private final String beanConfigFile = "bean_config.xml";
// 存放Manager实例集合
private Map<String, Object> managerMap = new HashMap<String, Object>();
// 存放DAO实例集合
private Map<String, Object> daoMap = new HashMap<String, Object>();
private Document document = null;
private BeanFactory() {
// 初始化SAXReader
SAXReader reader = new SAXReader();
InputStream in = Thread.currentThread().getContextClassLoader()
.getResourceAsStream(beanConfigFile);
try {
document = reader.read(in);
} catch (DocumentException e) {
e.printStackTrace();
}
}
public static BeanFactory getInstance() {
return beanFactory;
}
// 传入配置文件中id属性的名称,配置class属性,用反射产生对象.
public synchronized Object getManagerObj(String managerName) {
// 若存在实例则反回.
if (managerMap.containsKey(managerName)) {
return managerMap.get(managerName);
}
// 读取配置文件
Element el = (Element) document
.selectSingleNode("/bean/manager-class/manager[@id='"
+ managerName + "']");
String className = el.attributeValue("class");
Object manager = null;
try {
// 反射半生实例
manager = Class.forName(className).newInstance();
} catch (Exception e) {
e.printStackTrace();
throw new RuntimeException("类加载失败!!");
}
// 放入容器中.
managerMap.put(managerName, manager);
return manager;
}
public synchronized Object getDaoObj(String daoName) {
if (daoMap.containsKey(daoName)) {
return daoMap.get(daoName);
}
Element el = (Element) document
.selectSingleNode("/bean/dao-class/dao[@id='" + daoName + "']");
String className = el.attributeValue("class");
Object dao = null;
try {
dao = Class.forName(className).newInstance();
} catch (Exception e) {
e.printStackTrace();
throw new RuntimeException("类加载失败!!");
}
managerMap.put(daoName, dao);
return dao;
}
}
测试:
public static void main(String[] args) {
//从工厂获取Bean
ItemsManager itemsManager = (ItemsManager)BeanFactory.getInstance().getManagerObj(ItemsManager.class.getName());
}