抽象工厂模式的主要角色。
- 抽象工厂(Abstract Factory):提供了创建产品的接口,它包含多个创建产品的方法 newProduct(),可以创建多个不同等级的产品。
- 具体工厂(Concrete Factory):主要是实现抽象工厂中的多个抽象方法,完成具体产品的创建。
- 抽象产品(Product):定义了产品的规范,描述了产品的主要特性和功能,抽象工厂模式有多个抽象产品。
- 具体产品(ConcreteProduct):实现了抽象产品角色所定义的接口,由具体工厂来创建,它同具体工厂之间是多对一的关系。
工厂设计模式的优点
- 面向接口编程,体现了面向对象的思想;
- 将创建对象的工作转移到了工厂类;
代码举例
package com.qianfeng.Test03;
public class Test02 {
public static void main(String[] args) {
AFactory factory = AFactory.choosFactory("mysql");
factory.createAddform().addform();
factory.createmess().outmesave();
}
}
//具体产品
class Mysqlmesave implements Mesave{
public void outmesave() {
System.out.println("正在往mysql数据库中保存数据");
}
}
//具体产品
class Oraclemesave implements Mesave{
public void outmesave() {
System.out.println("正在往oracle数据库中保存数据");
}
}
//具体产品
class Mysqladdform implements Addform{
public void addform() {
System.out.println("正在往mysql数据库总添加订单");
}
}
//具体产品
class Oracleaddform implements Addform{
public void addform() {
System.out.println("正在往Oracle数据库总添加订单");
}
}
//抽象产品
interface Mesave{
void outmesave();
}
//抽象产品
interface Addform{
void addform();
}
//具体工厂
class Mysqlfactory extends AFactory{
public Mysqlmesave createmess() {
return new Mysqlmesave();
}
public Mysqladdform createAddform() {
return new Mysqladdform();
}
}
//具体工厂
class Oraclefactory extends AFactory{
public Oraclemesave createmess() {
return new Oraclemesave();
}
public Oracleaddform createAddform() {
return new Oracleaddform();
}
}
//抽象工厂
abstract class AFactory{
public abstract Mesave createmess();
public abstract Addform createAddform();
public static AFactory choosFactory(String sql) {
if(sql.equals("mysql")) {
return new Mysqlfactory();
} else if(sql.equals("oracle")) {
return new Oraclefactory();
} else {
return null;
}
}
}
上面这种方式还是存在在一些缺陷
比如如果不止上面的两种数据库,一旦添加一个新的数据库,不止具体产品和具体工厂要添加(这种添加无所谓,不会对之前的代码产生影响),而且抽象工厂中的原码就需要改变(这种修改就不符合高内聚低耦合的思想)
解决办法:
通过配置文件(.properties)与反射实现完整的工程设计模式
代码举例
//为客户提供一个工厂的选择方法
public static AFactory choosFactory() {
AbstractFactory factory=null;
try {
Properties prop=new Properties();
InputStream in = AbstractFactory.class.getClassLoader().getResourceAsStream("settings.properties");
prop.load(in);
String factoryName=prop.getProperty("factoryName");
Class clazz = Class.forName("com.qf.day23.abstractfactory." + factoryName);
factory=(AbstractFactory)clazz.newInstance();
// if(sql.equals("mysql")) {
// return new Mysqlfactory();
// } else if(sql.equals("oracle")) {
// return new Oraclefactory();
// } else {
// return null;
// }
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return factory;
}