抽象工厂模式(Abstract Factory Pattern):提供一个创建一系列相关或相互依赖对象的接口,而无须指定它们具体的类。
抽象工厂模式又称为Kit模式,属于对象创建型模式。
抽象工厂模式和工厂方法模式类似都是由四部分组成:
-
抽象工厂(AbstractFactory)角色:担任这个角色的是抽象工厂模式的核心,是与应用系统的商业逻辑无关的。通常使用Java接口或者抽象Java类实现。所有的具体工厂必须实现这个Java接口或继承这个抽象的Java类。
-
具体工厂(Factory)角色:这个角色直接在客户端的调用下创建产品的实例,这个角色含有选择合适的产品对象的逻辑,而这个逻辑是与应用系统商业逻辑紧密相关的。
-
抽象产品(AbstractProduct)角色:担任这个角色的类是抽象工厂模式所创建的对象的父类,或它们共同拥有的接口。通常使用Java接口或者抽象Java类实现这一角色。
-
具体产品(Product)角色:抽象工厂模式所创建的任何产品对象都是一个具体的产品类的实例。这是客户端最终需要的东西,其内部一定充满了应用系统的商业逻辑。通常使用具体Java类实现这个角色。
与工厂方法模式不同的是,抽象工厂模式中的具体工厂不再是只能创建一种产品,一个具体的工厂可以创建一个产品族的产品。
简单来说就是在工厂方法模式上面更抽象了一层,这个我们举例说明
=========================================================================
还是生产手机的例子,我们需要生产小米,华为,苹果三种手机。这次我们把手机更加的细化:手机由电池,屏幕,还有操作系统构成,我们通过输入手机,在对应的工厂中实现创建手机,并更细化的拿到手机的配置信息。这时候我们需要考虑,不同的电池,屏幕,OS,都是不同的产品族,那么按照之前的工厂模式设计,我每一次来一个新的手机,都要重新去写一个创建手机的具体方法。这工作量很大,那么我们就把创建手机抽象出来,生产零件抽象出来。那么我不论是增加新的零件还是新的手机,都不会对我们的项目结构有过大的影响。
=========================================================================
抽象工厂角色:
抽象工厂为手机生产厂,我们定义为手机由电池,屏幕,还有操作系统构成。我们可以理解为这是一个手机组装的代工厂,这个代工厂不生产零件,他们只会根据手机的具体需求去拿到相应的零件进行组装。
package AbstractFactoryPattern;
import AbstractFactoryPattern.dao.Battery;
import AbstractFactoryPattern.dao.OperationSystem;
import AbstractFactoryPattern.dao.PhoneScreen;
/**
* @author Zeyu Wan
* @version 1.0.0
* @ClassName SmartPhoneFactory.java
* @Description 智能手机的构成方式
* 仅仅定义生产同一族产品不同等级结构的产品接口,具体由子类工厂来实现
* @createTime 2022年02月10日 17:15:00
*/
public abstract class SmartPhoneFactory {
/**
* 手机屏幕
* @return 手机屏幕
*/
public abstract PhoneScreen screen();
/**
*操作系统
* @return 操作系统
*/
public abstract OperationSystem os();
/**
*电池
* @return 电量
*/
public abstract Battery battery();
}
具体工厂角色:
我们通过具体的工厂组装具体的手机,可以简单理解为代工厂中手机具体的流水线:
苹果手机工厂类 :
package AbstractFactoryPattern.factories;
import AbstractFactoryPattern.SmartPhoneFactory;
import AbstractFactoryPattern.dao.Battery;
import AbstractFactoryPattern.dao.OperationSystem;
import AbstractFactoryPattern.dao.PhoneScreen;
import AbstractFactoryPattern.dao.battery.BYD;
import AbstractFactoryPattern.dao.os.IOS;
import AbstractFactoryPattern.dao.screen.BOE;
import AbstractFactoryPattern.dao.screen.Corning;
/**
* @author Zeyu Wan
* @version 1.0.0
* @ClassName AppleFactory.java
* @Description 苹果手机工厂类
* @createTime 2022年02月14日 08:44:00
*/
public class AppleFactory extends SmartPhoneFactory {
@Override
public PhoneScreen screen() {
return new Corning();
}
@Override
public OperationSystem os() {
return new IOS();
}
@Override
public Battery battery() {
return new BYD();
}
}
华为手机工厂类 :
package AbstractFactoryPattern.factories;
import AbstractFactoryPattern.SmartPhoneFactory;
import AbstractFactoryPattern.dao.Battery;
import AbstractFactoryPattern.dao.OperationSystem;
import AbstractFactoryPattern.dao.PhoneScreen;
import AbstractFactoryPattern.dao.battery.BYD;
import AbstractFactoryPattern.dao.os.Android;
import AbstractFactoryPattern.dao.screen.BOE;
/**
* @author Zeyu Wan
* @version 1.0.0
* @ClassName HuaweiFactory.java
* @Description 华为工厂类
* @createTime 2022年02月14日 09:08:00
*/
public class HuaweiFactory extends SmartPhoneFactory {
@Override
public PhoneScreen screen() {
return new BOE();
}
@Override
public OperationSystem os() {
return new Android();
}
@Override
public Battery battery() {
return new BYD();
}
}
小米手机工厂类 :
package AbstractFactoryPattern.factories;
import AbstractFactoryPattern.SmartPhoneFactory;
import AbstractFactoryPattern.dao.Battery;
import AbstractFactoryPattern.dao.OperationSystem;
import AbstractFactoryPattern.dao.PhoneScreen;
import AbstractFactoryPattern.dao.battery.Samsung;
import AbstractFactoryPattern.dao.os.Android;
import AbstractFactoryPattern.dao.screen.Corning;
import SimpleFactoryPattern.factory.SimplePhoneFactory;
/**
* @author Zeyu Wan
* @version 1.0.0
* @ClassName XiaoMiFactory.java
* @Description 小米手机工厂类
* @createTime 2022年02月14日 09:06:00
*/
public class XiaoMiFactory extends SmartPhoneFactory {
@Override
public PhoneScreen screen() {
return new Corning();
}
@Override
public OperationSystem os() {
return new Android();
}
@Override
public Battery battery() {
return new Samsung();
}
}
抽象产品角色:
手机是由电池,屏幕,OS构成,但是我们存在不同的屏幕,不同的电池,和不同的OS。比如苹果使用的是IOS,小米使用的安卓。我们需要组装厂对需要的零件下订单,这就简单理解为下游零件厂的抽象类。
电池抽象类:
package AbstractFactoryPattern.dao;
/**
* @author Zeyu Wan
* @version 1.0.0
* @ClassName Battery.java
* @Description 电池抽象类
* @createTime 2022年02月10日 17:26:00
*/
public abstract class Battery {
/**
*电量
*/
public abstract void quantity();
}
操作系统抽象类 :
package AbstractFactoryPattern.dao;
/**
* @author Zeyu Wan
* @version 1.0.0
* @ClassName OperationSystem.java
* @Description 操作系统抽象类
* @createTime 2022年02月10日 17:22:00
*/
public abstract class OperationSystem {
/**
*操作系统版本
*/
public abstract void version();
}
屏幕抽象类 :
package AbstractFactoryPattern.dao;
/**
* @author Zeyu Wan
* @version 1.0.0
* @ClassName PhoneScreen.java
* @Description 手机屏幕抽象类
* @createTime 2022年02月10日 17:21:00
*/
public abstract class PhoneScreen {
/**
*硬度等级
*/
public abstract void hardLevel();
}
具体产品(Product)角色
具体的产品就是上面的抽象类下的 订单,也就是实际需要生产的具体对象。也就是具体的屏幕,OS等。
屏幕:
京东方屏幕:
package AbstractFactoryPattern.dao.screen;
import AbstractFactoryPattern.dao.PhoneScreen;
/**
* @author admin
* @version 1.0.0
* @ClassName BOE.java
* @Description 京东方屏幕
* @createTime 2022年02月14日 08:49:00
*/
public class BOE extends PhoneScreen {
/**
* @Description 构造函数
*/
public BOE(){
System.out.println("BOE Screen");
}
@Override
public void hardLevel() {
System.out.println("Level 8");
}
}
康宁屏幕 :
package AbstractFactoryPattern.dao.screen;
import AbstractFactoryPattern.dao.PhoneScreen;
/**
* @author admin
* @version 1.0.0
* @ClassName Corning.java
* @Description 康宁屏幕
* @createTime 2022年02月14日 08:47:00
*/
public class Corning extends PhoneScreen {
/**
* @Description 构造函数
*/
public Corning(){
System.out.println("Corning Screen");
}
@Override
public void hardLevel() {
System.out.println("Level 10");
}
}
电池:
比亚迪电池:
package AbstractFactoryPattern.dao.battery;
import AbstractFactoryPattern.dao.Battery;
/**
* @author Zeyu Wan
* @version 1.0.0
* @ClassName BYD.java
* @Description 比亚迪电池
* @createTime 2022年02月14日 08:51:00
*/
public class BYD extends Battery {
/**
* @Description 构造函数
*/
public BYD(){
System.out.println("BYD Battery");
}
@Override
public void quantity() {
System.out.println("3200mAh");
}
}
三星电池 :
package AbstractFactoryPattern.dao.battery;
import AbstractFactoryPattern.dao.Battery;
/**
* @author Zeyu Wan
* @version 1.0.0
* @ClassName Samsung.java
* @Description 三星电池
* @createTime 2022年02月14日 08:54:00
*/
public class Samsung extends Battery {
/**
* @Description 构造函数
*/
public Samsung(){
System.out.println("Samsung Battery");
}
@Override
public void quantity() {
System.out.println("4100mAh");
}
}
系统:
安卓系统:
package AbstractFactoryPattern.dao.os;
import AbstractFactoryPattern.dao.OperationSystem;
/**
* @author Zeyu Wan
* @version 1.0.0
* @ClassName Android.java
* @Description 安卓系统
* @createTime 2022年02月14日 08:56:00
*/
public class Android extends OperationSystem {
/**
* @Description 构造函数
*/
public Android(){
System.out.println("Android System");
}
@Override
public void version() {
System.out.println("Android 12");
}
}
IOS系统:
package AbstractFactoryPattern.dao.os;
import AbstractFactoryPattern.dao.OperationSystem;
/**
* @author Zeyu Wan
* @version 1.0.0
* @ClassName IOS.java
* @Description IOS系统
* @createTime 2022年02月14日 08:57:00
*/
public class IOS extends OperationSystem {
/**
* @Description 构造函数
*/
public IOS(){
System.out.println("IOS System");
}
@Override
public void version() {
System.out.println("IOS 15");
}
}
主函数
主函数下,我们不需要知道手机如何被创建、组合和表达,我们需要做的只是给代工厂下订单,代工厂就可以制造对应的手机了
package AbstractFactoryPattern;
import AbstractFactoryPattern.dao.Battery;
import AbstractFactoryPattern.dao.OperationSystem;
import AbstractFactoryPattern.dao.PhoneScreen;
import AbstractFactoryPattern.factories.AppleFactory;
import AbstractFactoryPattern.factories.HuaweiFactory;
import AbstractFactoryPattern.factories.XiaoMiFactory;
/**
* @author Zeyu Wan
* @version 1.0.0
* @ClassName GetAbsPhone.java
* @Description 主方法
* @createTime 2022年02月14日 09:10:00
*/
public class GetAbsPhone {
public static void main(String[] args) throws Exception {
String type = "IPhone13ProMax";
SmartPhoneFactory phone = getPhone(type);
getInfo(phone);
}
/**
* @Description 创建手机的方法
*/
public static SmartPhoneFactory getPhone(String phone) throws Exception {
if (!phone.isEmpty()){
switch (phone){
case "IPhone13ProMax":
return new AppleFactory();
case "HuaWeiP50":
return new HuaweiFactory();
case "XiaoMi11U":
return new XiaoMiFactory();
default:
System.out.println("Create Error: Error Type");
throw new Exception();
}
}else {
System.out.println("Create Error: No Type Identify");
throw new Exception();
}
}
/**
* @Description 获取对应的手机信息
*/
public static void getInfo(SmartPhoneFactory phone){
System.out.println("屏幕信息:");
PhoneScreen screen = phone.screen();
screen.hardLevel();
System.out.println("系统信息:");
OperationSystem os = phone.os();
os.version();
System.out.println("电池信息:");
Battery battery = phone.battery();
battery.quantity();
}
}
模式优点 :
- 抽象工厂模式隔离了具体类的生成,使得客户并不需要知道什么被创建。由于这种隔离,更换一个具体工厂就变得相对容易。所有的具体工厂都实现了抽象工厂中定义的那些公共接口,因此只需改变具体工厂的实例,就可以在某种程度上改变整个软件系统的行为。另外,应用抽象工厂模式可以实现高内聚低耦合的设计目的,因此抽象工厂模式得到了广泛的应用。
- 当一个产品族中的多个对象被设计成一起工作时,它能够保证客户端始终只使用同一个产品族中的对象。这对一些需要根据当前环境来决定其行为的软件系统来说,是一种非常实用的设计模式。
- 增加新的具体工厂和产品族很方便,无须修改已有系统,符合“开闭原则”。
模式缺点 :
- 在添加新的产品对象时,难以扩展抽象工厂来生产新种类的产品,这是因为在抽象工厂角色中规定了所有可能被创建的产品集合,要支持新种类的产品就意味着要对该接口进行扩展,而这将涉及到对抽象工厂角色及其所有子类的修改,显然会带来较大的不便。
- 开闭原则的倾斜性(增加新的工厂和产品族容易,增加新的产品等级结构麻烦)