静态工厂代替构造器

   也许你很早就听说过静态工厂了,可是他有什么用呢?下面我将分享自己从书上和项目中得到的一些心得,本文所指的是静态工厂和设计模式种的工厂方法不同。
	1、静态工厂与构造器相比有名称
	 有名称可读性就好
	 2、复用对象
	 也许你并不想每次都new一个对象,比如Boolean.valueOf()用的就是这种方法,缓存了一个对象,供调用者获取,而不是每次显示创建。另外,你也许想要做可控的实例,什么是可控呢,简单来说,你不想随便让人构造对象时滥用参数,我在项目中就遇到过这个问题。返回结果的一个类,这个类只能返回三种状态,不想让调用者自己传递状态,往往会出错。这里也就可以考虑一个静态工厂去做受控实例!
	 3、导出子类
	 静态工厂可以返回子类,增加api的灵活性,jdk种的Collections类就是这么干的!私有化构造器,
	 但是可以通过工厂导出子类如同步集合,不可变集合等。这里我贴出代码
	 下面展示一些 `内联代码片`。
// An highlighted block
public static <E> Set<E> newSetFromMap(Map<E, Boolean> map) {
        return new SetFromMap<>(map);
    }
	 4、条件判读
	 在工厂中你可以根据传递的参数来对条件进行判断,从而产生不同的对象,比如EnumSet就不提供公有的构造器,提供了静态工厂,如果传递的参数(一个枚举)中的元素超过64和小于64是不同的,这里我把代码粘出来
下面展示一些 `内联代码片`。
// a static factory
public static <E extends Enum<E>> EnumSet<E> noneOf(Class<E> elementType) {
        Enum<?>[] universe = getUniverse(elementType);
        if (universe == null)
            throw new ClassCastException(elementType + " not an enum");

        if (universe.length <= 64)
            return new RegularEnumSet<>(elementType, universe);
        else
            return new JumboEnumSet<>(elementType, universe);
    }
  5、方法返回的类可以是在编写该工厂时不存在的
  这句话好像有点玄乎,用服务提供者框架来举例吧!服务提供者框架的三个组件:1、服务接口,提供者用来实现
  2、提供者注册API,提供者用来注册 3、服务访问API,客户端用来获取服务实例的
  场景是这样的:sun公司在制定jdbc规则的时候,倘若mysql还未出现,或者别的未了解的数据库怎么使用呢?
  步骤是让提供者去实现服务接口,这些接口是sun约定好的,这时候提供商比如mysql实现这些接口,然后使用者只需要注册使用反射机制Class.forName(真正注册过程的代码mysql封装在com.mysql.jdbc.Drive类中的静态代码块里),一旦Class.forName("com.mysql.jdbc.Drive")即注册上去,具体代码如下
  下面展示一些 `内联代码片`
// An highlighted block
package com.mysql.jdbc;

import com.mysql.jdbc.NonRegisteringDriver;
import java.sql.DriverManager;
import java.sql.SQLException;

public class Driver extends NonRegisteringDriver implements java.sql.Driver {
    public Driver() throws SQLException {
    }

    static {
        try {
            DriverManager.registerDriver(new Driver());
        } catch (SQLException var1) {
            throw new RuntimeException("Can\'t register driver!");
        }
    }
}
 // List of registered JDBC drivers
 private final static CopyOnWriteArrayList<DriverInfo> registeredDrivers = new CopyOnWriteArrayList<DriverInfo>();

    public static synchronized void registerDriver(java.sql.Driver driver)
        throws SQLException {
        if(driver != null) {
            registeredDrivers.addIfAbsent(new DriverInfo(driver));
        } else {
            throw new NullPointerException();
        }
        println("registerDriver: " + driver);

    }

注册完成后,使用者调用服务访问api即可。通过工厂获取!!!
DriverManager.getConnection(“jdbc:mysql:///mydatabase”, “root”, “root”);
下面展示一些 内联代码片

// An highlighted block
  public static Connection getConnection(String url)
        throws SQLException {

        java.util.Properties info = new java.util.Properties();

        // Gets the classloader of the code that called this method, may
        // be null.
        ClassLoader callerCL = DriverManager.getCallerClassLoader();

        return (getConnection(url, info, callerCL));
    }

其实这就是我们想说的第五点!!方法返回的对象的类,未必在编写工厂时就存在!因为这个Connection是从注册的Driver里获取的,实际上返回的是mysql的connection!

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值