设计模式3——抽象工厂模式(abstract-factory)

 

一、抽象工厂模式说明

layouttitlefolderpermalinkcategoriestags

pattern

Abstract Factory

abstract-factory

/patterns/abstract-factory/

Creational

Java

Gang Of Four

Difficulty-Intermediate

 

布局标题文件夹永久链接分类tags

模式

抽象工厂

abstract-factory

/patterns/abstract-factory/

构建类

Java

四人帮

中级难度

这里针对分类加以说明,总体来说设计模式分为三大类:

创建型(构建型)模式,共五种:工厂方法模式、抽象工厂模式、单例模式、建造者模式、原型模式。

结构型模式,共七种:适配器模式、装饰器模式、代理模式、外观模式、桥接模式、组合模式、享元模式。

行为型模式,共十一种:策略模式、模板方法模式、观察者模式、迭代子模式、责任链模式、命令模式、备忘录模式、状态模式、访问者模式、中介者模式、解释器模式。

之前的观察者模式属于行为型模式,而单例模式属于创建型模式。

其实还有两类:并发型模式和线程池模式。用一个图片来整体描述一下:

Also known as

也被称为:

Kit

工具箱 (是不是很神奇的名字,抽象工厂也可以被称为工具箱类)。

Intent

Provide an interface for creating families of related or dependent objects without specifying their concrete classes.

含义

提供一个接口,这个接口能够创建一个家族相关联或者相互依赖的对象,而不用具体说明实体类。

注意这是中级难度的哦,得要好好理解和掌握。

Explanation

Real world example

解释

真实世界的例子

To create a kingdom we need objects with common theme. Elven kingdom needs an Elven king, Elven castle and Elven army whereas Orcish kingdom needs an Orcish king, Orcish castle and Orcish army. There is a dependency between the objects in the kingdom.

 

为了创建一个王国,我们需要一些有共同主题的对象。11个王国需要11个国王,11个城堡和11支军队,然而兽人的王国需要一个兽人的国王,兽人的堡垒和兽人的军队。王国里有一种对象之间的依赖关系。(因此一旦看到要构建类似的对象时,可以考虑工厂模式)

In plain words

通俗地讲

A factory of factories; a factory that groups the individual but related/dependent factories together without specifying their concrete classes.

 

许多个工厂中的一个,这个工厂能够将抽象但是相互关联(依赖)的工厂的相关特征组合起来,但不用制定实体类。

Wikipedia says

维基百科的说明:

The abstract factory pattern provides a way to encapsulate a group of individual factories that have a common theme without specifying their concrete classes

 

抽象工厂模式提供了一种封装的一群个别但却有相同主题的工厂的方式,而这种模式不用指定他们的实体类。

Programmatic Example

编程的案例

Translating the kingdom example above. First of all we have some interfaces and implementation for the objects in the kingdom

将上述的王国的案例进行翻译。首先在王国,我们有一些对象的借口和实现。

public interface Castle {
  String getDescription();
}
public interface King {
  String getDescription();
}
public interface Army {
  String getDescription();
}

// Elf   精灵
// Elven implementations ->
public class ElfCastle implements Castle {
  static final String DESCRIPTION = "This is the Elven castle!";
  @Override
  public String getDescription() {
    return DESCRIPTION;
  }
}
public class ElfKing implements King {
  static final String DESCRIPTION = "This is the Elven king!";
  @Override
  public String getDescription() {
    return DESCRIPTION;
  }
}
public class ElfArmy implements Army {
  static final String DESCRIPTION = "This is the Elven Army!";
  @Override
  public String getDescription() {
    return DESCRIPTION;
  }
}

// Orcish implementations similarly...

Then we have the abstraction and implementations for the kingdom factory

然后我们有了王国工厂的抽象和实现

public interface KingdomFactory {
  Castle createCastle();
  King createKing();
  Army createArmy();
}

public class ElfKingdomFactory implements KingdomFactory {
  public Castle createCastle() {
    return new ElfCastle();
  }
  public King createKing() {
    return new ElfKing();
  }
  public Army createArmy() {
    return new ElfArmy();
  }
}

public class OrcKingdomFactory implements KingdomFactory {
  public Castle createCastle() {
    return new OrcCastle();
  }
  public King createKing() {
    return new OrcKing();
  }
  public Army createArmy() {
    return new OrcArmy();
  }
}

Now we have our abstract factory that lets us make family of related objects i.e. Elven kingdom factory creates Elven castle, king and army etc.

也就是说(i.e.)现在我们有了抽象工厂,它可以让我们创建一个相关联实例家族。11个王国工厂创建了11个城堡、国王和军队等。

KingdomFactory factory = new ElfKingdomFactory();
Castle castle = factory.createCastle();
King king = factory.createKing();
Army army = factory.createArmy();

castle.getDescription();  // Output: This is the Elven castle!
king.getDescription(); // Output: This is the Elven king!
army.getDescription(); // Output: This is the Elven Army!

Now, we can design a factory for our different kingdom factories. In this example, we created FactoryMaker, responsible for returning an instance of either ElfKingdomFactory or OrcKingdomFactory.

现在我们可以设计一个针对不同王国工厂的工厂。在这个案例,我们创建了 FactoryMaker,用来返回ElfKingdomFactory或者OrcKingdomFactory的实例。


The client can use FactoryMaker to create the desired concrete factory which, in turn, will produce different concrete objects (Army, King, Castle).

用户能够用FactoryMaker 来创建想要的实体工厂,这个实体工厂,反过来,能够生产出不同的实体对象(军队,国王和城堡)


In this example, we also used an enum to parameterize which type of kingdom factory the client will ask for.

