《Effective Java》-考虑用静态工厂方法代替构造器

之前一直在开发平台中看到这样的代码,一直没反应过来这样写的好处:

private static SystemManager sm = new SystemManager();
private SystemManager(){}

public static SystemManager getInstance(){
    return sm;
}
private AppManager(){}

public static AppManager newInstance(){
    return new AppManager();
}

直到最近翻看《Effective Java》这本书,在第二章创建和销毁对象第1条讲的就是考虑用静态工厂方法代替构造器,书中罗列了以下优点:
1.静态工厂方法与构造器不同的第一大优势在于:它们有名称,可以取有意义的方法名
举个简单例子:

public class User {
    private String name;//姓名
    private Integer gender;//性别,0:女,1:男

    public User() {
    }

    public User(String name, Integer gender) {
        this.name = name;
        this.gender = gender;
    }

    public static User newManUser(String name){
        return new User(name, 1);
    }

    public static User newWomanUser(String name){
        return new User(name, 0);
    }

    //省略get set toString
}

当我采用构造器实例化对象时,对于调用者来说,它其实并不知道这个1代表什么意思,0代表什么意思,所以它并不知道创建的对象的性别是什么。

User user1 = new User("张三", 1);
User user2 = new User("莉莉", 0);

当我采用静态工厂方法实例化对象时,对于调用者来说,它已经可以通过静态工厂方法的名称知道创建的这个对象的性别了。

User user3 = User.newManUser("王五");
User user4 = User.newWomanUser("晓晓");

2.静态工厂方法与构造器不同的第二大优势在于:不必在每次调用它们的时候都创建一个新对象。
举个简单例子:

public class Teacher {
    private String name;

    private static Teacher teacher = new Teacher("王刚");

    private Teacher(String name){
        this.name = name;
    }

    public static Teacher getTeacher(){
        return teacher;
    }

    public static Teacher newTeacher(String name){
        return new Teacher(name);
    }

    //省略get set toString
}

将构造器使用private修饰后就只能通过静态工厂方法获取实例对象。
假设我默认Teacher对象的姓名都是王刚,那么可以通过getTeacher静态工厂方法获取对象时得到的Teacher对象,不需要每次都创建新对象。
当需要创建新的Teacher对象时可以通过newTeacher静态工厂方法获取新Teacher对象

Teacher teacher1 = Teacher.getTeacher();
Teacher teacher2 = Teacher.getTeacher();
Teacher teacher3 = Teacher.newTeacher("王五");
Teacher teacher4 = Teacher.newTeacher("赵六");
System.out.println(teacher1);//王刚
System.out.println(teacher2);//王刚
System.out.println(teacher3);//王五
System.out.println(teacher4);//赵六
System.out.println(teacher1 == teacher2);//true,引用地址是同一个
System.out.println(teacher1.equals(teacher2));//true

3.静态工厂方法与构造器不同的第三大优势在于:它们可以返回原返回类型的任何子类型的对象,当我们在选择返回类型的类时具有更大的灵活性。

关于这一点,个人暂还未领会,留待以后补充。

4.静态工厂方法与构造器不同的第四大优势在于:在创建参数化类型实例的时候,它们使代码更加简洁。
引用书上的例子:

Map<String,List<String>> map = new HashMap<String,List<String>>();//构造器方式  
public static  HashMap<K,V> newInstance(){ //静态工厂方式  
    return new HashMap<K,V>();  
}  

Map<String,List<String>> map  = HashMap.newInstance();

5.主要缺点:
1)类如果不含共有的或者受保护的构造器,就不能被子类化。
2)它们与其他的静态方法实际上没有任何区别。

算是读书笔记,前两点优势结合公司开发平台中的代码按自己理解写了两个简单例子

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值