如何优雅的创建对象(一)

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

在创建对象的时候大部分程序员都是直接用new的形式。下面来讲解另一个创建对象的方式,用静态工厂方法代替构造器。
比如我们想得到一个Integer对象,可以直接new得到,也可以用Integer.valueOf()这个静态方法直接得到。

        int a  = 5;
        Integer b = new Integer(a);
        Integer c = Integer.valueOf(a);

用静态工厂方法来提供对象,有优势也有劣势,可以根据自己的情况选择。

优势1

静态工厂方法有名字
在创建对象的时候,往往需要获取根据参数不同的来获取不同的实例对象,一个对象的构造器往往有多个,相信每一位都有被多个构造器弄蒙圈的情况,每个构造器的含义需要自己去代码里面看是什么意思,但是静态工厂方法可以自定义名字,来通过名字让我们去调用获取方法的时候能知道是什么含义
从下面的代码中我们可以清楚的从User类的静态方法名中知道我们获取的是一个单例的User实例。

        User user = User.newSingleInstance();

优势二

不必在每次调用它们的时候都创建一个新对象
如果我们用构造器获取对象,每次都是获取的一个新对象,但是我们通过静态工厂可以每次获取的都是同一个实例,对于有些不可变的实例来说大大加强了性能。
比如下面的Integer.valueOf方法,在类被加载的时候就已经缓存了-128~127的Integer实例,当判断需要创建的实例范围是在这个中间的时候,就直接返回缓存的实例就好了,这样避免创建大量重复无用的对象。

    public static Integer valueOf(int i) {
        if (i >= IntegerCache.low && i <= IntegerCache.high)
            return IntegerCache.cache[i + (-IntegerCache.low)];
        return new Integer(i);
    }

优势三

它们可以返回原返回类型的任何子类型的对象
这种设计方法可以隐藏具体的实现,只暴漏公共的接口,根据参数的不同再返回具体的实例对象。这也正式用户所希望的。对于用户来说只需要记住这一个接口就好了,他不用管具体的到底是哪个实现类去实现他。比如我们有个Book这个类,这个类下面有好多的类都继承了Book类,对于接口调用方来说,我只需要调用Book这一个接口就行了,通过传入的参数,再实例化具体的实现类来完成事情,例如,我要看童话书,调用Book接口,通过判断书的种类是童话书,再去实现具体的童话书Book类。

优势四

它们所返回的对象的类可以随着每次调用而发生变化,这取决于静态工厂方法的参数值
优势四其实是优势的进阶版,正因为有了优势三可以返回任何原始类型的子类型对象,才有了优势四可以随着调用不同的参数来返回不同的实例化对象。

优势五

方法返回的对象所属的类,在编写包含该静态工厂方法的类时可以不存在
比如JDBC连接数据库,我们在获取连接对象的时候具体的哪个数据库的连接对象的类可以没加载,比如连接对象里面有好多数据库的连接对象类,有mysql,oracle,derby等等,这三个数据库的连接实体类一开始都是不存在的,只有真正的接收具体的连接参数的时候才会有了该具体数据库的实体连接类

劣势一

静态工厂方法的主要缺点在子,类如果不含公有的或者受保护的构造器,就不能被子
类化

例如,要想将Collections中的任何便利的实现类子类化, 这是不可能的。但是这样也许会因祸得福,因为它鼓励程序员使用复合(composition),而不是继承,这正是不可变类型所需要的 。

劣势二

程序员很难发现它们
当我们对一个类不了解,但是还需要用的时候,往往想到的第一个实例化方法就是用构造器来实例化该类,但是对于一个只提供了静态工厂方法,而没有提供构造器的类来说,往往是很难发现如何实例化该类,需要查阅大量的文档和看API说明才可能知道如何去实例化该类,因此遵守标准的命名规范就显的格外重要了。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值