Effective Java —— 考虑用静态工厂方法代替构造器
2017-09-06 23:34
686 查看
构造器与静态工厂方法对比
Boolean对象中的静态工厂方法public static Boolean valueOf(Boolean b){ return b ? Boolean.TRUE : Boolean.FALSE; }
下面两种对象生成方式比较
//使用构造器 Boolean b1 = new Boolean(true); //使用静态工厂方法 Boolean b2 = Boolean.valueOf(true);
传入同样的参数为什么要用静态工厂方法替代构造器呢?
静态工厂方法优点
第一:静态工厂方法有名称一个类只能有一个带有指定签名(JVM为我们提供的方法签名实际上是由方法名、形参列表、返回值三部分构成的)的构造器。而静态工厂方法我们可以通过不同的名称来描述不同的构造方法,便于代码阅读。
第二:不必每次调用时都创建一个新的对象
Boolean.valueOf(boolean)方法就说明了这个有点,使用预先构建好的实例,或者将构建好的实例缓存起来,进行重复利用。
第三:可以返回原返回类型的任何子类型的对象
静态工厂方法返回对象所属的类可以是后来动态添加的。具体可以看后面的服务提供者框架
第四:在创建参数化类型实例时更简洁
假如HashMap提供了这个静态工厂
public static <K, V> HashMap<K, V> newInstance(){ return new HashMap<K, V>(); }
那么
//使用构造器创建 Map<String, List<String>> m1 = new HashMap<String, List<String>>(); //使用静态工厂方法创建 Map<String, List<String>> m2 = HashMap.newInstance();
服务提供者框架
服务提供者框架是指:多个服务提供者实现一个服务,系统为客户端提供多个实现,并把他们从多个实现中解耦出来。静态工厂方法返回的对象所属的类,在编写包含该静态工厂方法的类时可以不必存在。这种灵活的静态工厂方法构成 服务提供者框架 的基础。典型应用JDBC API。服务提供者三个重要组件:
服务接口
提供者注册API
服务访问API
服务提供者接口(可选)
首先我们先来看一下jdbc中获取mysql数据库连接对象的源码:
Class.forName("com.mysql.jdbc.Driver"); DriverManager.getConnection("jdbc:mysql://localhost:3306/test","root","123");
以北京地铁进出控制为例:现在北京地铁进出都是刷卡,有二种卡:1.一卡通(比如一次性冲值50元,进地铁刷一次,出地铁刷一次,扣2元)。2.一次性卡(进地铁刷一次,出地铁插入回收。)
服务定义接口
//进出地铁服务接口 public interface SubWayInterface { //进入地铁 public boolean in(); //出地铁 public boolean out(); }
服务具体实现
//一卡通地铁进出服务实现 public class SubWayImpl implements SubWayInterface { public boolean in() { System.out.println("通过一卡通进入地铁"); /** * 进行一些处理,然后返回是否放行 */ return false; } public boolean out() { System.out.println("通过一卡通出地铁"); /** * 进行一些处理,然后返回是否放行 */ return false; } }
服务提供者接口
//地铁进出服务提供者接口 public interface SubwayProviderInterface { public SubWayInterface getService(); }
服务提供者具体实现
//服务提供者实现类 这里返回了服务接口SubWayInterface public class SubwayProviderImpl implements SubwayProviderInterface { static { ServiceManager.registerProvider("一卡通", new SubwayProviderImpl()); } public SubWayInterface getService() { return new SubWayImpl(); } }
服务提供者注册类实现
public class ServiceManager { private ServiceManager() { } private static final Map<String, SubwayProviderInterface> providers = new ConcurrentHashMap<String, SubwayProviderInterface>(); public static void registerProvider(String name, SubwayProviderInterface p) { providers.put(name, p); } public static SubWayInterface getService(String name) { SubwayProviderInterface p = providers.get(name); if (p == null) { throw new IllegalArgumentException( "No provider registered with name:" + name); } return p.getService(); } }
测试
public static void main(String[] args) throws ClassNotFoundException { //Class.forName("")里面的参数放的完整包路径加类名 Class.forName("cn.netjava.cgl.subway.SubwayProviderImpl"); SubWayInterface swi = ServiceManager.getService("一卡通"); swi.in(); swi.out(); }
缺点
类如果不含公有的或者受保护的构造器,就不能被子类实例化。他们与其他的静态方法实际上没有任何区别。
惯用名称
valueOf-不太严格地讲,该方法返回的实例与它的参数具有相同的值。这样的静态工厂方法实际上是类型转换方法。of-valueOf的一种简洁替代。
getInstance-返回的实例是通过方法的参数来描述的,但是对于Singleton来说,该方法没有参数,并返回唯一的实例。
newInstance-可以确保返回的每个实例都不同
getType-像getInstance一样,但是在工厂方法处于不同的类中的时候使用。type表示工厂方法所返回的对象类型。
newType-像newInstance一样,但是在工厂方法处于不同的类中的时候使用。type表示工厂方法所返回的对象类型。
参考
JAVA服务提供者框架介绍 作者:liwenshui322相关文章推荐
- Effective java第一条:考虑用静态工厂方法代替构造器
- EffectiveJava-考虑用静态工厂方法代替构造器
- Effective Java 1:考虑使用静态工厂方法代替构造器
- Effective Java 中文版之学习 第1条:考虑用静态工厂方法代替构造器
- 【Effective Java笔记】第1条:考虑用静态工厂方法代替构造器
- 改善JAVA代码01:考虑静态工厂方法代替构造器
- Effective Java第一条:考虑用静态工厂方法替代构造器
- Effective Java 3rd 条目1 考虑用静态工厂方法代替构造子
- 改善JAVA代码01:考虑静态工厂方法代替构造器
- Java学习笔记1:考虑用静态工厂方法代替构造器
- Effective Java 学习笔记 使用静态工厂方法代替构造器
- Java学习笔记1:考虑用静态工厂方法代替构造器
- Java学习笔记1:考虑用静态工厂方法代替构造器
- Effective Java -- 用静态工厂方法来代替构造器
- 第一条:考虑用静态工厂方法代替构造器
- 01、考虑用静态工厂方法代替构造器
- Effective Java学习笔记之第1条 考虑用静态工厂方法代替构造器
- Effective Java 第一条:考虑用静态工厂方法代替构造器
- Android 编码规范:(一)考虑用静态工厂方法代替构造器
- [Effective Java Distilled] Item 1 考虑使用静态工厂方法来替换构造方法