抽象工厂模式

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();
    

    } } ```

  1. 抽象产品角色 ```java /**

    • 抽象产品(Abstract Product)角色 */ public abstract class ProductA {

      public void useProduct(){} }

/**

  • 抽象产品(Abstract Product)角色 */ public abstract class ProductB {

    public void useProduct(){} } ```

  1. 具体产品角色 ```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");
    

    } } ```

  1. 测试抽象工厂 ```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.总结

优缺点

  • 分离接口和实现
  • 使得切换产品簇变得容易
  • 不太容易扩展新的产品
  • 容易造成类层次的复杂

何时选用

  • 如果希望一个系统独立于它的产品创建,组合和表示的时候,换句话说,希望一个系统知识知道产品的接口,而不关心实现的时候
  • 如果一个系统要由多个产品系列中的一个来配置的时候,就是可以动态的切换产品簇的时候
  • 如果要强调一系列相关产品的接口,以便联合使用他们的时候

results matching ""

    No results matching ""