设计模式——工厂方法模式

来源:互联网 发布:php源码分析 编辑:程序博客网 时间:2024/06/05 19:28

定义


Define an interface for creating an object, but let subclass decide which class to instantiate. Factory Method lets a class defer instantiation to subclass.

使用场景


  • 所有需要生成对象的地方均可使用,但需考虑代码复杂度的增加。
  • 需要灵活、可拓展的框架时。
  • 异构项目。

UML


示例


抽象产品类

public interface Product {    void method();}

具体产品类

public class ConcreteProduct1 implements Product {    @Override    public void method() {    }}

抽象工厂类

public interface Creator {    <T extends Product> T FactoryMethod(Class<T> clz);}

具体工厂类

public class ConcreteCreator implements Creator {    @Override    public <T extends Product> T FactoryMethod(Class<T> clz) {        Product product = null;        try {            product = (T)Class.forName(clz.getName()).newInstance();        } catch (ClassNotFoundException | IllegalAccessException | InstantiationException e) {            e.printStackTrace();        }        return (T) product;    }}

场景类

public class Client {    public static void main(String[] args){        ConcreteCreator creator = new ConcreteCreator();        Product product1 = creator.FactoryMethod(ConcreteProduct1.class);        product1.method();    }}

优点


  • 良好的封装性,代码结构清晰。如需调用具体产品对象,只需知道产品类名,降低模块间的耦合度。
  • 扩展性优秀。
  • 屏蔽产品类,产品类如何变化,调用者无需担心。例:JDBC 切换数据库。
  • 符合迪米特原则、依赖倒置原则、里式替换原则。

扩展


简单工厂模式

使用场景

仅需一个工厂类。

UML

示例

去掉抽象工厂类,将工厂类中创建对象的方法设置为 static,简化类的创建流程。

工厂类

public class Factory {    public static <T extends Product> T FactoryMethod(Class<T> clz) {        Product product = null;        try {            product = (T)Class.forName(clz.getName()).newInstance();        } catch (ClassNotFoundException | IllegalAccessException | InstantiationException e) {            e.printStackTrace();        }        return (T) product;    }}

场景类

public class Client {    public static void main(String[] args){        Product product1 = Factory.FactoryMethod(ConcreteProduct1.class);        Product product2 = Factory.FactoryMethod(ConcreteProduct2.class);        product1.method();        product2.method();    }}

局限

扩展比较困难,不符合开闭原则。

多工厂模式

使用场景

产品类初始化复杂,导致工厂方法臃肿时。

示例

具体工厂类

public class ConcreteCreator1 implements Creator {    @Override    public Product createProduct() {        return new ConcreteProduct1();    }}

场景类

public class Client {    public static void main(String[] args){        Product product1 = (new ConcreteCreator1()).createProduct();        product1.method();    }}

优点

类职责清晰,结构简单。

局限

影响可扩展性与可维护性。

代替单例模式

示例

单例类

public class Singleton {    private Singleton(){}    public void method(){        System.out.print("Singleton");    }}

工厂类

public class SingletonFactory {    private static Singleton singleton;    static {        try {            Class clz = Class.forName(Singleton.class.getName());            Constructor constructor = clz.getDeclaredConstructor();            constructor.setAccessible(true);            singleton = (Singleton) constructor.newInstance();        } catch (ClassNotFoundException | NoSuchMethodException | IllegalAccessException | InvocationTargetException | InstantiationException e) {            e.printStackTrace();        }    }    public static Singleton getSingleton(){        return singleton;    }}

场景类

public class Client {    public static void main(String[] args){        Singleton singleton = SingletonFactory.getSingleton();        singleton.method();    }}

延迟初始化

使用场景

  • 限制某一产品类的最大实例化数量。
  • 对象初始化复杂。

示例

使用 Map 对需要再次重用的对象进行缓存。

延迟加载工厂类

public class Factory {    private static Map<String, Product> map = new HashMap();    public static <T extends Product> T createProduct(Class<T> clz){        Product product;        String cname = clz.getName();        if(map.containsKey(cname)){            product = map.get(cname);        }else{            if(cname.equals(ConcreteProduct1.class.getName())){                product = new ConcreteProduct1();            }else{                product = new ConcreteProduct2();            }            map.put(cname, product);        }        return (T) product;    }}

场景类

public class Client {    public static void main(String[] args){        Product product1 = Factory.createProduct(ConcreteProduct1.class);        Product product2 = Factory.createProduct(ConcreteProduct2.class);        product1.method();        product2.method();    }}

END ~

0 0
原创粉丝点击