Effective Java
来源:互联网 发布:modbus tcp编程实例 编辑:程序博客网 时间:2024/06/10 17:19
静态工厂方法代替构造器
读书笔记,仅供参考
ps: 静态工厂方法只是一个返回类的实例的静态方法, 与设计模式中的工厂方法并不一样
public static Boolean valueOf(boolean b) { return b? Boolean.TRUE: Bolean.FALSE;}
工厂方法的优势
拥有名称
构造器的参数有时无法确切的描述返回的对象,静态工厂方法可以通过方法名进行表示, 所以当一个类需要多个相同签名(具有相同的方法名,相同个数和相同类型参数)的构造器时,可以使用静态工厂方法代替构造器
不必在每次都创建一个新对象
- 避免创建不必要的重复对象
- 不可变类可以使用预先构建好的实例或者是缓存的实例
有助于类控制实例是否存在,称为实例受控的类(instance-controlled)
实例受控的类
- 可以被确保为 Singleton
- 可以被确保为不可实例化
- 使不可变的类可以确保不存在两个相等的实例,可以使用 == 代替 equals,提升性能
可以返回原返回类型的任何子类型
- 适用于基于接口的框架(接口为静态工厂方法提供了自然返回类型,但是接口不能有静态方法,所有将方法放在一个不可实例化的类中)
例子为 java.utils.Colllections 类,这个类是一个不可实例化的类,静态方法返回的类可以是非公有的。下面的代码是在这个类中找到的符合上面说法的例子。这里也证明了平常使用接口引用实现类的用法。
public static <K, V> Map<K, V> checkedMap(Map<K, V> m, Class<K> keyType, Class<V> valueType) { return new CheckedMap<>(m, keyType, valueType); } private static class CheckedMap<K,V> implements Map<K,V>, Serializable { }
- 服务提供者框架(Service Provider Framework)
静态工厂返回的对象的类,在编写包含静态工厂方法的类时可以不存在,这构成了服务提供者框架的基础。如 JDBC。
服务提供者框架:多个服务提供者实现一个服务,系统为服务提供者的客户端提供多个实现,并把它们从多个实现中解耦出来。
三个重要组件:- 服务接口:提供者实现
- 提供者注册API:系统注册实现类
- 服务访问API:客户端获取服务实例
- 服务提供者接口:提供者创建服务的实例(此组件可选)
//服务接口public interface Service {}//服务提供者接口public interface Provider { Service newService();}//服务注册和方位, 不可实例化的类public class Services { private Service(){} private static final Map<String, Provider> provider = new ConcurrentHashMap<String, Provider>(); public static final String DEFAULT_PROVIDER_NAME = "<def>"; //提供者注册API public static void registerDefaultProvider(Provider p) { registerProvider(DEFAULT_PROVIDER_NAME, p); } public static void registerProvider(String name, Provider p) { providers.put(); } //服务访问API public static Service newInstance() { return newInstance(DEFAULT_PROVIDER_NAME); } public static Service newInstance(String name) { Provider p = providers.get(name); if(p == null) throw new IllegalArgumentException("***"); return p.newService(); }}
这个服务者框架和我现在做的一个项目中一部分有相似的情况,项目是支付平台,支持支付宝和微信,所以有两个 service, AliPayService 和 WechatPayService,他们都实现了 InternalPayService 接口,在使用 spring 的情况下,使用如下代码
@Autowired private Map<String, InternalPayService> payServices;
可以自动得到一个Map,里面有两个KV,即上面两个实现类,可以说 spring 实现了上面的服务者框架。
在创建参数化类型实例时,使代码变得更加简洁
例子:
Map<String, List<String>> m = new HashMap<String, List<String>>();
假设实现了以下方法
public static <K, V> HashMap<K, V> newINstance() { return new HashMap<K, V>();}
第一处的代码可修改为
Map<String, List<String>> m = HashMap.newInstance();
虽然现在的 jdk 已经可以不用再在后面重复类型参数了,精神可以学习。
缺点
类如果不含有公有的或者受保护的构造器,就不能被子类化
这一点可以鼓励使用复合,而不是继承
与其他静态方法没有区别
在查找时不方便
阅读全文
0 0
- Effective Java
- Effective Java
- Effective Java
- Effective Java
- effective java
- effective java
- Effective Java
- Effective Java
- effective java
- Effective Java
- Effective Java
- 《Effective Java》
- effective java
- effective java
- Effective Java
- Effective Java
- 《Effective java》
- Effective Java
- 老何CAD工具箱 v1.2免费版下载
- 维护区间gcd(线段树 || ST表+二分)
- AngularJS(二)Deployd搭建
- 给图像加高斯噪声和椒盐噪声(不使用自带函数)matlab实现
- Java NIO系列教程(11):Pipe
- Effective Java
- hibernate延迟加载
- Python if语句
- 掌柜大作战(8):京东消息中间件JMQ的配置和使用
- 在Web开发中,如何实现会话的跟踪?
- 《 A Scalable 3-Phase Polar Decoder》可扩展的三相极性解码器
- Google大数据三篇著名论文中文版
- svn版本控制器的搭建
- 深入浅出JMS(一)--JMS基本概念