美文网首页
静态工厂

静态工厂

作者: 睦月MTK | 来源:发表于2020-01-25 16:08 被阅读0次

statement:本篇内容只是建立在我目前经验的基础之上,必然有不完善甚至是不正确的地方,请谨慎阅读,如果能指出错误与不足之处,更是不甚感激


一、什么是静态工厂
public class StaticFactoryTest {
    public static StaticFactoryTest newInstance() {
        return new StaticFactoryTest();
    }
}

静态工厂就是利用静态方法来返回一个类的实例


二、静态工厂优点
  • 相比于构造器,静态工厂可以有自定义的名字,你再也不用根据参数的数量去判断一个构造器究竟会返回怎样的实例
  • 相比于构造器,静态工厂不仅仅只是可以创造一个新的实例,对于可复用的实例,你可以在静态工厂中让其一直只返回一个原始实例
public class StaticFactoryTest {
    private static final StaticFactoryTest instance= new StaticFactoryTest();
    public static StaticFactoryTest getInstance() {
        return instance;
    }
}
  • 相比于构造器,静态工厂不仅仅只能返回本类的实例,它能返回本类及其子类的实例
public class StaticFactoryTest {
    public static StaticFactoryTest newStaticFactoryTestSon() {
        return new StaticFactoryTestSon();
    }
}
class StaticFactoryTestSon extends StaticFactoryTest{   
}
  • 使用类型推导,使得静态工厂具有简化创建泛型实例代码的能力
public class StaticFactoryTest<K> {
    public static void main(String[] args) {
        StaticFactoryTest<Object> test1 = new StaticFactoryTest<Object>();//1
        StaticFactoryTest<Object> test2 = StaticFactoryTest.newInstance();//2
    }
    
    public static <K> StaticFactoryTest<K> newInstance() {
        return new StaticFactoryTest<K>();
    }
}

代码1中使用构造器构造实例,两边均要加上<Object>,而代码2中则不用


三、静态工厂该如何正确使用
  • 一般来说,提供了静态工厂,则会同时把构造器设定为private,以防止使用者不使用设定的静态工厂去实例化类,但是这样也会带来一个问题,那就是这个类的子类没办法实例化。
  • 静态工厂归根结底是一个方法,与其他方法的区分是一个问题,所以静态工厂需要一些规范的命名:
    • newInstance --> 表示该工厂创建一个新的实例
    • getInstance --> 表示该工厂会根据条件(参数)返回一个符合的实例,不保证是新的
    • valueOf --> 表示该工厂将参数转换为对应于本类需求的一个实例,简单来说就是类型转换
  • 静态工厂最大的应用就在于实现单例模式
public class StaticFactoryTest {
    private static final StaticFactoryTest instance= new StaticFactoryTest();
    private StaticFactoryTest() {}
    public static StaticFactoryTest getInstance() {
        return instance;
    }
}
  • 静态工厂由于其对构造器进行了一种封装,所以能避免很多潜在的问题,比如this引用溢出的问题
public class StaticFactoryTest implements Runnable{
    private final Thread t;
    private StaticFactoryTest() {   
        t = new Thread(this);
        t.start();
    }
    @Override
    public void run() { 
    }
}

上述代码发生了this引用溢出的问题,在构造器中把this赋给一个Thread对象,并且在构造器中开启了线程,要知道构造器中的this对象还是一个未完成的对象,提前发布给一个线程,可能会使得那个线程从这个未完成的对象中得到一些未初始化的东西,从而引发潜在的问题。

public class StaticFactoryTest implements Runnable{
    private final Thread t;
    private StaticFactoryTest() {   
        t = new Thread(this);
    }
    public static StaticFactoryTest newInstance() {
        StaticFactoryTest instance = new StaticFactoryTest();
        instance.t.start();
        return instance;
    }
    @Override
    public void run() { 
    }
}

上述代码使用静态工厂完美的解决了这个问题,它在对象构造完成之后才启动一个新的线程并返回实例


参考文档:
[1] 《Effective Java》
[2] 《Java concurrency in practice》

相关文章

  • 设计模式

    设计模式 工厂模式生成bean 工厂模式分为静态工厂和实例工厂 静态工厂: 实例工厂

  • 工厂模式

    工厂模式 工厂模式分为 简单(静态)工厂 工厂方法 抽象工厂 下面分别介绍这几总工厂模式 简单工厂 (静态工厂) ...

  • 条目1:考虑使用静态工厂方法而不是构造函数

    静态工厂方法的优势: 1:静态工厂方法有名称 2:静态工厂方法不用每次都返回一个新的对象 3:静态工厂方法可以返回...

  • 静态工厂

    与简单工厂比较而言,优先使用 简单工厂模式!

  • 静态工厂

    statement:本篇内容只是建立在我目前经验的基础之上,必然有不完善甚至是不正确的地方,请谨慎阅读,如果能指出...

  • Java创建和销毁对象

    考虑用静态工厂方法代替构造器 静态工厂方法可以通过静态获取类的一个实例,而不需要通过构造器; 使用静态工厂方法的优...

  • Spring-4静态工厂方法和动态工程方法配置bean

    静态工厂方法 动态工厂方法

  • 【设计模式】——工厂模式_简单工厂模式

    要点 简单工厂模式也叫静态工厂模式(方法里面都为静态)。就是工厂类一般使用静态方法,通过接收的参数的不同来返回不同...

  • 静态工厂方法鸡肋吗?

    对比静态工厂 静态工厂方法很容易让人想到设计模式的静态工厂,也叫简单工厂,作者说两者不同,我认为这两者仅是从概念上...

  • Java静态工厂方法

    相比构造器,静态工厂方法提供实例的优势: 静态工厂方法有名字 使用静态工厂方法比直接使用等效的构造方法更易阅读理解...

网友评论

      本文标题:静态工厂

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