在这个例子中,我们也用枚举来进行参数化,这种参数化的方式会根据用户需要的王国工厂来判断。

public static class FactoryMaker {

  public enum KingdomType {
    ELF, ORC
  }

  public static KingdomFactory makeFactory(KingdomType type) {
    switch (type) {
      case ELF:
        return new ElfKingdomFactory();
      case ORC:
        return new OrcKingdomFactory();
      default:
        throw new IllegalArgumentException("KingdomType not supported.");
    }
  }
}

public static void main(String[] args) {
  App app = new App();

  LOGGER.info("Elf Kingdom");
  app.createKingdom(FactoryMaker.makeFactory(KingdomType.ELF));
  LOGGER.info(app.getArmy().getDescription());
  LOGGER.info(app.getCastle().getDescription());
  LOGGER.info(app.getKing().getDescription());

  LOGGER.info("Orc Kingdom");
  app.createKingdom(FactoryMaker.makeFactory(KingdomType.ORC));
  -- similar use of the orc factory
}

Applicability

应用性

Use the Abstract Factory pattern when

用抽象工厂模式,当:

  • a system should be independent of how its products are created, composed and represented
  • a system should be configured with one of multiple families of products
  • a family of related product objects is designed to be used together, and you need to enforce this constraint
  • you want to provide a class library of products, and you want to reveal just their interfaces, not their implementations
  • the lifetime of the dependency is conceptually shorter than the lifetime of the consumer.
  • you need a run-time value to construct a particular dependency
  • you want to decide which product to call from a family at runtime.
  • you need to supply one or more parameters only known at run-time before you can resolve a dependency.

 

  • 一个系统应当独立于产品的创建、组成和表现
  • 一个系统需要配置多个产品系列中的一种
  • 一个相关系列的产品对象被设计来一同使用,而你要做的就是强化这种约束
  • 你想要提供一个产品的类库,并且你想暴露出来的是他们的接口,而不是他们的实现
  • 依赖的生命周期从概念上来看,比使用者的生命周期短
  • 你需要一个运行时值来构建一个特定的依赖
  • 你想在运行时决定从哪个系列中调用产品
  • 在你能够解析一个依赖之前,你需要提供一个或多个只能在运行时才能知道的参数

 

其实抽象类的好处我觉得,在于能够将公共成员提取出来,剩下的部分能够在运行时调用确认,增强软件的灵活性,而抽象工厂则是给工厂类提供了这种灵活性。

Use Cases:

用例:

  • Selecting to call the appropriate implementation of FileSystemAcmeService or DatabaseAcmeService or NetworkAcmeService at runtime.
  • Unit test case writing becomes much easier

 

  • 在运行时,选择调用适当的FileSystemAcmeService 或  DatabaseAcmeService  或  NetworkAcmeService实现。
  • 单元测试用例的编写变得更加简单。

 

Consequences:

结论:

  • Dependency injection in java hides the service class dependencies that can lead to runtime errors that would have been caught at compile time.

 

  • java中的依赖注入隐藏了服务类的依赖,这可能会导致运行时的错误,而这个错误可能在编译时就被发现了。

Tutorial

教程

Presentations

展示

Real world examples

真实世界的案例

Credits

书籍

二、抽象工厂模式讲解分析

1,抽象工厂模式解析

/**
 * 
 * The Abstract Factory pattern provides a way to encapsulate a group of individual factories that have a common theme
 * without specifying their concrete classes. In normal usage, the client software creates a concrete implementation of
 * the abstract factory and then uses the generic interface of the factory to create the concrete objects that are part
 * of the theme. The client does not know (or care) which concrete objects it gets from each of these internal
 * factories, since it uses only the generic interfaces of their products. This pattern separates the details of
 * implementation of a set of objects from their general usage and relies on object composition, as object creation is
 * implemented in methods exposed in the factory interface.

抽象工厂模式提供了一种封装一系列具有公共主题的个别工厂的方式,但不用指定他们的实体类。通常使用中,客户软件创建了一个具体的抽象工厂实现然后用工厂通用的接口构建实体对象,这个对象归属于主题的一部分。客户不知道(或者不关心)哪个实体对象是从哪个内部工厂获取的,因为它只能使用他们产品的通用接口。这个模式将一系列对象实现的细节和他们通常用法相分离,并且依赖对象组合,如同对象是通过工厂接口暴露出来的方法构建的。

 


 * <p>
 * The essence of the Abstract Factory pattern is a factory interface ({@link KingdomFactory}) and its implementations (
 * {@link ElfKingdomFactory}, {@link OrcKingdomFactory}). The example uses both concrete implementations to create a
 * king, a castle and an army.
 * 
 */

抽象工厂模式的本质可以在 一个工厂接口KingdomFactory和它的实现ElfKingdomFactory、OrcKingdomFactory看到。这些例子都使用了实体实现来创建一个国王、一个城堡和一支军队。

2,一行一行读代码

首先App 这个类调用createKingdom()来设置king、castle、army三个对象,有趣的是它的创建不是直接创建而是通过KingdomFactory的对象来创建,来看这一段的核心代码:

app.createKingdom(FactoryMaker.makeFactory(KingdomType.ELF));

这里用KingdomType这个类,来判断需要构建的工厂的实例,而makeFactory方法的返回类型是KingdomFactory,这就是抽象工厂。

其实这个设计模式算相对比较好理解的,它的思路加以学习,其实和服务层先用service的接口然后再实现这样会比较好是一样的。为什么?因为你可能想改实现的方式,改变一些特征,这时候是很容易进行替换的而不影响原来写的程序。

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值