创建和销毁对象(一)

在面向对象编程中,任何代码都围绕着类和对象;一个类在使用之前必须要实例化一个对象,然后对这个对象进行操作;正如我在“对象导论”中所说的,类是组成问题空间的基本单位,若干个类将问题空间抽象出来,而对象便是类在解空间中的投影;因为类是抽象的,所以类没有任何具象的意义,只有在解空间中,给对象赋值之后,这个对象被数据具象化成一个有数据意义的实体,并且问题空间中的类的对象聚合之后才能形成具体的,能表达实体意义的解空间;在java中,生成对象的方法很多,相应的,生成了对象就必须适时的销毁对象,因为存储空间总是有限的,我们不可能放任对象无止境的去占用我们的存储空间,这对软件以及硬件都不是一个好消息;

每一个类都需要有构造方法来构造一个对象,当没有编写具体的构造方法时,java会自动给出一个无参的构造函数public Object();  这个构造方法会返回一个所有属性都为默认值的对象;所以有必要自己编写构造函数来更加高效的生成对象;

1.使用静态工厂来替代构造器

典型例子:


这是Boolean类中的一个静态方法,他通过入参来构造一个Boolean类;

使用静态方法来构造对象不会在每次调用他们的时候都创建一个新的对象,这使得不可变类可以使用预先构造好的实例或者将构建好的实例缓存起来,而不是反复的去构建一模一样的实例然后再销毁;静态构造方法从来不创建对象,如果程序经常请求创建一模一样的对象,使用静态构造方法将大大提升性能;

静态构造方法有确切的名字,这使得客户端开发者在调用时可以很明确的知道他将要调用的方法会生成一个什么样的结果;

同时,静态构造方法可以返回原返回类型的任何子类,这使程序有更大的灵活性;

静态工厂的第四个优势在于,所返回的对象的类可以对着每次调用而发生变化,这取决于静态方法的入参;我们有时候会根据参数的不同来构造不同的对象,这时候静态构造方法可以灵活的帮助我们自动构造我们需要的对象;

第五点,方法返回的对象所属的类,在编写包含该静态方法的类时可以不存在;这使得代码可扩展性很高,客户端程序猿可以很方便的去扩展服务端提供的框架;这就是 服务提供者框架 在这个框架中,服务提供者编写若干个api,而开发者可以通过不断去编写新的类去是现在这个api,从而不断的扩充这个api的功能;

静态方法的缺点主要在于,如果这个类没有共有或者受保护的构造起,则不能被实例化;还有一点,开发者很难去发现这些静态构造方法;

常见的构造方法命名:

from:类型转换;

Of:聚合;

valueOf:将入参转换为该类;

instance/getInstance:返回的实例是通过方法的参数来描述的,如果可以的话;

getType:蕾丝getInstance,type表示工厂方法所返回的对象类型;

create/newInstance:类似于getInstance,但是这两个关键词表示的方法一般都会确保每次调用都返回一个新的实例;

2.当构造器参数较多时,使用构建器

静态工厂和构造器都有个共同的缺点,无法很好的多个可选参数进行扩展;

首先,重叠构造器:


开发者在实例化对象时,可以对具体的需求选择需要的构造器;

在编写类时我们并不知道今后在构造实例时到底需要多少个属性,所以多写几个构造器总是好的,调用不同的构造器会生成不同的类;


当你想要构造实例的时候,就调用对应你想要的构造器就可以了;


但是这么写的话,当参数很多很多的时候,客户端的代码就会很麻烦,一大串而且难以阅读;其实java本身已经帮助我们解决了这个问题(javaBean方法),大不了就new一个无参的实例,然后一个一个调用set方法弄进去;但是这个方法并不是线程安全的,也就是说javaBean在构造过程中可能处于不一致的状态,这使得无法构造不可变类,除非开发者自己保证线程安全;

当然了,还有更好的方法 建造者模式(builder):

话不多说先上代码


建造者模式模拟了具名的可选参数,这使得客户端开发代码十分易于阅读;

而且,建造者模式也适用于类层次结构,类似于抽象工厂中的概念;

你可能感兴趣的:(创建和销毁对象(一))