用静态工厂方法代替构造器以及服务提供者框架

为什么要使用静态工厂方法代替构造器?

优点:

  1. 可以确切描述返回什么对象,避免构造不规范
  2. 可以不必在每次调用时都创建新的对象
  3. 它可以返回该类的子类对象,程序更加灵活
  4. 返回的对象可以根据指定参数生成,参数不同,对象就不同
  5. 返回对象所属的类,可以与该类无关

实例化对象时,不要第一反应就是提供公有构造器,而不先考虑静态工厂方法

实例

概念都是不好理解的,通过实例来理解概念
参考自知乎用户,Uncle-lv https://zhuanlan.zhihu.com/p/112986695

假如一所大学有三个学院,信息学院,财经学院,工程学院,我们不想把创建学院交给外部,因为外部不了解该大学的结构,
可能创造一个不存在的学院,但是,我们又要提供创建学院的接口,这时候该怎么做?

这时候静态工厂方法就起作用了,类提供一个公有的静态工厂方法

【优点1】:使用静态工厂模式确定要返回什么对象,避免构造不规范

public class College{
    private String name;
    //私有化构造方法
    private College(String name){
        this.name = name;
    }
    //提供3种创建方法
    public static College getInfomationCollege(){
        return new College("信息学院");
    }
    public static College getFinanceCollege(){
        return new College("财经学院");
    }
    public static College getEngineerCollege(){
        return new College("工程学院");
    }

    public String getName(){
        return name;
    }
}

【优点2】:可以不必在每次调用时都创建新的对象

//有时候我需要多次调用静态方法得到该对象,但是学院只要创建一个,我们先调用一下
College college1 = College.getEngineerCollege();
College college2 = College.getEngineerCollege();
System.out.println(college1 == college2);    //false
//很明显,生成了两个学院,这不符合我们的需求,所以第一段代码,还有改进的空间
private static College infomationCollege;
public static College getInfomationCollege() {
        //单例模式
        if(College.infomationCollege == null){
            return new College("信息学院");
        }
        return College.infomationCollege;
}
//再来测试一下
College college1 = College.getEngineerCollege();
College college2 = College.getEngineerCollege();
System.out.println(college1 == college2);    //true

有一个人的类,我们通过静态工厂方法生成其子类

【优点3】: 它可以返回该类的子类对象,程序更加灵活
这样我们返回的都是Person的子类对象,我们不必知道Adult类和Child类的存在,程序更加灵活

【优点4】:所放回的对象的类何以随着每次调用而发生变化,这取决于静态工厂方法的参数值
每次返回的类型因参数的都不同

public class Person {
   protected int age;
   public Person getPerson(int age){
       if(age < 18 && age >= 0){
           return new Adult(age);
       }
       if(age > 18){
           return new Child(age);
       }
       return null;
   }

    private static class Child extends Person{
        public Child(int age){
            this.age = age;
            System.out.println("我是一个"+ age +"岁的小孩");
        }
    }
    //成员内部类
    private static class Adult extends Person{
        public Adult(int age){
            this.age = age;
            System.out.println("我是一个"+ age +"岁的大人");
        }
    }
}

【优点5】:

总结

1、什么时候使用静态工厂方法?

  • 当一个类需要多个相同名字的构造器,可以通过静态工厂方法返回指定的类
  • 如果程序经常请求创建相同的对象
  • 适用基于接口的框架

2、缺点

  • 构造器私有化之后,就不能被继承了

服务提供者框架

https://www.jianshu.com/p/4d7a0cd36a82

posted @ 2020-04-10 17:05  小码过河233  阅读(208)  评论(0编辑  收藏  举报