设计模式11:抽象工厂模式
阅读材料:http://baike.xsoftlab.net/view/209.html#3_2
抽象工程模式解决的问题:
当前有一套产品,称为A;另一套产品称为B。客户端代码需要在两套产品中切换。
抽象工厂模式相当于在简单工厂模式之上又抽象了一层,使得客户端代码在两套产品切换中比较方便。
但是抽象工厂模式还是会引发大量的改动。如果要减少改动,可以使用反射+简单工厂解决这个问题。
UML:
User相关代码:
package abstractfactory; public abstract class IUser { public abstract void select(); public abstract void insert(); } package abstractfactory; public class MySQLUser extends IUser { @Override public void select() { System.out.println("MySQL select User"); } @Override public void insert() { System.out.println("MySQL insert User"); } } package abstractfactory; public class OracleUser extends IUser { @Override public void select() { System.out.println("Oracle select User"); } @Override public void insert() { System.out.println("Oracle insert User"); } }
Department相关代码:
package abstractfactory; public abstract class IDepartment { public abstract void select(); public abstract void insert(); } package abstractfactory; public class MySQLDepartment extends IDepartment { @Override public void select() { System.out.println("MySQL select Department"); } @Override public void insert() { System.out.println("MySQL insert Department"); } } package abstractfactory; public class OracleDepartment extends IDepartment { @Override public void select() { System.out.println("Oracle select Department"); } @Override public void insert() { System.out.println("Oracle insert Department"); } }
DataBase类:
使用反射确定要实例化哪个子类,数据库类型存储在xml中。
package abstractfactory; import java.io.IOException; import javax.xml.parsers.*; import org.w3c.dom.*; import org.xml.sax.SAXException; public class DataBase { private static String databaseName = null; static{ DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); DocumentBuilder builder = null; try { builder = factory.newDocumentBuilder(); } catch (ParserConfigurationException e) { e.printStackTrace(); } Document document = null; try { document = builder.parse("src\\abstractfactory\\Settings.xml"); } catch (SAXException | IOException e) { e.printStackTrace(); } Element database = (Element) document.getDocumentElement(); databaseName = database.getAttribute("Name"); } public static IUser getUserHandler() throws InstantiationException, IllegalAccessException, ClassNotFoundException { String classname = "abstractfactory." + databaseName + "User"; return (IUser) Class.forName(classname).newInstance(); } public static IDepartment getDepartmentHandler() throws InstantiationException, IllegalAccessException, ClassNotFoundException { String classname = "abstractfactory." + databaseName + "Department"; return (IDepartment) Class.forName(classname).newInstance(); } }
settings.xml
<?xml version="1.0" encoding="UTF-8"?><DataBase Name="Oracle"/>
Demo:
package abstractfactory; public class AbstractFactoryDemo { public static void main(String[] args) { IUser user; IDepartment department; try { user = DataBase.getUserHandler(); user.select(); user.insert(); department = DataBase.getDepartmentHandler(); department.select(); department.insert(); } catch (InstantiationException | IllegalAccessException | ClassNotFoundException e) { e.printStackTrace(); } } }