StaticFactory
抽象工厂:抽象工厂模式是工厂模式的泛化版,升级版。在工厂模式中一种工具类对应的是一种具体的产品,在产品种类很多的情况下就会显得很复杂,而抽象工厂一个具体工厂可以生产多个具体产品。
抽象工厂包含一下几个部分:
- AbstractFactory:抽象工厂用于声明生成具体的抽象产品方法,在一个抽象工厂中可以定义一组方法,没一个方法对应一个产品等级结构。
- ConcreteFactory:具体工厂,实现抽象工厂中生成抽象产品的方法,生产一组具体的产品,这些产品构成了一个产品族,每一个产品都位于某个产品的等级结构中。
- AbstractProduct:抽象产品为每种产品声明接口,在抽象产品中定义了产品的抽象业务方法。
- ConcreteProduct:具体产品定义具体工厂生产的具体产品对象,实现抽象产品接口中定义的业务方法。
- -
接下来我们来用一个具体的实现代码展示一下呗:
首先是抽象产品类: Connection
public interface Connection {
void startConnection();
}
具体产品类:OracleConnection
public class OracleConnection implements Connection {
@Override
public void startConnection() {
System.out.println("Oracle connection");
}
}
具体产品类:SqlConnection
public class SqlConnection implements Connection {
@Override
public void startConnection() {
System.out.println("SQL connection");
}
}
抽象产品:Statement
public interface Statement {
void runStatement();
}
具体产品类:OracleStatement
public class OracleStatement implements Statement{
@Override
public void runStatement(){
System.out.println("Oracle statement runing");
}
}
具体产品类:SqlStatement
public class SqlStatement implements Statement {
@Override
public void runStatement() {
System.out.println("SQL statement runing");
}
}
接下来是抽象工厂类:DBFactory
public abstract class DBFactory {
public abstract Connection dbConnection();
public abstract Statement dbStatement();
}
然后是具体工厂类:OracleFactory
public class OracleFactory extends DBFactory {
@Override
public Connection dbConnection() {
return new OracleConnection();
}
@Override
public Statement dbStatement() {
return new OracleStatement();
}
}
在来一个具体工厂类:SqlFactory
public class SqlFactory extends DBFactory {
@Override
public Connection dbConnection() {
return new SqlConnection();
}
@Override
public Statement dbStatement() {
return new SqlStatement();
}
}
然后是辅助代码 XMLUtil
作用:从xml文件中的节点里面读取具体产品的名字,利用Java反射机制生成对应的对象,再把对象传回去。
public class XMLUtil {
/**
* 从配置文件中获取具体类名
* @return
*/
public static Object getBean() {
try {
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
Document doc;
doc = builder.parse(new File("staticfactory.xml"));
NodeList nodeList = doc.getElementsByTagName("className");
Node node = nodeList.item(0).getFirstChild();
String cname = node.getNodeValue();
System.out.println(cname);
//这里是反射的用法,需要写全名
Class c = Class.forName(cname);
Object object = c.newInstance();
System.out.println(c.getName());
return object;
//return new SqlFactory();
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
}
哈哈哈最后一个客户端:
public class Client {
public static void main(final String[] a) {
try {
DBFactory factory;
Statement statement;
Connection connection;
// 这里得到对应的产品,再通过对应的产品来调用方法!
factory = (DBFactory) XMLUtil.getBean();
statement = factory.dbStatement();
statement.runStatement();
connection = factory.dbConnection();
connection.startConnection();
} catch (Exception e){
System.out.println(e.getMessage());
}
}
}
结束啦,说一下抽象工厂模式的优缺点吧
优点:
- 和工厂模式一样,抽象工厂隔离了具体类的生成,客户不知道什么被创建。由于这种隔离,更换一个工厂就变得很容易。所有的具体工厂都实现了抽象工厂的接口,所以只要改变具体工厂的实例就可以改变整个软件的行为。另外,抽象工厂模式实现了高内聚低耦合的设计目的。
- 增加新的具体工厂和产品族很方便,不需要修改已有的部分,符合开闭原则。
缺点:
- 在增加新的产品对象时,难易增加新种类的产品,如果要增加新种类产品就意味着要对抽象工厂进行修改,这就会让所有抽象工厂的子类都要做修改。