尺有所短,寸有所长;不忘初心,方得始终。
一、抽象工厂模式是什么
抽象工厂模式是围绕一个超级工厂创建其他工厂。该超级工厂又称为其他工厂的工厂。属于创建型模式,它提供了一种创建对象的最佳方式。
在抽象工厂模式中,接口是负责创建一个相关对象的工厂,不需要显式指定它们的类。每个生成的工厂都能按照工厂模式提供对象。

主要作用:提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类。
主要解决:主要解决接口选择的问题。
何时使用:系统的产品有多于一个的产品族,而系统只消费其中某一族的产品。
如何解决:在一个产品族里面,定义多个产品。
关键代码:在一个工厂里聚合多个同类产品。
二、抽象工厂模式的适用场景
-
如果代码需要与多个不同系列的相关产品交互, 但是由于无法提前获取相关信息, 或者出于对未来扩展性的考虑, 你不希望代码基于产品的具体类进行构建, 此时可以使用抽象工厂。
-
在设计良好的程序中, 每个类仅负责一件事。如果一个类与多种类型产品交互, 就可以考虑将工厂方法抽取到独立的工厂类或具备完整功能的抽象工厂类中。
-
当一个对象都有相同的行为方法时,可以使用抽象工厂模式。
这个工厂的几个产品都需要经过某些共同的行为方式产生出相同的结果时,这一组产品可以在一个工厂里面生产,减少很多重复的代码在不同的地方都出现多次。
三、抽象工厂模式结构
-
抽象工厂:接口声明了一组创建各种抽象产品的方法。 -
具体工厂:实现抽象工厂的构建方法。每个具体工厂都对应特定产品对象, 且仅初始化此种产品对象,其构建方法签名必须返回相应的抽象产品。 -
抽象产品:为构成系列产品的一组不同但相关的产品声明接口。 -
具体产品 :是抽象产品的多种不同类型实现,都必须实现相应的抽象产品。 -
客户端:只需通过抽象接口调用工厂和产品对象, 就能与任何具体工厂/产品变体交互,客户端不会与工厂创建的特定产品变体耦合。

四、抽象工厂模式实现方式
-
以不同的产品类型与产品变体为维度抽象产品工厂。
-
为所有产品声明抽象产品接口,然后让所有具体产品类实现这些接口。
-
声明抽象工厂接口, 并且在接口中为所有抽象产品提供一组构建方法。
-
为每种产品变体实现一个具体工厂类。
-
在应用程序中对特定具体工厂类进行初始化, 然后将该工厂对象传递给所有需要创建产品的类。
五、抽象工厂模式的实现
案例:抽象工厂模式实现创建一辆车和一架飞机,
-
抽象产品角色实现
/**
* 抽象产品类代码
*/
public interface ICar {
void GetCar();
}
/**
* 抽象产品 飞机类
*/
public interface IAirplane {
void GetAirplane();
} -
具体产品角色实现 与简单工厂代码一致
/**
* 具体汽车 : 越野车
*/
public class JeepCar implements ICar {
@Override
public void GetCar() {
System.out.println("这是越野车");
}
}
/**
* 具体汽车 : 跑车
*/
public class SportCar implements ICar {
@Override
public void GetCar() {
System.out.println("这是跑车");
}
}
/**
* 具体汽车 : 两箱车
*/
public class HatchbackCar implements ICar {
@Override
public void GetCar() {
System.out.println("这是两箱车");
}
}
/**
* 具体飞机 : 客机
*/
public class Airliner implements IAirplane {
@Override
public void GetAirplane() {
System.out.println("这是客机");
}
}
/**
* 具体飞机 : 客机
*/
public class Airliner implements IAirplane {
@Override
public void GetAirplane() {
System.out.println("这是客机");
}
} -
抽象工厂角色实现
/**
* 交通工具抽象工厂类 创建抽象类来获取具体工厂
*/
public abstract class TransportationAbstractFactory{
/**
* 抽象方法:获取创建一辆车的具体工厂
*/
public abstract ICar CreateCar(String type);
/**
* 抽象方法:获取创建架飞机的具体工厂
* @return
*/
public abstract IAirplane CreateAirplane(String type);
} -
具体工厂代码实现
/**
* 具体工厂:基于给定的信息生成实体类的对象。
* 汽车具体工厂类
*/
public class CarFactory extends TransportationAbstractFactory {
@Override
public ICar CreateCar(String type) {
switch (type){
case "跑车":
return new SportCar();
case "越野车":
return new JeepCar();
case "两箱车":
return new HatchbackCar();
default:
return null;
}
}
@Override
public IAirplane CreateAirplane(String type) {
return null;
}
}
/**
* 具体工厂:基于给定的信息生成实体类的对象。
* 飞机具体工厂类
*/
public class AirplaneFactory extends TransportationAbstractFactory{
@Override
public ICar CreateCar(String type) {
return null;
}
@Override
public IAirplane CreateAirplane(String type) {
switch (type){
case "客机":
return new Airliner();
case "战斗机":
return new Fighter();
default:
return null;
}
}
} -
工厂创造器.
/**
* 创建一个工厂创造器/生成器类,通过传递类型信息来获取工厂。
*/
public class FactoryProducer {
public static TransportationAbstractFactory getFactory(String type){
if(type.equalsIgnoreCase("CAR")){
return new CarFactory();
} else if(type.equalsIgnoreCase("AIRPLANE")){
return new AirplaneFactory();
}
return null;
}
} -
客户端代码实现
public static void main(String[] args) {
TransportationAbstractFactory factory = FactoryProducer.getFactory("CAR");
ICar iCar = factory.CreateCar("跑车");
iCar.GetCar();
TransportationAbstractFactory factory1 = FactoryProducer.getFactory("AIRPLANE");
IAirplane iAirplane = factory1.CreateAirplane("战斗机");
iAirplane.GetAirplane();
}
六、抽象工厂模式的优缺点
-
优点
-
抽象工厂模式隔离了具体类的生产,使得客户并不需要知道什么被创建。 -
单一职责原则。可以将产品生成代码抽取到同一位置, 使得代码易于维护。 -
增加新的具体工厂和产品族很方便,无须修改已有系统,符合“开闭原则”。 -
缺点
抽象方法模式的最大缺点就是产品族本身的扩展非常困难,增加新的产品等级结构很复杂,需要修改抽象工厂和所有的具体工厂类,代码可能会比之前更加复杂。
七、抽象工厂模式和其他模式的区别
-
生成器重点关注如何分步生成复杂对象。抽象工厂专门用于生产一系列相关对象。抽象工厂会马上返回产品, 生成器则允许在获取产品前执行一些额外构造步骤。 -
抽象工厂模式通常基于一组工厂方法, 但也可以使用原型模式来生成这些类的方法。 -
当只需对客户端代码隐藏子系统创建对象的方式时, 可以使用抽象工厂来代替外观模式。 -
抽象工厂,生成器和原型都可以用单例模式来实现。
八、总结
工厂模式与抽象工厂模式都属于创建型模式,在工厂模式中弥补了简单工厂模式的缺陷(不符合开闭原则),而在抽象工厂模式中弥补了工厂模式的不足(一个工厂只能生产一种产品)。
– END –
原文始发于微信公众号(星河之码):设计模式(4):抽象工厂模式
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/27202.html