工厂模式 什么是工厂?批量加工我需要的产品(对象)
Define an interface for creating an object, but let subclasses decide which class to instance. Factory Method lets a class defer instantiation to subclass.
UML类图:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 @startuml factory method abstract class Creator{ + factoryMethod() } class ConcreteCreator{ + factoryMethod() } abstract class Product{ + method() } class ConcreteProduct{ + method() } Creator --> Product Creator <|-- ConcreteCreator Product <|-- ConcreteProduct @enduml
面向对象设计的基本原则:
OCP
(开闭原则, Open-Closed Principle
):一个软件的实体应当对扩展开放,对修改关闭。
DIP
(依赖倒转原则,Dependence Inversion Principle
):要针对接口编程,不要针对实现编程。
LoD
(迪米特法则, Law of Demeter
):只与你直接的朋友通信,而避免和陌生人通信。
工厂方法模式实例 抽象产品类
1 2 3 4 5 6 7 8 9 public abstract class Product { public void commonMethod () { System.out.println("Hello world!" ); } public abstract void method () ; }
具体产品类
1 2 3 4 5 6 public class ConcreteProduct extends Product { @Override public void method () { System.out.println("doing something..." ); } }
抽象工厂类(Creator)
1 2 3 4 5 6 7 8 9 public abstract class Creator { public abstract <T extends Product> T createProduct (Class<T> cls) ; }
具体工厂类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 public class ConcreteCreator extends Creator { @Override public <T extends Product> T createProduct (Class<T> cls) { Product product = null ; try { product = (Product) Class.forName(cls.getName()).newInstance(); } catch (InstantiationException | IllegalAccessException | ClassNotFoundException e) { e.printStackTrace(); } return (T) product; } }
客户端(使用者)
1 2 3 4 5 6 public static void main (String[] args) { Creator creator = new ConcreteCreator(); final ConcreteProduct product = creator.createProduct(ConcreteProduct.class); product.commonMethod(); product.method(); }
简单工厂(Simple Factory) 有时候我们的产品(对象)
可能只需要一个工厂类
,于是使用静态方法就行
UML类图如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 @startuml simple facotry class Client{ } class ConcreteCreator{ + static createProduct(): Product } abstract class Product{ + method() } class ConcreteProduct{ + method() } Client --> Product Client --> ConcreteCreator Product <|-- ConcreteProduct @enduml
抽象产品类
1 2 3 4 5 6 7 8 9 public abstract class Product { public void commonMethod () { System.out.println("Hello world!" ); } public abstract void method () ; }
具体产品类
1 2 3 4 5 6 public class ConcreteProduct extends Product { @Override public void method () { System.out.println("doing something..." ); } }
简单工厂类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 public class ConcreteCreator { public static <T extends Product> T createProduct (Class<T> cls) { Product product = null ; try { product = (Product) Class.forName(cls.getName()).newInstance(); } catch (InstantiationException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } catch (ClassNotFoundException e) { e.printStackTrace(); } return (T) product; } }
客户端(使用者)
1 2 3 4 5 public static void main (String[] args) { final ConcreteProduct product = ConcreteCreator.createProduct(ConcreteProduct.class); product.commonMethod(); product.method(); }
工厂方法模式代替单例模式 如何使用工厂方法模式实现单例模式的功能呢?单例不允许通过正常渠道创建对象,所以我们可以通过反射的方式
来创建.
UML类图:
1 2 3 4 5 6 7 8 9 10 11 12 @startuml factory method singleton class SingletonFactory{ - static Singleton singleton + static Singleton getInstance() } class Singleton{ - singleton() + void method() } SingletonFactory o-- Singleton @enduml
需要处理为单例对象的类
1 2 3 4 5 6 7 8 9 public class Singleton { private Singleton () {} public void say () { System.out.println("Hello World!" ); } }
单例工厂
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 public class SingletonFactory { private static Singleton singleton; static { try { final Class cls = Class.forName(Singleton.class.getName()); final Constructor constructor = cls.getDeclaredConstructor(); constructor.setAccessible(true ); singleton = (Singleton) constructor.newInstance(); } catch (ClassNotFoundException e) { e.printStackTrace(); } catch (NoSuchMethodException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } catch (InstantiationException e) { e.printStackTrace(); } catch (InvocationTargetException e) { e.printStackTrace(); } } public static Singleton getInstance () { return singleton; } }
具体调用
1 2 3 public static void main (String[] args) { SingletonFactory.getInstance().say(); }
延迟初始化 延迟初始化(Lazy initialization),当对象第一次被调用的时候才去进行初始化,并且使用完后,不立即回收,等待被再次调用.
UML类图
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 @startuml lazy initialization abstract class Product{ + doSomething() } class ConcreteProduct{ + doSomething() } class ProductFactory{ + static final Map<Class,Product> productMap = new HashMap() + static synchrinized <T extends Product> T createProduct(Class<T> cls) } ProductFactory o-- Product Product <|-- ConcreteProduct @enduml
ProductFactory
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 public class ProductFactory { private static final Map<Class, Product> productMap = new HashMap<>(16 ); public static synchronized <T extends Product> T createProduct (Class<T> cls) { Product product = null ; if (null != productMap.get(cls)){ product = productMap.get(cls); } else { try { product = (Product) Class.forName(cls.getName()).newInstance(); productMap.put(cls, product); } catch (InstantiationException | ClassNotFoundException | IllegalAccessException e) { e.printStackTrace(); } } return (T) product; } }
Product
1 2 3 4 5 6 7 8 9 public abstract class Product { public void commonMethod () { System.out.println("Hello world!" ); } public abstract void method () ; }
ConcreteProduct
1 2 3 4 5 6 7 public class ConcreteProduct extends Product { @Override public void method () { System.out.println("doing something..." ); } }
Client
1 2 3 4 5 6 7 8 9 public class Client { public static void main (String[] args) { final Product concreteProduct = ProductFactory.createProduct(ConcreteProduct.class); final Product concreteProduct1 = ProductFactory.createProduct(ConcreteProduct.class); System.out.println(concreteProduct.hashCode()); System.out.println(concreteProduct1.hashCode()); } }
实例部分 简单工厂 1 2 3 4 public abstract class Coffee { abstract String getName () ; }
1 2 3 4 5 6 7 public class LatteCoffee extends Coffee { @Override String getName () { return "LatteCoffee" ; } }
1 2 3 4 5 6 7 8 9 public class SimpleFactory { public static Coffee createCoffee (Class clazz) { if (Coffee.class.equals(clazz)){ return new LatteCoffee(); } else { throw new RuntimeException("none" ); } } }
利用反射实现
1 2 3 4 5 6 7 8 9 10 11 12 13 public class StaticFactory { public static <T extends Coffee> T createCoffee (Class<T> clazz) { try { return (T) Class.forName(clazz.getName()).newInstance(); } catch (Exception e){ e.printStackTrace(); System.out.println("error happened when instance!" ); } return null ; } }
多方法静态工厂(类似Executor类)
1 2 3 4 5 6 7 public class ManyStaticFactory { public static Coffee createLatte () { return new LatteCoffee(); } ... }
工厂方法 将类的初始化推迟到子类(抽象工厂 -> 具体工厂 )
1 2 3 4 public abstract class CoffeeFactory { public abstract String createCoffee () ; }
1 2 3 4 5 6 7 public class LatteCoffeeFactory extends CoffeeFactory { @Override public String createCoffee () { return "LatteCoffee" ; } }
1 2 3 4 5 6 public class FactoryMethod { public static void main (String[] args) { CoffeeFactory coffeeFactory = new LatteCoffeeFactory(); System.out.println(coffeeFactory.createCoffee()); } }
抽象工厂 饮料抽象 1 2 3 4 5 6 7 8 9 public abstract class Beverage { public abstract String getName () ; }
1 2 3 4 5 6 7 public class LatteCoffee extends Beverage { @Override public String getName () { return "LatteCoffee" ; } }
1 2 3 4 5 6 7 public class Tea extends Beverage { @Override public String getName () { return "Tea" ; } }
工厂抽象 1 2 3 4 5 6 7 8 9 10 11 12 13 14 public abstract class AbstractFactory { public abstract LatteCoffee createCoffee () ; public abstract <T extends LatteCoffee> T createCoffee (Class<T> clazz) ; public abstract Tea createTea () ; public abstract <T extends Tea> T createTea (Class<T> clazz) ; }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 public class StarbucksFactory extends AbstractFactory { @Override public LatteCoffee createCoffee () { return new LatteCoffee(); } @Override public <T extends LatteCoffee> T createCoffee (Class<T> clazz) { try { return (T) Class.forName(clazz.getName()).newInstance(); } catch (Exception e){ e.printStackTrace(); System.out.println("error happened when LatteCoffee instance!" ); } return null ; } @Override public Tea createTea () { return new Tea(); } @Override public <T extends Tea> T createTea (Class<T> clazz) { try { return (T) Class.forName(clazz.getName()).newInstance(); } catch (Exception e){ e.printStackTrace(); System.out.println("error happened when Tea instance!" ); } return null ; } }
测试代码
1 2 3 4 5 6 7 8 9 public static void main (String[] args) { StarbucksFactory starbucksFactory = new StarbucksFactory(); System.out.println(starbucksFactory.createTea().getName()); System.out.println(starbucksFactory.createTea(Tea.class).getName()); System.out.println(starbucksFactory.createCoffee().getName()); System.out.println(starbucksFactory.createCoffee(LatteCoffee.class).getName()); }