- 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();
}
注意,這裏的商品等級Apple
和Banana
不需要像簡單工廠模式和工廠方法模式中那樣基於同一個基類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
,商品類NorthPear
,SouthPear
,爲抽象工廠類/工廠類FruitFactory
, NorthFactory
, SouthFactory
增加getPear
方法