抽象工厂模式
1.定义
抽象工厂模式(英语:Abstract factory pattern)是一种软件开发设计模式.抽象工厂模式提供了一种方式,可以将一组具有同一主题的单独的工厂封装起来.在正常使用中,客户端程序需要创建抽象工厂的具体实现,然后使用抽象工厂作为接口来创建这一主题的具体对象.客户端程序不需要知道(或关心)它从这些内部的工厂方法中获得对象的具体类型,因为客户端程序仅使用这些对象的通用接口.抽象工厂模式将一组对象的实现细节与他们的一般使用分离开来.
2.实现
抽象工厂模式包括四个角色:
- 抽象工厂角色(Abstract Factory)
- 具体工厂类角色(Concrete Factory)
- 抽象产品角色(Abstract Product)
具体产品角色(Concrete Product)
抽象工厂
/** * 抽象工厂(Abstract Factory)角色 */ public interface Company { ProductA buildProductA(); ProductB buildProductB(); }具体工厂类角色 ```java /**
具体工厂类(Concrete Factory)角色 */ public class CompanyA implements Company {
@Override public ProductA buildProductA() { return new ProductA1(); }
@Override public ProductB buildProductB() { return new ProductB1(); } }
/**
具体工厂类(Concrete Factory)角色 */ public class CompanyB implements Company {
@Override public ProductA buildProductA() {
return new ProductA2();}
@Override public ProductB buildProductB() {
return new ProductB2();} } ```
抽象产品角色 ```java /**
抽象产品(Abstract Product)角色 */ public abstract class ProductA {
public void useProduct(){} }
/**
抽象产品(Abstract Product)角色 */ public abstract class ProductB {
public void useProduct(){} } ```
具体产品角色 ```java / 产品A / /**
具体产品(Concrete Product)角色 */ public class ProductA1 extends ProductA {
private static final Logger logger = LoggerFactory.getLogger(ProductA1.class);
@Override public void useProduct() { logger.info("产品A1"); } }
/**
具体产品(Concrete Product)角色 */ public class ProductA2 extends ProductA {
private static final Logger logger = LoggerFactory.getLogger(ProductA2.class);
@Override public void useProduct() {
logger.info("产品A2");} }
/ 产品B / /**
具体产品(Concrete Product)角色 */ public class ProductB1 extends ProductB {
private static final Logger logger = LoggerFactory.getLogger(ProductB1.class);
@Override public void useProduct() {
logger.info("产品B1");} }
/**
具体产品(Concrete Product)角色 */ public class ProductB2 extends ProductB {
private static final Logger logger = LoggerFactory.getLogger(ProductB2.class);
@Override public void useProduct() {
logger.info("产品B2");} } ```
测试抽象工厂 ```java /**
测试使用产品 */ public class Client {
public static void main(String[] args) { Company company = new CompanyA(); ProductA productA = company.buildProductA(); productA.useProduct();
ProductB productB = company.buildProductB(); productB.useProduct();
company = new CompanyB();
productA = company.buildProductA();
productA.useProduct();
productB = company.buildProductB();
productB.useProduct();
// stdout
// [main] INFO ProductA1 - 产品A1
// [main] INFO ProductB1 - 产品B1
// [main] INFO ProductA2 - 产品A2
// [main] INFO ProductB2 - 产品B2
}
} ```
3.区别
- 抽象工厂关键在于产品之间的抽象关系,所以至少要两个产品;工厂方法在于生成产品,不关注产品间的关系,所以可以只生成一个产品.
- 抽象工厂中客户端把产品的抽象关系理清楚,在最终使用的时候,一般使用客户端(和其接口),产品之间的关系是被封装固定的;而工厂方法是在最终使用的时候,使用产品本身(和其接口).
- 抽象工厂的工厂是类;工厂方法的工厂是方法.
抽象工厂模式是工厂方法模式的升级版本,他用来创建一组相关或者相互依赖的对象.他与工厂方法模式的区别就在于,工厂方法模式针对的是一个产品等级结构;而抽象工厂模式则是针对的多个产品等级结构.在编程中,通常一个产品结构,表现为一个接口或者抽象类,也就是说,工厂方法模式提供的所有产品都是衍生自同一个接口或抽象类,而抽象工厂模式所提供的产品则是衍生自不同的接口或抽象类.
4.总结
优缺点
- 分离接口和实现
- 使得切换产品簇变得容易
- 不太容易扩展新的产品
- 容易造成类层次的复杂
何时选用
- 如果希望一个系统独立于它的产品创建,组合和表示的时候,换句话说,希望一个系统知识知道产品的接口,而不关心实现的时候
- 如果一个系统要由多个产品系列中的一个来配置的时候,就是可以动态的切换产品簇的时候
- 如果要强调一系列相关产品的接口,以便联合使用他们的时候