一、对象的创建与销毁

一、静态工厂创建代替构造方法

  • 创建类对象时候,可以采用静态工厂代替构造方法;

1 优势

1.1 静态工厂方法可指定不同名字:见名知意

  • 构造器构建对象时候,参数如果多,则构建时候不方便;
  • 静态工厂可以根据名字,来区分得到的对象的具体的属性;
@Setter
@Getter
@ToString
@NoArgsConstructor
public class Student {

    private String name;

    private String address;

    public Student(String name){
        this.name = name;
    }

    public Student(String name, String address){
        this.name = name;
        this.address = address;
    }

    /**
     * 采用静态工厂,而不是构造器的方式,能够突出创建的对象的属性
     * @param name
     * @return
     */
    public static Student getStudentWithName(String name){
        Student student = new Student();
        student.setName(name);
        return student;
    }

    public static Student getStudentWithNameAndAddress(String name, String address){
        Student student = new Student();
        student.setName(name);
        student.setAddress(address);
        return student;
    }
}

1.2 静态工厂方法能够创建单例

  • 对于某些开销比较大的对象,同时只需要一个对象的类,不需要反复创建;
  • 静态工厂方法可以只创建一个,但是构造方法构造会创建多个;
public class SecondDemo {

    // 工厂静态方法:只会调用一次对象
    @Test
    public void firstDemo(){
        for (int i = 0; i < 10; i++){
            People instance = People.getInstance();
            System.out.println(instance);
        }
    }

    // 构造器创建:会创建多个对象
    @Test
    public void secondDemo(){
        for (int i = 0; i<10; i++){
            People instance = new People();
            System.out.println(instance);
        }
    }
}

class People{

    // 静态初始化变量:只会加载一次
    private static People people = new People();

    public People(){}

    public static People getInstance(){
        return people;
    }
}

1.3 根据静态方法传入的不同参数,可以返回对应该方法的子类;

public class Test02 {
    public static void main(String[] args) {
        Animal ani1 = Animal.getAnimal(12);
        Animal ani2 = Animal.getAnimal(5);
        System.out.println(ani1.getClass());
        System.out.println(ani2.getClass());
    }
}

@NoArgsConstructor
@Setter
class Animal {
    private int weightKg;

    public static Animal getAnimal(int weightKg) {
        if (weightKg < 10) {
            Cat cat = new Cat();
            cat.setWeightKg(weightKg);
            return cat;
        } else {
            Sheep sheep = new Sheep();
            sheep.setWeightKg(weightKg);
            return sheep;
        }
    }
}

class Cat extends Animal {

}

class Sheep extends Animal {

}

2. 劣势

2.1 子类继承遭破坏
  • 若类中包含静态工厂方法,但构造器不是public或protected修饰,则不能被子类继承;破坏了类的继承性;
  • 鼓励开发中尽可能使用复用,而不是继承;
2.2 类的文档难以阅读
  • 类的API文档中,构造器比较容易发现,静态工厂方法难以发现,不利于他人知悉对象创建方式;
  • 采用约定成俗的方法命名,如下为常见的命名;
# 1. 类型转换: 返回的实例与传入的参数具有相同的值;
Object valueOf(Object obj);       Object of(Object obj);

    public static Boolean valueOf(boolean b) {
        return (b ? TRUE : FALSE);
    }

# 2. 获取单一实例: 一般是根据传入的参数来决定实例;   Singleton中不含参数
Object getInstance(params);

# 3. 获取实例:  一般获取的是不同的实例
Object newInstance(parmas);

3. 总结

  • 通常静态工厂方法更加实用,因此切忌一上来就使用构造方法;

二、多个构造方法考虑使用构建器

  • 若一个类中包含的成员变量太多,一般使用多个构造方法;
  • 每个构造方法都会存在: 参数多,构建对象时候参数容易混淆;

1. 优化一: JavaBean模式

  • 采用无参构造创建对象,调用setter方法为对象赋值;
  • javabean的模式存在着:不一致性的问题

2. 优化二: 构建器模式

public class ThirdDemo {

    @Test
    public void method(){
        // 创建的内部类中的对象:外部类.内部类
        Phone phone = new Phone.Builder("华为","红色")
                               .price(2100D)
                               .weight(1D)
                               .size(5D)
                               .build();

    }

}

class Phone{
    /** 1. 必选参数和非必选参数
     */
    private String brand;
    private String color;

    private Double price;
    private Double weight;
    private Double size;
    
    /**
     *  2.  静态内部类 Builder
     */

    public static class Builder{
        // 2.1 和外部类对应的参数
        private String brand;
        private String color;
        private Double price;
        private Double weight;
        private Double size;

        // 2.2 必选参数通过构造器,非必选参数使用类似setter的方法
        public Builder(String brand,String color){
            this.brand = brand;
            this.color = color;
        }

        public Builder price(Double price){
            this.price = price;
            return this;
        }

        public Builder weight(Double weight){
            this.weight = weight;
            return this;
        }

        public Builder size(Double size){
            this.size = size;
            return this;
        }

        // 2.3 提供公有方法
        public Phone build(){
            // 将builder对象传入到Phone对象中
            return new Phone(this);
        }
    }

    /**
     * 3. 将外部类和内部类的参数对应起来
     */
    private Phone(Builder builder){
        this.brand = builder.brand;
        this.color = builder.color;
        this.size = builder.size;
        this.weight = builder.weight;
        this.price = builder.size;
    }
}

三、私有构造器或者枚举类强化单例模式

  • 即单例模式;

四、私有构造器强化不可实例化的对象

  • 即工具类;

五、避免创建不必要的重复对象

  • 即单例模式;

六、消除过期对象的引用

七、避免使用终结方法

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值