设计模式-抽象工厂模式(Abstract Factory)
概述
-
定义 : 抽象工厂提供一个创建一系列相关或相互依赖对象的接口
-
无需指定它们具体的类
-
类型 : 创建型设计模式
适用场景
- 客户端不依赖于产品实例如何被创建, 实现等细节
- 强调一系列相关的产品对象(属于同一产品组)一起使用创建对象需要大量重复的代码
- 提供一个产品类多的库, 所有的产品已同样的接口出现, 从而使客户端端不依赖于具体实现
优点
- 具体产品在应用层代码隔离, 无需关心创建细节
- 将一个系列的产品族统一到一起创建
缺点
- 规定了所有可能被创建的产品集合, 产品族中扩展新的产品困难, 需要修改抽象工厂的接口
- 增加了系统的抽象性和理解难度
产品等级结构与产品族
模式角色
- AbstractFactory : 声明一个创建抽象产品对象的操作接口
- ConcreteFactory : 实现创建具体产品对象的操作
- AbstractProduct : 为一类产品对象声明一个接口
- ConcreteProduct : 定义一个将被相应的具体工厂创建的产品对象; 实现AbstractProduct接口
- Client : 客户端, 仅使用由AbstractFactory 和AbstractProduct 类声明的接口
代码演示
场景 :
以在KFC点餐为场景, 有两种套餐, 套餐A和套餐B, 每一种套餐都包含一种饮料和一种食物,这个场景中角色对应如下 :
- KFC就相当于模式中中的AbstractFactory角色,
- 而套餐A和套餐B就相当于模式中的ConcreteFactory 角色, 是抽象工厂的实现
- 食物和饮料对应的就是模式中的AbstractProduct抽象产品
- 食物和饮料的实现类就对应模式中的ConcreteProduct,
- 假如套餐A包含可乐和汉堡, 套餐B包含薯条和果汁; 那么可乐和汉堡就是一个产品族, 薯条和果汁也是一个产品族, 同样的可乐和果汁是一个产品等级, 薯条和汉堡是一个产品等级
UML类图如下 :
代码如下:
KFC类, 对应AbstractFactory :
/**
* 餐厅工厂接口
* 可以使用接口或者抽象类实现
* @author 七夜雪
* @create 2018-11-22 15:01
*/
public interface KFCFactory {
public Drink getDrink();
public Food getFood();
}
套餐A和套餐B代码, 对应ConcreteFactory :
/**
* 套餐A工厂类-包含可乐和汉堡
*
* @author 七夜雪
* @create 2018-11-22 15:15
*/
public class ProductAFactory implements KFCFactory {
@Override
public Drink getDrink() {
return new Cola();
}
@Override
public Food getFood() {
return new Hamburger();
}
}
/**
* 套餐B工厂类-包含薯条和果汁
*
* @author 七夜雪
* @create 2018-11-22 15:16
*/
public class ProductBFactory implements KFCFactory {
@Override
public Drink getDrink() {
return new Juice();
}
@Override
public Food getFood() {
return new Chip();
}
}
食物和饮料接口对应AbstractProduct :
/**
* 食物接口
* 可以使用接口或者抽象类
* @author 七夜雪
* @create 2018-11-22 15:03
*/
public interface Food {
public void produce();
}
/**
* 饮料接口
* 可以使用接口或者抽象类
* @author 七夜雪
* @create 2018-11-22 15:02
*/
public interface Drink {
public void produce();
}
食物和饮料实现类, 对应ConcreteProduct:
/**
* Food实现类-汉堡
*
* @author 七夜雪
* @create 2018-11-22 15:12
*/
public class Hamburger implements Food {
@Override
public void produce() {
System.out.println("获得汉堡包一个...");
}
}
/**
* Food实现类-薯条
*
* @author 七夜雪
* @create 2018-11-22 15:13
*/
public class Chip implements Food {
@Override
public void produce() {
System.out.println("获得薯条一包...");
}
}
/**
* 饮料实现类-可乐
*
* @author 七夜雪
* @create 2018-11-22 15:10
*/
public class Cola implements Drink {
@Override
public void produce() {
System.out.println("获得可乐一听...");
}
}
/**
* 饮料实现类-果汁
*
* @author 七夜雪
* @create 2018-11-22 15:11
*/
public class Juice implements Drink {
@Override
public void produce() {
System.out.println("获得果汁一杯...");
}
}
测试类, 对应Client:
/**
* 抽象工厂测试类
* @author 七夜雪
* 2018/11/14 10:04
*/
public class Client {
public static void main(String[] args) {
// 获取套餐A
KFCFactory factory1 = new ProductAFactory();
factory1.getFood().produce();
factory1.getDrink().produce();
// 获取套餐B
KFCFactory factory2 = new ProductBFactory();
factory2.getFood().produce();
factory2.getDrink().produce();
}
}
本文参考:
慕课网<java设计模式精讲 Debug 方式+内存分析>课程
四人帮<设计模式>