工廠模式
- 描述
- 簡單工廠(靜態工廠)
- 工廠方法模式
- 抽象工廠
- 增加工廠管理類
- 使用
描述
工廠模式用以封裝復雜的實例初始化過程,供外部統一調用
簡單工廠(靜態工廠)
如果對象創建邏輯簡單且一致,可以使用簡單工廠。傳入想要生成的實例類型
public class HumanFactory {public static <T> T getInstance(Class<T> c) {try {return (T) Class.forName(c.getName()).getDeclaredConstructor().newInstance();} catch (Exception e) {throw new RuntimeException("生成對象異常", e);}}
}
工廠方法模式
多種類型產品初始化邏輯不一致時,可以采用不同工廠實例來初始化對應類型的產品
由于每種產品定義了對應的工廠類,因此工廠方法不需要類型參數就非常明確需要創建的實例
- 聲明工廠抽象定義
public abstract class AbstractProductFactory {public abstract Product createProduct();
}
- 聲明產品抽象定義
public interface Product {String getName();default void description() {System.out.println("產品名稱:" + getName());}
}
- 定義具體產品
public class Apple implements Product {@Overridepublic String getName() {return "蘋果";}
}public class Banana implements Product {@Overridepublic String getName() {return "香蕉";}
}
- 定義產品對應的工廠
public class AppleFactory extends AbstractProductFactory {public Product createProduct() {// 蘋果其他初始化邏輯return new Apple();}
}public class BananaFactory extends AbstractProductFactory {public Product createProduct() {// 香蕉其他初始化邏輯return new Banana();}
}
- 使用
public static void main(String[] args) {AbstractProductFactory appleFactory = new AppleFactory();Product product = appleFactory.createProduct();product.description();AbstractProductFactory bananaFactory = new BananaFactory();Product banana = bananaFactory.createProduct();banana.description();
}
抽象工廠
以上工廠方法,一個產品就需要一個工廠類。
如果產品本身就有一些共通的地方,我們可以將產品劃分到同一個工廠的不同產品線,這些產品的生產可以共用一些資源。
比如,我的產品都分為大、中、小三種分類。分別進行不同的加工
- 聲明抽象水果
public interface Fruit {String getName();String getSize();default void description() {System.out.println("產品名稱:" + getSize() + getName());}
}
- 聲明具體水果
public class BigApple implements Fruit {@Overridepublic String getName() {return "蘋果";}@Overridepublic String getSize() {return "大號";}
}public class MiddleApple implements Fruit {@Overridepublic String getName() {return "蘋果";}@Overridepublic String getSize() {return "中號";}
}public class SmallApple implements Fruit {@Overridepublic String getName() {return "蘋果";}@Overridepublic String getSize() {return "小號";}
}
public class BigBanana implements Fruit {@Overridepublic String getName() {return "香蕉";}@Overridepublic String getSize() {return "大號";}
}public class MiddleBanana implements Fruit {@Overridepublic String getName() {return "香蕉";}@Overridepublic String getSize() {return "中號";}
}public class SmallBanana implements Fruit {@Overridepublic String getName() {return "香蕉";}@Overridepublic String getSize() {return "小號";}
}
- 聲明抽象工廠
public abstract class AbstractFruitFactory {abstract Fruit bigFruit();abstract Fruit middleFruit();abstract Fruit smallFruit();
}
- 定義具體工廠
public class AppleFruitFactory extends AbstractFruitFactory{@OverrideFruit bigFruit() {return new BigApple();}@OverrideFruit middleFruit() {return new MiddleApple();}@OverrideFruit smallFruit() {return new SmallApple();}
}
public class BananaFruitFactory extends AbstractFruitFactory {@OverrideFruit bigFruit() {return new BigBanana();}@OverrideFruit middleFruit() {return new MiddleBanana();}@OverrideFruit smallFruit() {return new SmallBanana();}
}
增加工廠管理類
當抽象工廠的子類擴展時,調用方需要和各個子類工廠交互,在一定程度上違反了迪米特法則。
我們可以將工廠子類交由工廠管理類進行管理,調用方只需要和這個管理類交互即可
public final class FruitFactoryManager {private static Map<String, AbstractFruitFactory> register = new HashMap<>();static {register.put("apple", new AppleFruitFactory());register.put("banana", new BananaFruitFactory());}public static AbstractFruitFactory getFactory(String factoryCode) {return register.get(factoryCode);}
}
使用
public class Sample {public static void main(String[] args) {AbstractFruitFactory appleFactory = new AppleFruitFactory();Fruit smallApple = appleFactory.smallFruit();smallApple.description();Fruit middleApple = appleFactory.middleFruit();middleApple.description();Fruit bigApple = appleFactory.bigFruit();bigApple.description();AbstractFruitFactory bananaFactory = new BananaFruitFactory();Fruit smallBanana = bananaFactory.smallFruit();smallBanana.description();Fruit middleBanana = bananaFactory.middleFruit();middleBanana.description();Fruit bigBanana = bananaFactory.bigFruit();bigBanana.description();}
}