博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
【02】创建型-工厂方法
阅读量:7080 次
发布时间:2019-06-28

本文共 3222 字,大约阅读时间需要 10 分钟。

  hot3.png

1、上下文及问题

    有些对象的实例化比较复杂,比如读哪些配置文件,按哪些步骤初始化等等,这种问题,通常使用工厂方法,来对调用者屏蔽对象的创建逻辑。

2、常见场景

(1)需要对对象的实例进行管理的,比如统计/限制实例个数、实例回收等等,可以交由工厂来管理,比如数据库连接池

(2)多线程情况下,通常需要保证对象的不能够发布逃逸,就是在构造器初始化中将未实例化完成的对象发布出去,比如赋值给外部对象,或者在构造器开线程去访问等等,容易出现问题,因而可以用工厂方法,确保对象构造完后再加上某些必要的步骤之后才发布对象。

(3)如果一个类本身希望由子类来实例化,则很明显的要使用工厂方法

(4)数据库连接池、线程池、ThreadLocal

3、解决方式

(1)使用继承的方式解决,类的实例化延迟到具体的子类

4、模式抽象图

161610_i3D8_1383356.png

5、代码示例

(1)UML类图代码示例

Product及其实现类

/*** @author cbf4Life cbf4life@126.com* I'm glad to share my knowledge with you all.* 抽象产品类*/public abstract class Product {    //产品类的公共方法    public void method1(){        //业务逻辑处理    }    //抽象方法1    public abstract void method2();}public class ConcreteProduct1 extends Product {    public void method2() {        //业务逻辑处理    }}public class ConcreteProduct2 extends Product {    public void method2() {        //业务逻辑处理    }}

   工厂及其实现类

public abstract class Factory{    /*     * 创建一个产品对象,其输入参数类型可以自行设置     * 通常为String、Enum、Class等,当然也可以为空     */    public abstract 
 T createProduct(Class
 c);}public class ConcreteFactory extends Factory {    public 
 T createProduct(Class
 c){        Product product=null;        try {             product = (Product)Class.forName(c.getName()).newInstance();        } catch (Exception e) {            //异常处理        }                return (T)product;            }}

客户端调用

public class Client {    public static void main(String[] args) {        Factory factory= new ConcreteFactory();        Product product = factory.createProduct(ConcreteProduct1.class);        /*         * 继续业务处理         */    }}

(2)外部利用反射产生单例

public class Singleton {    //不允许通过new产生一个对象    private Singleton(){    }    public void doSomething(){        //业务处理    }}

    外部反射产生单例

/*** @author cbf4Life cbf4life@126.com* I'm glad to share my knowledge with you all.*/public class SingletonFactory {    private static Singleton singleton;    static{         try {            Class cl= Class.forName(Singleton.class.getName());            //获得无参构造            Constructor constructor=cl.getDeclaredConstructor();            //设置无参构造是可访问的            constructor.setAccessible(true);            //产生一个实例对象            singleton = (Singleton)constructor.newInstance();        } catch (Exception e) {            //异常处理        }            }    public static Singleton getSingleton(){        return singleton;        }}

   客户端调用

public class Client {    public static void main(String[] args) {        SingletonFactory.getSingleton().doSomething();    }}

(3)缓存示例

/*** @author cbf4Life cbf4life@126.com* I'm glad to share my knowledge with you all.*/public class Factory {    private static final Map
 prMap = new HashMap();    public static synchronized  Product createProduct(String type) throws Exception{        Product product =null;        //如果Map中已经有这个对象        if(prMap.containsKey(type)){            product = prMap.get(type);        }else{            if(type.equals("Product1")){                product = new ConcreteProduct1();            }else{                product = new ConcreteProduct2();            }            //同时把对象放到缓存容器中            prMap.put(type,product);        }        return product;    }}

转载于:https://my.oschina.net/scipio/blog/282235

你可能感兴趣的文章
mongodb自带监控 mongostat数值说明
查看>>
教与学的思考
查看>>
阿里云maven仓库地址
查看>>
学习资料积累
查看>>
linux下挂载U盘的方法
查看>>
linux 基础练习题、面试题(一)
查看>>
Java(Mybatis)和SQL(MySQL)之间的数据类型转换
查看>>
如何在windows server 2008上配置NLB群集
查看>>
爱情是人类最高贵的情感
查看>>
我的友情链接
查看>>
C++ 异常学习
查看>>
EX2003升级到EX2010 无法自动装载数据库!!
查看>>
23 款实用的 Elasticsearch 查询示例
查看>>
提高PHP代码质量36计(1)
查看>>
C++_CFileFind文件查找
查看>>
VS_生成事件
查看>>
关于android布局的两个属性dither和tileMode
查看>>
Top 10 JavaScript编辑器,你在用哪个?
查看>>
MySQL数据库 添加用户、删除用户与授权
查看>>
Heartbeat-Gui V2 实现HA LAMP 搭建wordpress博客
查看>>