《Head First 設計模式》:抽象工廠模式
阿新 • • 發佈:2020-07-26
正文
一、定義
抽象工廠模式提供一個介面,用於建立相關或依賴物件的家族,而不需要明確指定具體類。
要點:
- 抽象工廠允許客戶使用抽象的介面來建立一組相關的產品,而不需要知道實際產品的具體產品是什麼。這樣一來,客戶就從具體的產品中被解耦。
- 抽象工廠的任務是定義一個負責建立一組產品的介面。這個介面內的每個方法都負責建立一個產品,同時利用實現抽象工廠的子類來提供具體的做法。
- 抽象工廠的方法經常以工廠方法的方式實現。
二、實現步驟
1、建立產品抽象類
(1)產品A抽象類
/** * 產品A抽象類 */ public abstract class ProductA { String name; public String getName() { return name; } }
(2)產品B抽象類
/**
* 產品B抽象類
*/
public abstract class ProductB {
String name;
public String getName() {
return name;
}
}
2、建立具體的產品,並繼承產品抽象類
(1)產品A1
/** * 產品A1 */ public class ConcreteProductA1 extends ProductA { public ConcreteProductA1() { name = "ConcreteProductA1"; } }
(2)產品A2
/**
* 產品A2
*/
public class ConcreteProductA2 extends ProductA {
public ConcreteProductA2() {
name = "ConcreteProductA2";
}
}
(3)產品B1
/** * 產品B1 */ public class ConcreteProductB1 extends ProductB { public ConcreteProductB1() { name = "ConcreteProductB1"; } }
(4)產品B2
/**
* 產品B2
*/
public class ConcreteProductB2 extends ProductB {
public ConcreteProductB2() {
name = "ConcreteProductB2";
}
}
3、建立工廠介面,並定義建立產品的方法
也可以使用工廠抽象類,然後在建立具體工廠時繼承工廠抽象類。
/**
* 抽象工廠介面
*/
public interface AbstractFactory {
/**
* 建立產品A
*/
public ProductA createProductA();
/**
* 建立產品B
*/
public ProductB createProductB();
}
4、建立具體的工廠,並實現工廠介面
(1)工廠1
/**
* 工廠1
*/
public class ConcreteFactory1 implements AbstractFactory {
@Override
public ProductA createProductA() {
return new ConcreteProductA1();
}
@Override
public ProductB createProductB() {
return new ConcreteProductB1();
}
}
(2)工廠2
/**
* 工廠2
*/
public class ConcreteFactory2 implements AbstractFactory {
@Override
public ProductA createProductA() {
return new ConcreteProductA2();
}
@Override
public ProductB createProductB() {
return new ConcreteProductB2();
}
}
5、使用工廠建立產品
public class Test {
public static void main(String[] args) {
// 工廠1
AbstractFactory factory1 = new ConcreteFactory1();
// 工廠2
AbstractFactory factory2 = new ConcreteFactory2();
// 工廠1建立產品
ProductA productA = factory1.createProductA();
System.out.println("工廠1建立產品A:" + productA.getName());
ProductB productB = factory1.createProductB();
System.out.println("工廠1建立產品B:" + productB.getName());
// 工廠2建立產品
productA = factory2.createProductA();
System.out.println("工廠2建立產品A:" + productA.getName());
productB = factory2.createProductB();
System.out.println("工廠2建立產品B:" + productB.getName());
}
}
三、舉個栗子
1、背景
假設你有一個披薩店,並且擁有許多加盟店。為了確保每家加盟店都能使用高質量的原料,你打算建造生產原料的工廠,並將原料運送到各家加盟店。
由於加盟店坐落在不同的區域,每個區域的原料是不一樣的。因此,必須能夠針對不同的區域提供相應的原料。
2、實現
為每個區域建造一個工廠,每個工廠負責建立相應區域的原料。
(1)建立所有原料抽象類
/**
* 麵糰抽象類
*/
public abstract class Dough {
String name;
public String getName() {
return name;
}
}
/**
* 醬料抽象類
*/
public abstract class Sauce {
String name;
public String getName() {
return name;
}
}
/**
* 芝士抽象類
*/
public abstract class Cheese {
String name;
public String getName() {
return name;
}
}
(2)建立不同區域的所有原料
/**
* 薄皮面團
*/
public class ThinCrustDough extends Dough {
public ThinCrustDough() {
name = "Thin Crust Dough";
}
}
/**
* 厚皮面團
*/
public class ThickCrustDough extends Dough {
public ThickCrustDough() {
name = "Thick Crust Dough";
}
}
/**
* 大蒜番茄醬
*/
public class MarinaraSauce extends Sauce {
public MarinaraSauce() {
name = "Marinara Sauce";
}
}
/**
* 番茄醬
*/
public class PlumTomatoSauce extends Sauce {
public PlumTomatoSauce() {
name = "Plum Tomato Sauce";
}
}
/**
* 帕馬森雷加諾乾酪
*/
public class ReggianoCheese extends Cheese{
public ReggianoCheese() {
name = "Reggiano Cheese";
}
}
/**
* 馬蘇裡拉乳酪
*/
public class MozzarellaCheese extends Cheese{
public MozzarellaCheese() {
name = "Mozzarella Cheese";
}
}
(3)建立原料工廠介面
/**
* 披薩原料工廠介面
*/
public interface PizzaIngredientFactory {
/**
* 建立麵糰
*/
public Dough createDough();
/**
* 建立醬料
*/
public Sauce createSauce();
/**
* 建立芝士
*/
public Cheese createCheese();
// 建立其他原料
}
(4)建立不同區域的原料工廠
/**
* 紐約原料工廠
*/
public class NYPizzaIngredientFactory implements PizzaIngredientFactory {
@Override
public Dough createDough() {
return new ThinCrustDough();
}
@Override
public Sauce createSauce() {
return new MarinaraSauce();
}
@Override
public Cheese createCheese() {
return new ReggianoCheese();
}
}
/**
* 芝加哥原料工廠
*/
public class ChicagoPizzaIngredientFactory implements PizzaIngredientFactory {
@Override
public Dough createDough() {
return new ThickCrustDough();
}
@Override
public Sauce createSauce() {
return new PlumTomatoSauce();
}
@Override
public Cheese createCheese() {
return new MozzarellaCheese();
}
}
(5)使用不同區域的原料工廠建立原料
public class Test {
public static void main(String[] args) {
// 紐約原料工廠
PizzaIngredientFactory nyFactory = new NYPizzaIngredientFactory();
// 芝加哥原料工廠
PizzaIngredientFactory chicagoFactory = new ChicagoPizzaIngredientFactory();
// 使用紐約原料工廠建立原料
Dough dough = nyFactory.createDough();
Sauce sauce = nyFactory.createSauce();
Cheese cheese = nyFactory.createCheese();
System.out.println("New York Pizza Ingredient Factory Create:");
System.out.println(" " + dough.getName());
System.out.println(" " + sauce.getName());
System.out.println(" " + cheese.getName() + "\n");
// 使用芝加哥原料工廠建立原料
dough = chicagoFactory.createDough();
sauce = chicagoFactory.createSauce();
cheese = chicagoFactory.createCheese();
System.out.println("Chicago Pizza Ingredient Factory Create:");
System.out.println(" " + dough.getName());
System.out.println(" " + sauce.getName());
System.out.println(" " + cheese.getName());
}
}