Java特性之设计模式【抽象工厂模式】
一、抽象工厂模式
概述
抽象工厂模式(Abstract Factory Pattern)是围绕一个超级工厂创建其他工厂。该超级工厂又称为其他工厂的工厂。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式
在抽象工厂模式中,接口是负责创建一个相关对象的工厂,不需要显式指定它们的类。每个生成的工厂都能按照工厂模式提供对象
抽象工厂模式提供了一种创建一系列相关或相互依赖对象的接口,而无需指定具体实现类。通过使用抽象工厂模式,可以将客户端与具体产品的创建过程解耦,使得客户端可以通过工厂接口来创建一族产品
主要解决:主要解决接口选择的问题
何时使用:我们明确地计划不同条件下创建不同实例时
优缺点
优点:
当一个产品族中的多个对象被设计成一起工作时,它能保证客户端始终只使用同一个产品族中的对象
缺点:
产品族扩展非常困难,要增加一个系列的某一产品,既要在抽象的 Creator 里加代码,又要在具体的里面加代码
1. 各个角色介绍
1.1 抽象工厂(Abstract Factory)
声明了一组用于创建产品对象的方法,每个方法对应一种产品类型。抽象工厂可以是接口或抽象类
1.2 具体工厂(Concrete Factory)
实现了抽象工厂接口,负责创建具体产品对象的实例
1.3 抽象产品(Abstract Product)
定义了一组产品对象的共同接口或抽象类,描述了产品对象的公共方法
1.4 具体产品(Concrete Product)
实现了抽象产品接口,定义了具体产品的特定行为和属性
2. UML图
将创建 Shape 和 Color 接口和实现这些接口的实体类。下一步是创建抽象工厂类 AbstractFactory。接着定义工厂类 ShapeFactory 和 ColorFactory,这两个工厂类都是扩展了 AbstractFactory。然后创建一个工厂创造器/生成器类 FactoryProducer
AbstractFactoryPatternDemo 类使用 FactoryProducer 来获取 AbstractFactory 对象。它将向 AbstractFactory 传递形状信息 Shape(CIRCLE / RECTANGLE / SQUARE),以便获取它所需对象的类型。同时它还向 AbstractFactory 传递颜色信息 Color(RED / GREEN / BLUE),以便获取它所需对象的类型
3. 具体例子和代码
角色分配
-
Shape:形状接口
- Circle:圆形(实现形状接口)
- Rectangle:三角形(实现形状接口)
- Square:正方形(实现形状接口)
-
Color:形状接口
- Red:圆形(实现形状接口)
- Green:三角形(实现形状接口)
- Blue:正方形(实现形状接口)
-
AbstractFactory:抽象工厂
- ColorFactory:颜色工厂
- ShapeFactory:形状工厂
-
FactoryProducer:工厂生产者
3.1 形状接口以及实现类
- Shape
package com.vinjcent.prototype.abstractFactory;
/**
* @author vinjcent
* @description 形状接口
*/
public interface Shape {
/**
* 绘图
*/
void draw();
}
- Circle
package com.vinjcent.prototype.abstractFactory;
/**
* @author vinjcent
* @description 实现形状接口-圆形
*/
public class Circle implements Shape {
@Override
public void draw() {
System.out.println("Inside Circle::draw() method.");
}
}
- Rectangle
package com.vinjcent.prototype.abstractFactory;
/**
* @author vinjcent
* @description 实现形状接口-长方形
*/
public class Rectangle implements Shape {
@Override
public void draw() {
System.out.println("Inside Rectangle::draw() method.");
}
}
- Square
package com.vinjcent.prototype.abstractFactory;
/**
* @author vinjcent
* @description 实现形状接口-正方形
*/
public class Square implements Shape {
@Override
public void draw() {
System.out.println("Inside Square::draw() method.");
}
}
3.2 颜色接口以及实现类
- Color
package com.vinjcent.prototype.abstractFactory;
/**
* @author vinjcent
* @description 颜色接口
*/
public interface Color {
/**
* 颜色填充
*/
void fill();
}
- Red
package com.vinjcent.prototype.abstractFactory;
/**
* @author vinjcent
* @description 继承颜色接口-红色
*/
public class Red implements Color {
@Override
public void fill() {
System.out.println("Inside Red::fill() method.");
}
}
- Green
package com.vinjcent.prototype.abstractFactory;
/**
* @author vinjcent
* @description 继承颜色接口-绿色
*/
public class Green implements Color {
@Override
public void fill() {
System.out.println("Inside Green::fill() method.");
}
}
- Blue
package com.vinjcent.prototype.abstractFactory;
/**
* @author vinjcent
* @description 继承颜色接口-蓝色
*/
public class Blue implements Color {
@Override
public void fill() {
System.out.println("Inside Blue::fill() method.");
}
}
3.3 抽象工厂类以及实现类
- AbstractFactory
package com.vinjcent.prototype.abstractFactory;
/**
* @author vinjcent
* @description 抽象工厂
*/
public abstract class AbstractFactory {
/**
* 构造颜色实体
*
* @param color 颜色名称
* @return 颜色实体
*/
public abstract Color getColor(String color);
/**
* 构造形状实体
*
* @param shape 形状名称
* @return 形状实体
*/
public abstract Shape getShape(String shape);
}
- ColorFactory
package com.vinjcent.prototype.abstractFactory;
/**
* @author vinjcent
* @description 颜色工厂
*/
public class ColorFactory extends AbstractFactory {
@Override
public Shape getShape(String shapeType) {
return null;
}
@Override
public Color getColor(String color) {
if (color == null) {
return null;
}
if (color.equalsIgnoreCase("RED")) {
return new Red();
} else if (color.equalsIgnoreCase("GREEN")) {
return new Green();
} else if (color.equalsIgnoreCase("BLUE")) {
return new Blue();
}
return null;
}
}
- ShapeFacotry
package com.vinjcent.prototype.abstractFactory;
/**
* @author vinjcent
* @description 形状工厂
*/
public class ShapeFactory extends AbstractFactory {
@Override
public Shape getShape(String shapeType) {
if (shapeType == null) {
return null;
}
// (优化:这里可以通过反射来获取)
if (shapeType.equalsIgnoreCase("CIRCLE")) {
return new Circle();
} else if (shapeType.equalsIgnoreCase("RECTANGLE")) {
return new Rectangle();
} else if (shapeType.equalsIgnoreCase("SQUARE")) {
return new Square();
}
return null;
}
@Override
public Color getColor(String color) {
return null;
}
}
3.4 工厂生产者
- FactoryProducer
package com.vinjcent.prototype.abstractFactory;
/**
* @author vinjcent
* @description 工厂生产者
*/
public class FactoryProducer {
/**
* 根据选择获取对应的生产工厂
*
* @param choice 选择类型
* @return 具体的工厂
*/
public static AbstractFactory getFactory(String choice) {
if (choice.equalsIgnoreCase("SHAPE")) {
return new ShapeFactory();
} else if (choice.equalsIgnoreCase("COLOR")) {
return new ColorFactory();
}
return null;
}
}
3.5 测试主函数
package com.vinjcent.prototype.abstractFactory;
/**
* @author vinjcent
*/
public class Main {
public static void main(String[] args) {
// 1.获取形状工厂
AbstractFactory shapeFactory = FactoryProducer.getFactory("SHAPE");
// 2.获取形状为 Circle 的对象
Shape circle = shapeFactory.getShape("CIRCLE");
// 2.1 调用 Circle 的 draw 方法
circle.draw();
// 3.获取形状为 Rectangle 的对象
Shape rectangle = shapeFactory.getShape("RECTANGLE");
// 3.1 调用 Rectangle 的 draw 方法
rectangle.draw();
// 4.获取形状为 Square 的对象
Shape square = shapeFactory.getShape("SQUARE");
// 4.1 调用 Square 的 draw 方法
square.draw();
// 5.获取颜色工厂
AbstractFactory colorFactory = FactoryProducer.getFactory("COLOR");
// 6.获取颜色为 Red 的对象
Color red = colorFactory.getColor("RED");
// 6.1 调用 Red 的 fill 方法
red.fill();
// 7.获取颜色为 Green 的对象
Color green = colorFactory.getColor("GREEN");
// 7.1调用 Green 的 fill 方法
green.fill();
// 8.获取颜色为 Blue 的对象
Color blue = colorFactory.getColor("BLUE");
// 8.1调用 Blue 的 fill 方法
blue.fill();
}
}
- 测试结果
4. 使用场景
- QQ 换皮肤,一整套一起换
- 生成不同操作系统的程序
注意事项:
产品族难扩展,产品等级易扩展