zoukankan      html  css  js  c++  java
  • 创建和销毁对象——用静态工厂方法代替构造器

    参考资料:《Effective Java》,https://www.jianshu.com/p/ceb5ec8f1174

    基础回顾

    1.什么是构造器?

    构造器与类同名,在新建一个类的对象时,构造器会运行,以便将实例初始化为所希望的状态。

    每个类都会有一个默认的无参的构造器。也可以自己手动写一个构造器。

    如,在People类中写一个构造器:

    public People(String Name,int Age)
    {
        this.Name=Name;
        this.Age=Age;    
    }

    然后新建一个关于这个类的实例

    People a=new Prople("张三",18);

    像上面这样,可以在new后面加入对应的参数。如果我们不加参数,就会调用默认的无参构造器。

    2.工厂方法

    这里的静态工厂方法并不是直接对应设计模式当中的工厂方法

    静态工厂方法常用于类似LoaclDate或NumberFormat这种类当中。比如LocalDate.now等。

    为什么会用静态工厂方法呢?比如NumberFormat.getCurrencyInstance()和NumberFormat.getPercentInstance()这两个工厂方法,一个得到的是货币类型的,一个是百分比类型的。

    但是他们的接收参数都是一样的,构造器又必须得和类同名,如果非得用构造器去实现这个功能,还得添加其他参数,同时没有明确的名字去区分,增加了开发者的使用难度。

    下面将会详细说出静态工厂方法的其他优势。

    静态工厂方法的优势

    先自己写个静态工厂方法

    public class EJ01_01 {
        private int Num = 0;
    
        //静态工厂方法
        public static EJ01_01 convert(double Num) {
            EJ01_01 ej01_01 = new EJ01_01();
            ej01_01.Num = (int) Num;
            return ej01_01;
        }
        //测试可以返回子类
        public static EJ01_01_Son convert() {
            return new EJ01_01_Son();
        }
    
        public int Show() {
            return this.Num;
        }
    
        public int Add_10() {
            return this.Num + 10;
        }
    }
    
    class Test {
        public static void main(String args[]) {
            EJ01_01 test = EJ01_01.convert(1.2);
            System.out.println(test.Add_10());//输出11
            System.out.println(test.Show());//输出1
        }
    }
    //子类
    class EJ01_01_Son extends EJ01_01 {
    }

    1.静态工厂方法有名称。

    这个不用多说,就像上面的NumberFormat.getCurrencyInstance()和NumberFormat.getPercentInstance()一样。开发者一眼就可以看出他们的区别。

    2.不必在每次调用时都创建一个新的对象。

    如上面的代码。在测试类中:

    EJ01_01 test = EJ01_01.convert(1.2);

    并没有新建任何对象,直接调用。

    3.它可以返回原返回类型的任何子类

    构造函数只能返回自己原本的类型,但是在静态工厂方法中是可以返回子类的。如:

     //测试可以返回子类
        public static EJ01_01_Son convert() {
            return new EJ01_01_Son();
        }

    我测试了也可以返回其他常见的数据类型,比如convert方法的返回类型可以直接写成int,但是不见资料当中有任何提及,也不知道这种写法是否规范。

    4.可以减少对外暴露的属性

    下面代码的功能,调用Get_Type时,只能输入规定的参数,然后输出对应的数据。

    这种情况非常常见,比如一些方法只让输入MAX、MIN这种参数,输入其他参数直接报错。

    但是我们如果只用构造器来实现,是限制不了用户输入的是什么。下面的代码相当于把静态工厂方法当成构造函数的参数,用户只能调用对应的静态工厂方法,然后工厂方法进行赋值。

    class Get_Type {
        public static final int TYPE_Small = 1;
        public static final int TYPE_Moderate = 2;
        public static final int TYPE_Big = 3;
    
        private Get_Type(int type) {
            switch (type){
                case 1:
                    System.out.println("这是小号");
                    break;
                case 2:
                    System.out.println("这是中号");
                    break;
                case 3:
                    System.out.println("这是大号");
                    break;
            }
        }
    
        public static Get_Type Small() {
            return new Get_Type(TYPE_Small);
        }
        public static Get_Type Moderate() {
            return new Get_Type(TYPE_Moderate);
        }
        public static Get_Type Big() {
            return new Get_Type(TYPE_Big);
        }
    }
    
    //调用
    class Test2{
        public static void main(String args[]){
            Get_Type get_small=Get_Type.Big();//输出这是大号
        }
    }

     静态工厂方法的优势不止这几点,其他的一些优势我可能还没发现,剩下知道的几个以目前的能力来看,还无法完全理解。

  • 相关阅读:
    N75终于可以发彩信了
    用OpenSSL编写SSL,TLS程序(转)
    分享 jdk ant 绿色安装及自动化配置 for windows
    Symbian: How to write HBufC* to file(转)
    [转载]用非对称密码算法制作共享软件的注册码
    [笔记]远程终端API,Terminal Services Administration
    [转载]共享软件的注册加密法
    [希腊神话] 3Apollo(阿波罗,太阳神) [English Edition][附译文]
    [转载]软件加密技术和注册机制
    [希腊神话] 5Nereus and Proteus(纳鲁斯和普鲁吐斯,海神) [English Edition][附译文]
  • 原文地址:https://www.cnblogs.com/lbhym/p/11787505.html
Copyright © 2011-2022 走看看