抽象工厂模式(Abstract Factory Pattern)定义:提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类。抽象工厂模式又称Kit模式,属于对象创建型模式。
抽象工厂用于声明生成抽象产品,在一个抽象工厂中可以定义一组方法,每一个方法对应一个产品等级结构。
具体工厂实现了抽象工厂声明的生成抽象产品的方法,生成一组具体产品,这些产品构成一个产品族,每一个产品都位于某个产品等级结构中。
抽象产品为每种产品声明接口,在抽象产品中定义了产品的抽象业务方法。
具体产品定义具体工厂生产的具体产品对象,实现抽象产品接口中定义的业务方法。
它隔离了具体类的生成,使用客户并不需要知道什么被创建,并且在更换一个具体工厂变得相对容易。它能保证客户端始终只使用同一个产品族中的对象。
增加新的产品等级结构很复杂,需要修改抽象工厂和所有的具体工厂类,对“开闭原则”的支持呈倾斜性.
一个系统不应当依赖于产品类实例如何被创建、组合和表达的细节;
系统中有多个产品族,而每次只使用其中某一产品族;
属于同一产品族的产品将在一起使用;
系统提供一个产品类的库,所有的产品以同样的接口出现,从而使客户端不依赖于具体实现。
某系统为了改进数据库操作的性能,自定义数据库连接对象Connection和语句对象Statement,可针对不同类型的数据库提供不同的连接对象和语句对象,如提供Oracle或SQL Server专用连接类和语句类,而且用户可以通过配置文件等方式根据实际需求动态更换系统数据库。使用抽象工厂模式设计该系统。
给出具体代码并编写 测试客户端类,并可通过XML配置文件更改连接的数据库类型
运行结果如下:
连接到Oracle数据库。
执行Oracle数据库操作语句。
(1)抽象产品类Connection(连接类),其中实现连接到数据库类型的方法where()的声明。
public interface Connection {
public void where();
}
(2)具体产品类MySqlConnection(MySql连接类),是Connection的子类,实现了方法where()
public class MySqlConnection implements Connection {
@Override
public void where() {
System.out.println("连接到MySql...");
}
}
(3)具体产品类OrcalConnection(Orcale连接类),
public class OrcalConnection implements Connection {
@Override
public void where() {
System.out.println("连接到Orcal...");
}
}
(4)抽象产品类Statement(实现类),其中实现执行数据库类型语句的方法execute()的声明。
public interface Statement {
public void execute();
}
(5)具体产品类MySqlStatement(MySql实现类),是Statement的子类,实现了方法execute()
public class MySqlStatement implements Statement {
@Override
public void execute() {
System.out.println("执行MySql数据库操作语句");
}
}
(6)具体产品类OrcalStatement (Orcale实现类),
public class OrcalStatement implements Statement {
@Override
public void execute() {
System.out.println("执行Orcal数据库操作语句");
}
}
(7)抽象工厂类DBUtil(数据库工厂类),其中定义了抽象工厂方法,针对每一个产品族的产品都提供了一个对应的工厂方法。
public interface DBUtil {
public Connection produceConnection();
public Statement produceStatement();
}
(8)具体工厂类MySql,实现了DBUtil中定义的工厂方法,用于创建具体产品对象。
public class MySql implements DBUtil {
@Override
public Connection produceConnection() {
return new MySqlConnection();
}
@Override
public Statement produceStatement() {
return new MySqlStatement();
}
}
(9)具体工厂类Orcal
public class Orcal implements DBUtil {
@Override
public Connection produceConnection() {
return new OrcalConnection();
}
@Override
public Statement produceStatement() {
return new OrcalStatement();
}
}
(1)XMLUtil工具类
public class XMLUtil {
//该方法用于从XML配置文件中提取具体类类名,并返回一个实例对象
public static Object getBean(){
try {
//创建DOM文档对象
DocumentBuilderFactory dFactory =DocumentBuilderFactory.newInstance();
DocumentBuilder builder = dFactory.newDocumentBuilder();
Document doc;
doc =builder.parse(new File("DB.xml"));
//获取包含类名的文本节点
NodeList nl = doc.getElementsByTagName("className");
Node classNode = nl.item(0).getFirstChild();
String cName =classNode.getNodeValue();
//通过类名生成实例对象并将其返回
Class c = Class.forName(cName);
Object obj = c.newInstance();
return obj;
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
}
(2)配置文件DB.xml
<config>
<className>edu.xatu.DB.OrcalclassName>
config>
(3)客户端测试类Client
public class Client {
@Test
public void test1(){
DBUtil data;
Connection connect;
Statement state;
//getBean()的返回类型是Object,此处需要进行强制类型转换
data = (DBUtil) XMLUtil.getBean();
connect = data.produceConnection();
connect.where();
state = data.produceStatement();
state.execute();
}
}