静态工厂方法代替构造器
对于类而言,为了让客户端获取它自身的一个实例,最常用的办法是提供一个公有的构造器。还有一种方法:公有的静态工厂方法。它只是一个返回类实例的静态方法,如下代码所示:
public class Gender {
private String description;
private static Gender male = new Gender("男");
private static Gender female = new Gender("女");
private Gender(String description) {
this.description = description;
}
public static Gender getMale() {
return male;
}
public static Gender getFemale() {
return female;
}
public String getDescription() {
return description;
}
public String of() {
return description;
}
}
其区别于构造器的有点有几点:
- 首先,静态工厂方法可以自定义名称,这样做的好处是在阅读客户端代码的时候会更加容易。例如,构造器BigInteger(int, int, Random)返回的BigInteger可能为素数,如果用名为BigInteger.probablePrime的静态工厂方法来表示,显然更为清楚。由于静态工厂方法有名称,当一个类需要多个带有相同签名的构造器时,用静态工厂方法代替构造器,并且慎重的选择名称以便突出他们的区别。
其次,静态工厂方法不必在每次调用他们的时候都创建一个新的对象。这使得不可变类可以使用预先构建好的实例,或者将构建好的实例缓存起来进行重复利用。Boolean.valueOf()方法从来不创建实例,这种方法类似于Flyweight模式。
静态工厂方法能够为重复的调用返回相同的类,这样有助于类总能严格控制在某个时刻哪些实例应该存在。这种类被称作实例受控的类。返回原返回类型的任何子类型的对象。
- 代码简洁
静态工厂方法的一些惯用名称:
- valueOf
- of(valueOf的简写)
- getInstance
- newInstance
- getType
- newType
重叠构造器模式
多个参数时使用,重叠构造器模式:提供第一个只有必要参数的构造器,第二个构造器只有一个可选参数,第三个构造器有两个可选参数。。。以此类推,最后一个包含所有构造参数。
JavaBeans模式
多个参数时使用该模式,这个就不用多说了,就是我们最常用的getter和setter方法。
builder模式
多个参数也可以使用builder模式来构建,这样的客户端代码很容易编写,且易于阅读。builder模式模拟了具名的可选参数,就像Ada和Phyton 中的一样。
简而言之,如果类的构造器或者静态工厂中具有多个参数,设计这种类时,Builder模式就是种不错的选择,特别是当大多数参数都是可选的时候。
package com.test.createanddestory;
/**
* @Date 2016/12/15.
* @Description 多构造器和builder模式
*/
public class Person {
//必选参数
private Gender gender;
private String name;
//可选参数
private int age;
private float height;
private float weight;
private String country;
public static class Builder {
private Gender gender;
private String name;
private int age = 0;
private float height = (float) 160.00;
private float weight = (float) 50.00;
private String country = "china";
public Builder(Gender gender, String name) {
this.gender = gender;
this.name = name;
}
public Builder age(int age) {
this.age = age;
return this;
}
public Builder height(float height) {
this.height = height;
return this;
}
public Builder weight(float weight) {
this.weight = weight;
return this;
}
public Builder country(String country) {
this.country = country;
return this;
}
public Person build() {
return new Person(this);
}
}
private Person(Builder builder) {
gender = builder.gender;
name = builder.name;
age = builder.age;
height = builder.height;
weight = builder.weight;
country = builder.country;
}
public String toString() {
return "This person's name is " + name
+ " gender is " + gender.getDescription()
+ " age is " + age
+ " height is " + height
+ " weight is " + weight
+ " country is " + country;
}
public Gender getGender() {
return gender;
}
public void setGender(Gender gender) {
this.gender = gender;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public float getHeight() {
return height;
}
public void setHeight(float height) {
this.height = height;
}
public float getWeight() {
return weight;
}
public void setWeight(float weight) {
this.weight = weight;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getCountry() {
return country;
}
public void setCountry(String country) {
this.country = country;
}
}