Java之静态工厂方法

作者: 有财君 | 来源:发表于2019-04-26 22:59 被阅读37次

著名Java书籍《Effective Java》中第一条就提到了一个原则:考虑用静态方法而不是构造器。初看这条规则的时候我还感到很费解,构造器是Java提供的构造对象的方法,为什么不是首选呢?

假设有这样一个类:

package com.example.demo;

public class Dog {
    private String name;

    private String color;

    private int age;

    public Dog() {
    }

    public Dog(String name) {
        this.name = name;
    }

    public Dog(String name, String color, int age) {
        this.name = name;
        this.color = color;
        this.age = age;
    }
}

一条狗的属性很多,比如名字,颜色和年龄,我上面的类里有三个构造器,一个无参数的默认构造器,一个参数只有name的构造器和一个有所有三个参数的构造器。

那么这个时候问题来了,我想加一个只有毛色color参数的构造器,因为确实有些狗我只知道它的颜色,但是这已经是不可能了:

public Dog(String color) {
    this.color = color;
}

方法重载也是有限制的,这个构造器实际上和name构造器冲突了。

为了实现功能,我们还是改改代码的好:

package com.example.demo;

public class Dog {
    private String name;

    private String color;

    private int age;

    private Dog() {
    }

    public static Dog newDogWithAllParam(String name, String color, int age) {
        Dog dog = new Dog();
        dog.name = name;
        dog.age = age;
        dog.color = color;
        return dog;
    }

    public static Dog newDogWithName(String name) {
        Dog dog = new Dog();
        dog.name = name;
        return dog;
    }

    public static Dog newDogWithColor(String color) {
        Dog dog = new Dog();
        dog.color = color;
        return dog;
    }
// Getters & Setters
}

每次新建对象的时候,只需要调度需要的方法就可以了。这段代码也解释了书中提到的静态工厂方法的一个好处——有名字。通过名字我可以清楚的知道我是用什么属性去创建的对象。

我个人很喜欢使用Guava的Lists类库来创建List:

List<Long> list = Lists.newArrayList();

这种方式可以说简洁而优雅,其实,这也是静态工厂方法取代构造器的典型案例,它的源码可以来品味一下:

@GwtCompatible(serializable = true)
  public static <E> ArrayList<E> newArrayList() {
    return new ArrayList<>();
  }

其实和我之前的代码原理上是一样的。

《Effective Java》还提到了一条,就是静态工厂方法不必在每次被调用的时候都会产生新对象,照例要看源码,我们看一下书里提供的一段代码:

public static Boolean valueOf(boolean b) { 
    return b ? Boolean.TRUE : Boolean.FALSE;
}

在这样的语句:boolean bl = Boolean.valueOf(false); 的时候,实际上是不需要创建额外的对象的,原因在我之前写static的文章中有提及:

Java之再看static变量

虽然上面的例子基本上是一句废话,但是也能说明问题。

静态工厂方法还有一个好处,就是可以返回子类型,比如我们有一个Car类,其中有一个关键的参数叫做price,我希望price>30万的返回豪车子类,price<30万的返回买菜车子类,那么代码就要这样写了:

package com.example.demo;

public class Car {
    private int price;

    Car() {}

    public static Car newCarWithPrice(int price) {
        if (price > 30 * 10000) {
            return new LuxCar();
        } else {
            return new NormalCar();
        }
    }
}

这种代码就是构造器无法实现的了。

相关文章

  • 比较 Java 静态工厂方法与构造函数

    1 什么是静态工厂方法 Java 静态工厂方法是在方法前加上 public static,让这个方法变为公开、静态...

  • Java与模式

    《JAVA与模式》之简单工厂模式《JAVA与模式》之工厂方法模式《JAVA与模式》之抽象工厂模式

  • Effective Java刷书笔记---静态工厂方法

    Effective Java刷书笔记---静态工厂方法 类实例获取--“考虑”用静态工厂方法代替构造器对于一个类而...

  • Effective java 整理(第三版)

    整理一下自己effective java 创建 和销毁对象 静态工厂方法代替构造器 优点 静态工厂方法有名字 ,是...

  • Java之静态工厂方法

    著名Java书籍《Effective Java》中第一条就提到了一个原则:考虑用静态方法而不是构造器。初看这条规则...

  • 详解:Java 的静态工厂方法

    序:什么是静态工厂方法 Effective Java2.1 静态工厂方法与构造器不同的第一优势在于,它们有名字2....

  • 大话设计模式之_工厂模式

    大话设计模式之_工厂模式 工程方法(即简单工厂模式simpleFactory,或静态工厂方法 static fac...

  • java收藏夹

    java中的经典问题solution Java 的静态工厂方法 单例的四种实现方法 Java中的clone方法 J...

  • 设计模式系列-简单工厂模式

    JAVA设计模式系列: 单例模式 观察者模式 模板方法模式 简单工厂模式 定义 简单工厂模式又叫做静态工厂方法模式...

  • 2016.06笔记

    iOS设计模式之工厂模式(简单工厂,工厂方法,抽象工厂) 简单工厂:简单工厂模式的工厂类一般是使用静态方法,通过接...

网友评论

    本文标题:Java之静态工厂方法

    本文链接:https://www.haomeiwen.com/subject/esscnqtx.html