抽象工厂模式
定义
提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类。
解决
抽象工厂模式和工厂方法不太一样,它要解决的问题比较复杂,不但工厂是抽象的,产品是抽象的,而且有多个产品需要创建。
抽象工厂模式与工厂方法模式最大的区别在于,工厂方法模式针对的是一个产品等级结构,而抽象工厂模式则需要面对多个产品等级结构,一个工厂等级结构可以负责多个不同产品等级结构中的产品对象的创建。
优点
- 抽象工厂模式隔离了具体类的生成,使得客户并不需要知道什么被创建。由于这种隔离,更换一个具体工厂就变得相对容易。所有的具体工厂都实现了抽象工厂中定义的那些公共接口,因此只需改变具体工厂的实例,就可以在某种程度上改变整个软件系统的行为。另外,应用抽象工厂模式可以实现高内聚低耦合的设计目的,因此抽象工厂模式得到了广泛的应用。
- 当一个产品族中的多个对象被设计成一起工作时,它能够保证客户端始终只使用同一个产品族中的对象。这对一些需要根据当前环境来决定其行为的软件系统来说,是一种非常实用的设计模式。
- 增加新的具体工厂和产品族很方便,无须修改已有系统,符合“开闭原则”。
缺点
- 在添加新的产品对象时,难以扩展抽象工厂来生产新种类的产品,这是因为在抽象工厂角色中规定了所有可能被创建的产品集合,要支持新种类的产品就意味着要对该接口进行扩展,而这将涉及到对抽象工厂角色及其所有子类的修改,显然会带来较大的不便。
- 开闭原则的倾斜性(增加新的工厂和产品族容易,增加新的产品等级结构麻烦)。
结构
抽象工厂模式包含如下角色:
- AbstractFactory:抽象工厂
- ConcreteFactory:具体工厂
- AbstractProduct:抽象产品
- Product:具体产品
实现
AbstractProductA和AbstractProductB是两个抽象产品,之所以为抽象,是因为他们都有可能由两种不同的实现,而ProductA1、ProductA2和ProductB1和ProductB2就是对这两个抽象产品的具体分类的实现。
package abstractfactorypattern;
/**
* 定义工厂方法所创建的对象的接口
*/
public abstract class AbstractProductA {
abstract void fun();
}
/**
* 具体产品,实现AbstractProductA
*/
class ProductA1 extends AbstractProductA
{
@Override
public void fun() {
System.out.println("ConcreteProductA1 fun()");
}
}
class ProductA2 extends AbstractProductA
{
@Override
public void fun() {
System.out.println("ConcreteProductA2 fun()");
}
}
package abstractfactorypattern;
public abstract class AbstractProductB {
abstract void fun();
}
class ProductB1 extends AbstractProductB
{
@Override
public void fun() {
System.out.println("ConcreteProductB1 fun()");
}
}
class ProductB2 extends AbstractProductB
{
@Override
public void fun() {
System.out.println("ConcreteProductB2 fun()");
}
}
package abstractfactorypattern;
/**
* 抽象工厂接口,它里面应该包含所有产品创建的抽象方法
*/
public abstract class AbstractFactory {
abstract AbstractProductA createProductA();
abstract AbstractProductB createProductB();
}
/**
* 具体工厂,创建具有特定实现的产品对象
*/
class ConcreteFactory1 extends AbstractFactory
{
@Override
AbstractProductA createProductA() {
return new ProductA1();
}
@Override
AbstractProductB createProductB() {
return new ProductB1();
}
}
class ConcreteFactory2 extends AbstractFactory
{
@Override
AbstractProductA createProductA() {
return new ProductA2();
}
@Override
AbstractProductB createProductB() {
return new ProductB2();
}
}
package abstractfactorypattern;
public class AbFaClient {
public static void main(String[] args) {
//获取工厂1
AbstractFactory af1=new ConcreteFactory1();
//获取工厂1的A产品
AbstractProductA pa1=af1.createProductA();
//调用该产品的方法
pa1.fun();
//获取工厂1的B产品
AbstractProductB pb1=af1.createProductB();
//调用该产品的方法
pb1.fun();
//获取工厂2
AbstractFactory af2=new ConcreteFactory2();
//获取工厂2的A产品
AbstractProductA pa2=af2.createProductA();
//调用该产品的方法
pa2.fun();
//获取工厂2的B产品
AbstractProductB pb2=af2.createProductB();
//调用该产品的方法
pb2.fun();
}
}
实例
先创两个实体类了 User 和 Department
package abstractfactorypattern.demo.entity;
public class User {
private int id;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
}
package abstractfactorypattern.demo.entity;
public class Department {
private int id;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
}
package abstractfactorypattern.demo;
//Factory接口 ,定义一个创建访问User表对象的抽象的工厂接口
public interface IFactory {
IUser createUser();
IDepartment createDepartment();
}
class SqlServerFactory implements IFactory
{
@Override
public IUser createUser() {
return new SqlserverUser();
}
@Override
public IDepartment createDepartment() {
return new SqlserverDepartment();
}
}
class AccessFactory implements IFactory{
@Override
public IUser createUser() {
return new AccessUser();
}
@Override
public IDepartment createDepartment() {
return new AccessDepartment();
}
}
package abstractfactorypattern.demo;
import abstractfactorypattern.demo.entity.Department;
interface IDepartment {
void insert(Department department);
Department getDepartment(int id);
}
class SqlserverDepartment implements IDepartment
{
@Override
public void insert(Department department) {
System.out.println("在SQLServer中给Department增加了记录");
}
@Override
public Department getDepartment(int id) {
System.out.println("在SQLServer中根据id得到Department的一条数据");
return null;
}
}
class AccessDepartment implements IDepartment
{
@Override
public void insert(Department department) {
System.out.println("在Access中给Department增加了记录");
}
@Override
public Department getDepartment(int id) {
System.out.println("在Access中根据id得到Department的一条数据");
return null;
}
}
package abstractfactorypattern.demo;
import abstractfactorypattern.demo.entity.User;
interface IUser {
void insert(User user);
User getUser(int id);
}
class SqlserverUser implements IUser
{
@Override
public void insert(User user) {
System.out.println("在SQLServer中给User增加了记录");
}
@Override
public User getUser(int id) {
System.out.println("在SQLServer中根据id得到User的一条数据");
return null;
}
}
class AccessUser implements IUser
{
@Override
public void insert(User user) {
System.out.println("在Access中给User增加了记录");
}
@Override
public User getUser(int id) {
System.out.println("在Access中根据id得到User的一条数据");
return null;
}
}
package abstractfactorypattern.demo;
import abstractfactorypattern.demo.entity.Department;
import abstractfactorypattern.demo.entity.User;
public class AbFaClient {
public static void main(String[] args) {
//new一个Department实体
Department department=new Department();
//设置该实体
department.setId(1);
//new一个User实体
User user=new User();
//设置该实体
department.setId(1);
//创建sqlserver工厂
IFactory facsql=new SqlServerFactory();
//得到sqlserver工厂的Department
IDepartment sqldep=facsql.createDepartment();
//在SQLServer中根据id=1 得到Department的一条数据
sqldep.getDepartment(1);
//在SQLServer中给Department增加了记录
sqldep.insert(department);
//得到sqlserver工厂的User
IUser sqluser =facsql.createUser();
//在SQLServer中根据id=1 得到User的一条数据
sqluser.getUser(1);
//在SQLServer中给User增加了记录
sqluser.insert(user);
//同理
IFactory facacc=new AccessFactory();
IDepartment accdep=facacc.createDepartment();
accdep.getDepartment(1);
accdep.insert(department);
IUser accuser =facacc.createUser();
accuser.getUser(1);
accuser.insert(user);
}
}
总结
- 抽象工厂模式提供一个创建一系列相关或相互依赖对象的接口,而无须指定它们具体的类。抽象工厂模式又称为Kit模式,属于对象创建型模式。
- 抽象工厂模式包含四个角色:抽象工厂用于声明生成抽象产品的方法;具体工厂实现了抽象工厂声明的生成抽象产品的方法,生成一组具体产品,这些产品构成了一个产品族,每一个产品都位于某个产品等级结构中;抽象产品为每种产品声明接口,在抽象产品中定义了产品的抽象业务方法;具体产品定义具体工厂生产的具体产品对象,实现抽象产品接口中定义的业务方法。
- 抽象工厂模式是所有形式的工厂模式中最为抽象和最具一般性的一种形态。抽象工厂模式与工厂方法模式最大的区别在于,工厂方法模式针对的是一个产品等级结构,而抽象工厂模式则需要面对多个产品等级结构。
- 抽象工厂模式的主要优点是隔离了具体类的生成,使得客户并不需要知道什么被创建,而且每次可以通过具体工厂类创建一个产品族中的多个对象,增加或者替换产品族比较方便,增加新的具体工厂和产品族很方便;主要缺点在于增加新的产品等级结构很复杂,需要修改抽象工厂和所有的具体工厂类,对“开闭原则”的支持呈现倾斜性。
- 抽象工厂模式适用情况包括:一个系统不应当依赖于产品类实例如何被创建、组合和表达的细节;系统中有多于一个的产品族,而每次只使用其中某一产品族;属于同一个产品族的产品将在一起使用;系统提供一个产品类的库,所有的产品以同样的接口出现,从而使客户端不依赖于具体实现。