工廠模式

  • macOS High Sierra
  • jdk 11.0.4

簡單工廠模式

  • 客戶端(驅動類,或者業務邏輯)與產品類的構造分離
  • 工廠類的switch實現中,新增對象需要修改工廠類代碼,耦合度較高;反射實現中,對於對象的構造依賴Java的反射機制,不夠靈活

代碼(反射版本)

驅動類:Main.java

public class Main {
    public static void main(String[] args) {
        FruitFactory ff = new FruitFactory();
        Fruit apple = ff.getFruit("Apple"), banana = ff.getFruit("Banana");
        apple.pick();
        banana.pick();
    }
}

抽象產品類:Fruit.java

public interface Fruit {
    public void pick();
}

產品類:Apple.java

public class Apple implements Fruit {
    @Override
    public void pick() {
        System.out.println("pick apple");
    }
}

產品類:Banana.java

public class Banana implements Fruit {
    @Override
    public void pick() {
        System.out.println("pick banana");
    }
}

工廠類(反射):FruitFactory.java

import java.lang.reflect.InvocationTargetException;

public class FruitFactory {
    public Fruit getFruit(String fruitType) {
        try {
            return (Fruit) Class.forName(fruitType).getDeclaredConstructor().newInstance();
        } catch (ClassNotFoundException | NoSuchMethodException | InstantiationException | IllegalAccessException | InvocationTargetException e) {
            e.printStackTrace();
            System.out.println("Fruit name error!");
            return null;
        }
    }
}

工廠方法模式

  • 新增產品則新增工廠,無需修改抽象工廠類;客戶端需要知道工廠類名

代碼

驅動類:Main.java

public class Main {
    public static void main(String[] args) {
        FruitFactory af = new AppleFactory(), bf = new BananaFactory();
        Fruit apple = af.getFruit(), banana = bf.getFruit();
        apple.pick();
        banana.pick();
    }
}

產品類和抽象產品類同『簡單工廠模式』,此處略。
抽象工廠類:FruitFactory.java

public interface FruitFactory {
    public Fruit getFruit();
}

工廠類:AppleFactory.java

public class AppleFactory implements FruitFactory {
    @Override
    public Fruit getFruit() {
        return new Apple();
    }
}

工廠類:BananaFactory.java

public class BananaFactory implements FruitFactory {
    @Override
    public Fruit getFruit() {
        return new Banana();
    }
}

抽象工廠模式

簡單工廠模式和工廠方法模式解決的是客戶端使用各種種類的商品的問題,其中商品種類可擴展;而抽象工廠模式解決的是客戶端使用各種商品等級(以下代碼中的Apple, Banana類表示兩種不同的商品等級)、各種商品族(以下代碼中的North, South代表商品族),其中商品等級不易擴展,商品族易擴展。在抽象工廠模式中,擴展商品族只需要增刪該商品族對應的工廠類,而擴展商品等級在增刪商品等級類和商品類的同時,需要增刪抽象工廠類和各工廠類的生產方法。

代碼

驅動類:Main.java

public class Main {
    public static void main(String[] args) {
        FruitFactory nf = new NorthFactory(), sf = new SouthFactory();
        Apple na = nf.getApple(), sa = sf.getApple();
        Banana nb = nf.getBanana(), sb = sf.getBanana();
        na.pick();
        sa.pick();
        nb.pick();
        sb.pick();
    }
}

商品等級類:Apple.java

public interface Apple {
    public void pick();
}

商品等級類:Banana.java

public interface Banana {
    public void pick();
}

注意,這裏的商品等級AppleBanana不需要像簡單工廠模式和工廠方法模式中那樣基於同一個基類Fruit實現,事實上,不同的商品等級類之間沒有關係。
商品類:NorthApple.java

public class NorthApple implements Apple {
    @Override
    public void pick() {
        System.out.println("pick north apple");
    }
}

商品類:SouthApple.java

public class SouthApple implements Apple {
    @Override
    public void pick() {
        System.out.println("pick south apple");
    }
}

商品類:NorthBanana.java

public class NorthBanana implements Banana {
    @Override
    public void pick() {
        System.out.println("pick north banana");
    }
}

商品類:SouthBanana.java

public class SouthBanana implements Banana {
    @Override
    public void pick() {
        System.out.println("pick south banana");
    }
}

抽象工廠類:FruitFactory.java

public interface FruitFactory {
    public Apple getApple();
    public Banana getBanana();
}

工廠類:NorthFactory.java

public class NorthFactory implements FruitFactory {
    @Override
    public Apple getApple() {
        return new NorthApple();
    }

    @Override
    public Banana getBanana() {
        return new NorthBanana();
    }
}

工廠類:SouthFactory.java

public class SouthFactory implements FruitFactory {
    @Override
    public Apple getApple() {
        return new SouthApple();
    }

    @Override
    public Banana getBanana() {
        return new SouthBanana();
    }
}

如果要增加商品族Foreign,只需要增加工廠類ForeignFactory即可;
如果要增加商品等級Pear,則需要增加商品等級Pear,商品類NorthPearSouthPear,爲抽象工廠類/工廠類FruitFactory, NorthFactory, SouthFactory增加getPear方法

發佈了715 篇原創文章 · 獲贊 141 · 訪問量 24萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章