考虑用静态工厂方法代替构造器的场景

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了考虑用静态工厂方法代替构造器的场景相关的知识,希望对你有一定的参考价值。

总结点,使用场景:
 
a.当你尝试使用多个构造器,然后,每个构造器的区别是签名(参数类型或者参数顺序不同或者参数数量不同),那么,这个时候,可以考虑使用静态工厂方法来替代构造器。“如果构造器的参数本身没有确切地描述正被返回的对象,那么具有适当名称的静态工厂会更容易使用,产生的客户端代码也更易于阅读”
Example:
BigInteger.probablePrime()返回一个素数的整数
相比构造器Biginteger(int, int, Random)要直观
 
Car.smallCar()返回小车
 
b.当需要隐藏对象的实现类时,客户端不需要知道返回的对象,该对象对应的实现类是什么。那么就可以定义返回的对象类型,然后,静态工厂方法选择任何的实现类(对应的实例可以向下转换为返回的对象类型)-----暴露最少的信息给客户端
 
 
其它概念:
1.基于接口的框架(interface-based framework)----第18条
2.服务提供者框架(Service Provider framework)
 
服务提供者框架是指这样一个系统:多个服务提供者(Provider)实现一个服务(Service),系统为服务提供者的客户端提供多个实现,并把它们从多个实现中解耦出来。
服务提供者框架中有三个重要的组件:服务接口(Service Interface),这是提供者(Provider)实现的;提供者注册API(Provider Registration API),这是系统用来注册实现,让客户端访问它们的;服务访问API(Service Access API),是客户端用来获取服务的实例的。服务访问API一般允许但是不要求客户端指定某种选择提供者的条件。如果没有这样的规定,API就会返回默认实现的一个实例。服务访问API是"灵活的静态工厂",它构成了服务提供者框架的基础。
 
 https://gist.github.com/SnailTyan/377c38ab1f5d81df67c3b2c4432201ae:
// Service provider framework sketch 
 
 // Service interface 
 public interface Service { 
  ... // Service-specific methods go here 
 } 
 
 // Service provider interface 
 public interface Provider { 
  Service newService(); 
 } 
 
 // Noninstantiable class for service registration and access 
 public class Services { 
  private Services() { }  // Prevents instantiation (Item 4) 
 
  // Maps service names to services 
  private static final Map<String, Provider> providers =
   new ConcurrentHashMap<String, Provider>();
 
  public static final String DEFAULT_PROVIDER_NAME = "<def>";
 
  // Provider registration API 
  public static void registerDefaultProvider(Provider p) {
   registerProvider(DEFAULT_PROVIDER_NAMEp);
  } 
 
  public static void registerProvider(String name, Provider p){
   providers.put(namep);
  } 
 
  // Service access API; used by Client; This is static factory method
  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(
     "No provider registered with name: " + name);
  return p.newService();
  } 
 } 
 
通过服务者框架,客户端Client与服务完全解耦,Client不关注服务怎么实现,它只关注想要什么服务,具体这个服务怎么实现,它不关注。
每一个服务,只需要定义好接口,至于怎么实现,也不关注。每一个Provider,要实现一个服务,实现一个服务,就成为一个Provider。
然后,系统只关心,注册Provider,读取输入,返回Service给Client

以上是关于考虑用静态工厂方法代替构造器的场景的主要内容,如果未能解决你的问题,请参考以下文章

读书笔记 - Effective Java01. 考虑用静态工厂方法代替构造器

第1条:考虑用静态工厂方法代替构造器

第一条:考虑用静态工厂方法代替构造器

用静态工厂方法代替构造器遇到多个构造器参数时要考虑用构建器

第1条:考虑用静态工厂方法代替构造器

EffectiveJava读书笔记——考虑用静态工厂方法代替构造器