设计模式学习笔记(5)抽象工厂

本文实例代码:https://github.com/JamesZBL/java_design_patterns

抽象工厂模式是在工厂方法模式之上的有一次升级,以便能够处理更加复杂的对象创建场景。因此也是所有形态的工厂模式中最为抽象和最具一般性的一种形态。工厂 ( Factory ) 和产品 ( Product ) 是 Abstract Factory 模式的主要参与者。 该模式描述了怎样在不直接实例化类的情况下创建一系列相关的产品对象。 它最适用于产品对象的数目和种类不变, 而具体产品系列之间存在不同的情况。 我们通过实例化一个特定的具体工厂对象来选择产品系列, 并且以后一直使用该工厂生产产品对象。 我们也能够通过用一个不同的具体工厂实例来替换原来的工厂对象以改变整个产品系列。 抽象工厂模式对产品系列的强调使它区别于其他只与一种产品对象有关的创建性模式。

实例

设想这样一种情景,一支远洋的队伍由船、船长以及水手组成,队伍有新人队伍和老兵队伍之分。新人的队伍有新船长、新水手以及崭新的船只;而老兵的队伍有老船长、经验丰富的老水手以及破旧的船只。不同队伍有着不同的特点,队伍中不同的部分之间存在一定的依赖。

首先定义“成员”接口,规定每个成员都可以描述自己的特性:

Member.java

public interface Member {

  String getDescription();
}

三种具体成员的接口,它们都继承了“成员”接口:

Captain.java

public interface Captain extends Member {

}

Sailor.java

public interface Sailor extends Member {

}

Ship.java

public interface Ship extends Member {

}

下面就是一个抽象工厂,它描述了如何“生产”一支队伍:

TeamFactory.java

public interface TeamFactory {

  Ship createShip();

  Captain createCaptain();

  Sailor createSailor();
}

两种不同的队伍工厂分别“生产”不同特性的队伍:

YoungTeamFactory.java

public class YoungTeamFactory implements TeamFactory {

  public Ship createShip() {
    return new NewShip();
  }

  public Captain createCaptain() {
    return new YoungCaptain();
  }

  public Sailor createSailor() {
    return new YoungSailor();
  }
}

PermanentTeamFactory.java

public class PermanentTeamFactory implements TeamFactory {

  public Ship createShip() {
    return new OldShip();
  }

  public Captain createCaptain() {
    return new OldCaptain();
  }

  public Sailor createSailor() {
    return new OldSailor();
  }
}

现在,一支队伍的“生产”就可以由这几步构成:创建具体特性的工厂,由工厂“生产”队伍:

App.java

TeamFactory factory = new YoungTeamFactory();

Ship ship = factory.createShip();
Captain = factory.createCaptain();
Sailor = factory.createSailor();

总结

抽象工厂的“抽象”指的就是:确定一个应用创建的对象的类,只关心生产什么产品而无需关注产品具体由哪些部件组成,更不需要关注产品具体是怎么生产出来的,它对某一类产品的生产过程制定了一个规则,所以抽象工厂并不关心具体组件的实现,而是只专注于接口。

关于抽象工厂模式和“开闭原则”:
如果需要重新组队,构成一支由新人和老人组成的混合队伍,那么只需要增加一种新的实现了 TeamFactory 接口的工厂即可,所以抽象工厂模式实现了“对扩展开放”。
但是,如果队伍中添加了一种新成员,比如“无线电操作员”,那么现有的所有接口都要跟着修改,所以它并没有实现“对修改关闭”。

发表评论

电子邮件地址不会被公开。 必填项已用*标注

This site uses Akismet to reduce spam. Learn how your comment data is processed.