Effective Java --静态工厂方法代替构造器的优缺点

Effective Java --静态工厂方法代替构造器的优缺点

最近在看Effective Java,记录下之后编码时可以注意的一些习惯,提高编码质量

每提高一点都是积累

创建对象

一.使用类公有的构造器

大家习惯用的方式,但是破坏了封装性

二.通过静态方法返回一个实例对象

1. 静态方法的优点:

静态工厂方法与构造器不同的第一大优势在于,它们有名称

静态工厂方法的名字由自己命名,而构造方法必须与类名相同。
我们可以通过静态工厂方法名明确知道我们要获取到的是一个素数。

//使用构造器方法获取到一个素数
BigInteger prime = new BigInteger(int, int ,Random);
//使用静态工厂方法
BigInteger prime = BigInteger.probablePrime(int, Random);

不必在每次调用它们的时候都创建一个新对象

构造方法每次调用都会创建一个对象,而静态工厂方法则不会每次调用时都创建要给对象。

静态方法通常会使用预先构建好的实例或者将构建好的实例缓存起来,进行重复利用,从而避免创建不必要的重复对象,比如我们常见的单例模式。

public class Singleton { /* * 利用一个静态变量来记录Singleton类的唯一实例 */

    private static Singleton uniqueInstance; /* * 声明为private,使得只有Singleton类内才可以调用构造器 */

    private Singleton() {
    } /* * 通过该方法实例化对象,并返回这个实例 */
    public static Singleton getInstance() {
        if (uniqueInstance == null) {
            uniqueInstance = new Singleton();
        }

        return uniqueInstance;
    }
}

静态工厂方法可以返回原返回类型的任何子类型对象

这样使我们在选择返回对象的类时就有了更大的灵活性。

静态工厂方法可以返回原返回类型的任何子类型对象

这样使我们在选择返回对象的类时就有了更大的灵活性。

class Father {
    private Father() {
    }

    public static Father newInstance(String type) {
        if (type.equals("ChildA")) { // 根据类型判断返回那个子类对象
            return new ChildA();
        } else {
            return new ChildB();
        }
    }

    public void getName() { 
        System.out.println("My name is father");
    }

    private static class ChildA extends Father {
        public void getName() { 
            System.out.println("My name is child A");
        }
    }

    private static class ChildB extends Father {
        public void getName() {
            System.out.println("My name is child B");
        }
    }
}

public class Test {
    public static void main(String[] args) {
        Father c1 = Father.newInstance("ChildA");
        c1.getName();
        Father c2 = Father.newInstance("ChildB");
        c2.getName();
    }
}

静态工厂方法在创建参数化类型实例的时候,可以使代码变得更加简洁

//构造方法 
Map> map = new HashMap>(); 
//静态方法 public static  HashMap newInstance(){
    return new HashMap(); 
}
Map> map = HashMap.newInstance();

2.静态方法的缺点:

1.类如果不含有公有的类或者受保护的构造器,就不能被子类化

2.它们与其他的静态方法实际上没什么区别,因此我们约定了一些静态工厂方法的常用名称:

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

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

  • getInstance——返回的实例是通过方法的参数描述的,但是不能够说与参数具有同样地值。对于Singleton来说,该方法没有参数,并返回唯一的实例。

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

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

  • newType——像newInstance一样,但是在工厂方法处于不同的类中的时候使用。Type表示工厂方法所返回的对象类型。

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

你可能感兴趣的:(java)