來源:Java聯盟

Java設計模式——工廠三兄弟之抽象工廠模式

抽象工廠模式

抽象工廠模式指當有多個抽象角色時,使用的一種工廠模式。抽象工廠模式可以向客戶端提供一個接口,使客戶端在不必指定產品的具體的情況下,創建多個產品族中的產品對象。

角色

  • Factory(工廠角色):工廠角色即工廠類,它是簡單工廠模式的核心,負責實現創建所有產品實例的內部邏輯;工廠類可以被外界直接調用,創建所需的產品對象;在工廠類中提供了靜態的工廠方法factoryMethod(),它的返回類型爲抽象產品類型Product
  • Product(抽象產品角色):它是工廠類所創建的所有對象的父類,封裝了各種產品對象的公有方法,它的引入將提高系統的靈活性,使得在工廠類中只需定義一個通用的工廠方法,因爲所有創建的具體產品對象都是其子類對象。
  • Factory(工廠角色):工廠角色即工廠類,它是簡單工廠模式的核心,負責實現創建所有產品實例的內部邏輯;工廠類可以被外界直接調用,創建所需的產品對象;在工廠類中提供了靜態的工廠方法factoryMethod(),它的返回類型爲抽象產品類型Product
  • ConcreteProduct(具體產品角色):它是簡單工廠模式的創建目標,所有被創建的對象都充當這個角色的某個具體類的實例。每一個具體產品角色都繼承了抽象產品角色,需要實現在抽象產品中聲明的抽象方法

實例

我們將創建一個Shape和Color接口並實現這些接口的具體類。在下一步中,將創建一個抽象工廠類AbstractFactory。在每個工廠類ShapeFactory和ColorFactory定義都是擴展自AbstractFactory。創建工廠創建者/生成器類 - FactoryProducer。

AbstractFactoryPatternDemo這是一個演示類,使用FactoryProducer來獲取AbstractFactory對象。 它會將信息(CIRCLE / RECTANGLE / SQUARE)傳遞給AbstractFactory以獲取所需的對象類型。 它還將信息(用於Color的 RED / GREEN / BLUE)傳遞給AbstractFactory以獲取所需的對象類型。

  • 創建Shape的接口——Shape.java

public interface Shape {

void draw();

}

  • 創建實現相同接口的具體類——Rectangle.java
public class JavaVideo extends Video {
@Override
public void produce() {
System.out.println("錄製Java課程視頻");
}
}
public class PythonVideo extends Video {
@Override
public void produce() {
System.out.println("錄製Python課程視頻");
}
}
Square.java
public class Square implements Shape {
@Override
public void draw() {
System.out.println("Inside Square::draw() method.");
}
}
Circle.java
public class Circle implements Shape {
@Override
public void draw() {
System.out.println("Inside Circle::draw() method.");
}
}
  • 創建一個Colors接口,如下所示
public interface Color {
void fill();
}
  • 創建實現相同接口的具體類。
public class Red implements Color {
@Override
public void fill() {
System.out.println("Inside Red::fill() method.");
}
}
Green.java
public class Green implements Color {
@Override
public void fill() {
System.out.println("Inside Green::fill() method.");
}
}
Blue.java
public class Blue implements Color {
@Override
public void fill() {
System.out.println("Inside Blue::fill() method.");
}
}
  • 創建實現相同接口的具體類——AbstractFactory.java
public abstract class AbstractFactory {
abstract Color getColor(String color);
abstract Shape getShape(String shape) ;
}
  • 創建實現相同接口的具體類,創建工廠類,根據給定信息擴展AbstractFactory以生成具體類的對象。
ShapeFactory.java
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
Color getColor(String color) {
return null;
}
}
ColorFactory.java
public class ColorFactory extends AbstractFactory {
@Override
public Shape getShape(String shapeType){
return null;
}
@Override
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;
}
}
  • 使用FactoryProducer來獲取AbstractFactory,以便通過傳遞類型等信息來獲取具體類的工廠——AbstractFactoryPatternDemo.java
public abstract class AbstractFactory {
abstract Color getColor(String color);
abstract Shape getShape(String shape) ;
}
  • 驗證輸出,結果如下
Inside Circle::draw() method.
Inside Rectangle::draw() method.
Inside Square::draw() method.
Inside Red::fill() method.
Inside Green::fill() method.
Inside Blue::fill() method.

優點

  • 封裝了產品的創建,使得不需要知道具體是哪種產品,只需要知道是哪個工廠即可。
  • 可以支持不同類型的產品,使得模式靈活性更強。
  • 可以支持不同類型的產品,使得模式靈活性更強。

缺點

  • 結構過於臃腫,如果產品類型較多或產品族較多,會非常難於管理。
  • 每次如果添加一組產品,那麼所有的工廠類都必須添加一個方法,這樣違背了開放-封閉原則。所以一般適用於產品組合產品族變化不大的情況。

適用場景

在不必指定產品的具體的情況下,創建多個產品族中的產品對象。

相關文章