定义
为创建一组相关或是相互依赖的对象提供一个接口,而不需要指定它们的具体类。抽象工厂模式是围绕一个超级工厂创建其他工厂。
使用场景
一个对象族有相同的约束时可以使用抽象工厂模式,能解决接口选择的问题(比如Android和IOS是不同系统但有相同的电话、短信等软件;比如Android中的主题修改,多套主题,不同按钮弹窗的样式)。
UML类图
抽象工厂的类比较多,但是一共也是四个角色,即四大模块:
- 一是抽象工厂AbstractFactory,声明了一组用于创建一种产品的方法,每一个方法对应一种产品,如createProductA()对应创建产品A和createProductB()对应创建产品B;
- 二是具体工厂ConcreteFactory,实现了在抽象工厂中定义的创建产品的方法,生成一组具体产品,这些产品构成了一个产品种类,每一个产品都位于某个产品等级结构中,如ConcreteFactoryT1和ConcreteFactoryT2;
- 三是抽象产品AbstractProduct,为每种产品申明接口,如AbstractProductA和AbstractProductB;
- 四是具体产品ConcreteProduct,定义具体工厂生产的具体产品对象,实现抽象产品中申明的业务方法,如ConcreteProductA1、ConcreteProductA2、ConcreteProductB1和ConcreteProductB2。
代码实现
package com.tcl.tvweishi.utils;
/**
* Desc
*
* @author Agg
* @date 2020/09/30
*/
public class Client {
public static void main(String[] args) {
AbstractFactory abstractFactory;
System.out.println("----------------------------");
System.out.println("生产多个小产品组装起来的大产品T1");
abstractFactory = new ConcreteFactoryT1();
abstractFactory.createProductA().functionA();
abstractFactory.createProductB().functionB();
System.out.println("----------------------------");
System.out.println("生产多个小产品组装起来的大产品T2");
abstractFactory = new ConcreteFactoryT2();
abstractFactory.createProductA().functionA();
abstractFactory.createProductB().functionB();
System.out.println("----------------------------");
}
/**
* 抽象产品A
*/
public interface AbstractProductA {
void functionA();
}
/**
* 抽象产品B
*/
public interface AbstractProductB {
void functionB();
}
/**
* 具体产品A1
*/
public static class ConcreteProductA1 implements AbstractProductA {
@Override
public void functionA() {
System.out.println("ConcreteProductA1");
}
}
/**
* 具体产品A2
*/
public static class ConcreteProductA2 implements AbstractProductA {
@Override
public void functionA() {
System.out.println("ConcreteProductA2");
}
}
/**
* 具体产品B1
*/
public static class ConcreteProductB1 implements AbstractProductB {
@Override
public void functionB() {
System.out.println("ConcreteProductB1");
}
}
/**
* 具体产品B2
*/
public static class ConcreteProductB2 implements AbstractProductB {
@Override
public void functionB() {
System.out.println("ConcreteProductB2");
}
}
/**
* 抽象工厂
*/
public interface AbstractFactory {
AbstractProductA createProductA();
AbstractProductB createProductB();
}
/**
* 具体工厂T1
*/
public static class ConcreteFactoryT1 implements AbstractFactory {
@Override
public AbstractProductA createProductA() {
System.out.println("ConcreteFactoryT1: ConcreteProductA1");
return new ConcreteProductA1();
}
@Override
public AbstractProductB createProductB() {
System.out.println("ConcreteFactoryT1: ConcreteProductB1");
return new ConcreteProductB1();
}
}
/**
* 具体工厂T2
*/
public static class ConcreteFactoryT2 implements AbstractFactory {
@Override
public AbstractProductA createProductA() {
System.out.println("ConcreteFactoryT1: ConcreteProductA2");
return new ConcreteProductA2();
}
@Override
public AbstractProductB createProductB() {
System.out.println("ConcreteFactoryT2: ConcreteProductB2");
return new ConcreteProductB2();
}
}
}
日志打印
----------------------------
生产多个小产品组装起来的大产品T1
ConcreteFactoryT1: ConcreteProductA1
ConcreteProductA1
ConcreteFactoryT1: ConcreteProductB1
ConcreteProductB1
----------------------------
生产多个小产品组装起来的大产品T2
ConcreteFactoryT1: ConcreteProductA2
ConcreteProductA2
ConcreteFactoryT2: ConcreteProductB2
ConcreteProductB2
----------------------------
总结
优点: 很好的做到了接口与实现的分离,客户端面向接口接口编程。
缺点:
- 类比较多,每增加一个工厂会对应增加具体的多种产品类;
- 扩展性不好,每当增加一个产品类就需要修改抽象工厂,那么所有的具体工厂也需要修改。
总的来说,抽象工厂在平常用的并不多。