工廠方法模式
針對簡單工廠模式的缺點(diǎn),使用工廠方法模式就可以完美的解決,完全遵循開閉原則
工廠方法模式概念
定義一個用于創(chuàng)建對象的接口,讓子類決定實(shí)例化那個產(chǎn)品類對象,工廠方法使一個產(chǎn)品類的實(shí)例化延遲到其工廠的子類
結(jié)構(gòu)
工廠方法模式的主要角色
- 抽象工廠:提供了創(chuàng)建產(chǎn)品的接口,調(diào)用者通過它訪問具體工廠的工廠方法來創(chuàng)建產(chǎn)品
- 具體工廠:主要是實(shí)現(xiàn)抽象工廠中的抽象方法,完成具體的產(chǎn)品創(chuàng)建
- 抽象產(chǎn)品:定義了產(chǎn)品的規(guī)范,描述了產(chǎn)品的主要特性和功能
- 具體產(chǎn)品:實(shí)現(xiàn)了抽象產(chǎn)品角色所定義的接口,由具體工廠來創(chuàng)建,它同具體工廠之間一一對應(yīng)
實(shí)現(xiàn)

工廠方法模式.png
抽象工廠
/**
* 定義一個Coffeec抽象工廠
*/
public interface CoffeeFactory {
// 創(chuàng)建咖啡對象的抽象方法
Coffee createCoffee();
}
具體工廠-美式咖啡工廠
/**
* 美式咖啡工廠對象,專門用來生產(chǎn)美式咖啡的
* 工廠里依賴具體的咖啡對象
*/
public class AmericanCoffeeFactory implements CoffeeFactory{
@Override
public Coffee createCoffee() {
return new AmericanCoffee();
}
}
具體工廠-拿鐵咖啡工廠
/**
* 拿鐵咖啡工廠
*/
public class LatteCoffeeFactory implements CoffeeFactory{
@Override
public Coffee createCoffee() {
return new LatteCoffee();
}
}
抽象產(chǎn)品
public abstract class Coffee {
public abstract String getName();
//加糖
public void addSugar(){
System.out.println("加糖");
}
// 加奶
public void addMile(){
System.out.println("加奶");
}
}
具體產(chǎn)品-美式咖啡
public class AmericanCoffee extends Coffee {
@Override
public String getName() {
return "美式咖啡";
}
}
具體產(chǎn)品-拿鐵咖啡
public class LatteCoffee extends Coffee {
@Override
public String getName() {
return "拿鐵咖啡";
}
}
咖啡店 - 依賴咖啡工廠支持點(diǎn)咖啡功能
/**
* 咖啡店
*/
public class CoffeeStore {
private CoffeeFactory coffeeFactory;
public void setCoffeeFactory(CoffeeFactory factory){
this.coffeeFactory = factory;
}
// 點(diǎn)咖啡功能
public Coffee orderCoffee(){
Coffee coffee = coffeeFactory.createCoffee();
// 加配料
coffee.addMile();
coffee.addSugar();
return coffee;
}
}
測試類
/**
* 測試類
*/
public class Client {
public static void main(String[] args) {
CoffeeStore coffeeStore = new CoffeeStore();
coffeeStore.setCoffeeFactory(new AmericanCoffeeFactory());
Coffee coffee = coffeeStore.orderCoffee();
System.out.println(coffee.getName());
}
}
優(yōu)點(diǎn)
- 用戶只需要直到具體工廠的名稱就可以得到所需要的產(chǎn)品,無需知道產(chǎn)品的具體創(chuàng)建過程
- 在系統(tǒng)增加新的產(chǎn)品是只需要添加具體產(chǎn)品類和對應(yīng)的具體工廠類,無需對原工廠進(jìn)行任何修改,滿足開閉原則
缺點(diǎn)
- 每增加一個產(chǎn)品就需要增加一個具體產(chǎn)品類和一個對應(yīng)具體的工廠類,這增加了系統(tǒng)的復(fù)雜度
jdk源碼使用

jdk工廠方法模式實(shí)現(xiàn).png
Collection 接口是抽象工廠類,ArrayList是具體工廠類,Iterator接口是抽象產(chǎn)品類,ArrayList類中的Iter內(nèi)部類是具體的商品類,在具體的工廠類中iterator()方法創(chuàng)建具體商品類對象。