目录
结构
抽象工厂模式的主要角色如下:
-
抽象工厂(Abstract Factory):提供了创建产品的接口,它包含多个创建产品的方法,可以创建多个不同等级的产品。
-
具体工厂(Concrete Factory):主要是实现抽象工厂中的多个抽象方法,完成具体产品的创建。
-
抽象产品(Product):定义了产品的规范,描述了产品的主要特性和功能,抽象工厂模式有多个抽象产品。
-
具体产品(ConcreteProduct):实现了抽象产品角色所定义的接口,由具体工厂来创建,它 同具体工厂之间是多对一的关系。
坐标轴理解
PS:产品等级对应抽象产品类,产品族对应抽象工厂类。同一个具体工厂可以制造不等等级的产品,同一个产品可由不同的工厂制造。(其中抽象工厂类乐意为接口类)
咖啡厅案例
现咖啡店业务,不仅要生产咖啡还要生产甜点,如提拉米苏、抹茶慕斯等,要是按照工厂方法模式,需要定义提拉米苏类、抹茶慕斯类、提拉米苏工厂、抹茶慕斯工厂、甜点工厂类,很容易发生类爆炸情况。其中拿铁咖啡、美式咖啡是一个产品等级,都是咖啡;提拉米苏、抹茶慕斯也是一个产品等级;拿铁咖啡和提拉米苏是同一产品族(也就是都属于意大利风味),美式咖啡和抹茶慕斯是同一产品族(也就是都属于美式风味)。所以这个案例可以使用抽象工厂模式实现。类图如下:
代码实现
抽象工厂类
package abstract_factory;
/**
* @author: ZQH
* @project: Design Pattern
* @description 抽象点心工厂类
* @date: 2023/7/18 20:07
*/
public interface DessertFactory {
Coffee createCoffee();
Dessert createDessert();
}
具体工厂类
package abstract_factory;
/**
* @author: ZQH
* @project: Design Pattern
* @description 意大利甜味工厂
* @date: 2023/7/18 20:26
*/
public class ItalyDessertFactory implements DessertFactory{
@Override
public Coffee createCoffee() {
return new LatteCoffee();
}
@Override
public Dessert createDessert() {
return new Tiramisu();
}
}
package abstract_factory;
/**
* @author: ZQH
* @project: Design Pattern
* @description 美式工厂
* @date: 2023/7/18 20:20
*/
public class AmericanDessertFactory implements DessertFactory{
@Override
public Coffee createCoffee() {
// 美式工厂创建美式咖啡
return new AmericanCoffee();
}
@Override
public Dessert createDessert() {
// 美式工厂创建抹茶
return new MatchaMousse();
}
}
抽象产品类
抽象咖啡类
package abstract_factory;
/**
* @author: ZQH
* @project: Design Pattern
* @description 咖啡类
* @date: 2023/7/18 14:43
*/
public abstract class Coffee {
public abstract void getName();
}
抽象点心类
package abstract_factory;
/**
* @author: ZQH
* @project: Design Pattern
* @description 抽象甜品类
* @date: 2023/7/18 20:13
*/
public abstract class Dessert {
public abstract void show();
}
具体产品类
咖啡
package abstract_factory;
/**
* @author: ZQH
* @project: Design Pattern
* @description 美式咖啡
* @date: 2023/7/18 14:47
*/
public class AmericanCoffee extends Coffee{
public void getName(){
System.out.println("美式咖啡");
}
}
package abstract_factory;
/**
* @author: ZQH
* @project: Design Pattern
* @description 拿铁咖啡
* @date: 2023/7/18 14:59
*/
public class LatteCoffee extends Coffee {
public void getName(){
System.out.println("拿铁咖啡");
}
}
点心
package abstract_factory;
/**
* @author: ZQH
* @project: Design Pattern
* @description 抹茶类
* @date: 2023/7/18 20:22
*/
public class MatchaMousse extends Dessert {
@Override
public void show() {
System.out.println("抹茶慕斯");
}
}
package abstract_factory;
/**
* @author: ZQH
* @project: Design Pattern
* @description 提拉米苏(具体甜品类)
* @date: 2023/7/18 20:14
*/
public class Tiramisu extends Dessert{
@Override
public void show() {
System.out.println("提拉米苏");
}
}
测试类
package abstract_factory;
/**
* @author: ZQH
* @project: Design Pattern
* @description 测试类
* @date: 2023/7/18 20:05
*/
public class Client {
public static void main(String[] args) {
// 创建意大利工厂对象
ItalyDessertFactory factory1 = new ItalyDessertFactory();
// 工厂制作点心
Coffee coffee1 = factory1.createCoffee();
Dessert dessert1 = factory1.createDessert();
// 展示
coffee1.getName();
dessert1.show();
System.out.println("_______________________");
// 创建美式工厂对象
AmericanDessertFactory factory2 = new AmericanDessertFactory ();
// 工厂制作点心
Coffee coffee2 = factory2.createCoffee();
Dessert dessert2 = factory2.createDessert();
// 展示
coffee2.getName();
dessert2.show();
}
}
优缺点
优点
当一个产品族中的多个对象被设计成一起工作时,它能保证客户端始终只使用同一个产品族中的对象。
缺点
当产品族中需要增加一个新的产品时,所有的工厂类都需要进行修改。