zoukankan      html  css  js  c++  java
  • [Effective Java]创建和销毁对象

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

    使用静态工厂方法的优势:

    • 静态工厂方法具有名称,具有适当名称的方法更易阅读。

    具有多个构造器的类用户往往不知道该用哪个,可考虑提供多个合适命名的静态工厂方法。

    • 相比于构造器,不必再每次调用时都创建一个新对象

    不可变类可以预先创建好实例,或者将构件好的实例缓存起来,从而避免重复创建对象。此方法类似于Flyweight模式。如果程序经常请求创建相同的对象,并且创建对象的代价很高,此项技术可以极大地提升性能。

    •  可以返回原返回类型的任意子类型

    在选择返回对象的类时就有了更大的灵活性。比如:API可以提供对象,但是该对象实际的类可以被隐藏起来,用户无需知道其具体类型。静态工厂方法返回的对象所属的类,在编写包含该静态工厂方法的类时可以不必存在。这种灵活的静态工厂方法构成了服务提供者框架的基础。

    简单例子:

    1 public interface Service {
    2     // service-specific methods go here
    3 }
    public interface Provider {
        public Service newService();
    }
     1 import java.util.Map;
     2 import java.util.concurrent.ConcurrentHashMap;
     3 
     4 /**
     5  * Noninstantiable class for service registration and access 
     6  */
     7 public class Services {
     8     private Services(){}            //prevent instantiation
     9     
    10     private static final Map<String, Provider> providers = new ConcurrentHashMap<>();
    11     private static final String DEFAULT_PROVIDER_NAME = "<def>";
    12     
    13     public static void registerDefaultProvider(Provider p) {
    14         registerProvider(DEFAULT_PROVIDER_NAME, p);
    15     }
    16     
    17     public static void registerProvider(String name, Provider p) {
    18         providers.put(name, p);
    19     }
    20     
    21     // Service access API
    22     public static Service newInstance() {
    23         return newInstance(DEFAULT_PROVIDER_NAME);
    24     }
    25     
    26     public static Service newInstance(String name) {
    27         Provider p = providers.get(name);
    28         
    29         if (null == p) {
    30             throw new IllegalArgumentException("No provider registered with name: " + name);
    31         }
    32         
    33         return p.newService();
    34     }
    35     
    36 }

     在创建参数化类型实例时,使代码变得简洁

    缺点:

    主要缺点:类如果不含有公有的或者受保护的构造器,就不能被子类化。

    第二个缺点在于,与其他静态方法实际上没有任何区别

    没有像构造器那样在API文档中明确标识出来,因此,对于一个提供了静态方法而不是构造器的类来说,要想查明如何实例化一个类,是非常困难的。你可以在类或者接口注释中关注静态工厂,并遵守标准命名习惯,来弥补这一劣势。

    静态工厂方法的惯用名称:

    • valueOf 

    不太严格的讲,该方法返回的实例与参数具有相同的值,这样的静态工厂方法实际上是类型转换方法。

    • of

    valueOf的一种更简洁的替代,在EnumSet中使用并流行起来

    • getInstance

    返回的实例是通过方法的参数来描述的,但是不能够说与参数具有相同的值。

    • newInstance

    像getInstance一样,但是newInstance能够确保返回的每个实例都与所有其他实例不同

    • getType

    想getInstance一样,但是在工厂方法处于不同的类中的时候使用。Type表示工厂方法返回的对象类型

    • newType

    像newInstance一样,但是在工厂方法处于不同的类中时候使用。

    简而言之,静态工厂方法和构造器都各有用处,需要理解各自的长处。静态工厂通常更加合适,切忌第一反应就是提供公有的构造器,而不先考虑静态工厂方法。

  • 相关阅读:
    字符编码与解码详解
    【Java反射机制】用反射改进简单工厂模式设计
    数据结构
    根据 中序遍历 和 后序遍历构造树(Presentation)(C++)
    【动态规划】记忆搜索(C++)
    Linux环境下安装中山大学东校区iNode客户端
    webpack前端开发环境搭建
    CSS中line-height继承问题
    MySQL中MyISAM与InnoDB的主要区别对比
    JavaScript中易混淆的DOM属性及方法对比
  • 原文地址:https://www.cnblogs.com/luckyxiaoxuan/p/4390956.html
Copyright © 2011-2022 走看看