设计模式中的创建型

在创建一个对象的时候,我们通常会用到以下几个方式:单例模式、工厂模式、建造者模式。我们具体看下怎么使用,以及应用场景。

单例模式

单例模式常见的主要有饿汉模式、懒汉模式、双重检测、静态内部类。

饿汉模式:

public class IdGenerator {
    private IdGenerator(){}
    private static IdGenerator idGenerator = new IdGenerator();
    public static IdGenerator getInstance(){
        return idGenerator;
    }
}

适用点:预加载,降低在程序过程中初始化慢可能带来的性能问题。适用于初始化加载时间长的对象,缺点不能延迟加载对象。

懒汉模式

public class IdGenerator {
    private IdGenerator(){}
    private static IdGenerator idGenerator ;
    public static synchronized IdGenerator getInstance(){
        if(idGenerator==null){
            idGenerator = new IdGenerator();
        }
        return idGenerator;
    }
}

适用点:延迟加载,但是由于在加锁,导致并发性不高。适用于使用不频繁,并发量不高的情况

双重检测

public class IdGenerator {
    private IdGenerator(){}
    private static volatile IdGenerator idGenerator ;
    public static  IdGenerator getInstance(){
        if(idGenerator==null){
            synchronized (IdGenerator.class){
                if(idGenerator==null){
                    idGenerator = new IdGenerator();
                }
            }

        }
        return idGenerator;
    }
}

适用点:既满足了并发量的场景,也满足了延迟加载。双重检测锁的优势在于并发情况下,多条线程同时获取null的情况。

内部静态类

public class IdGenerator {
    private IdGenerator(){}
    private static class IdGeneratorHolder{
        private static  IdGenerator idGenerator = new IdGenerator();
    }
    public static IdGenerator getInstance(){
        return IdGeneratorHolder.idGenerator;
    }
}

适用点:满足了延迟加载,也没有双重检测写法麻烦。保证了线程的安全性

单例模式主要适用的场景在于当一个类只需要一个实例对象的时候。默认为无参构造函数,当我们为有参构造函数时,实现一个单例,只能通过延迟加载的模式中传入参数

工厂模式

工厂模式主要分为三个:简单工厂模式、工厂模式、抽象工厂模式

简单工厂模式: 主要用途创建对象的过程比较简单,可以直接放置在一个工厂类中,进行判断

工厂模式: 主要用途创建对象的过程比较复杂,则每个对象都有自己的工厂类,然后整合到统一的工厂类中

抽象工厂:主要当创建的对象其实又分为两个或多个大的方向时,则对象在生成自己的工厂类的方法的时候。同时继承同一个方向的接口

普通模式

public void countAninal(String type){
    Animal animal=null;
    if(type.equalsIgnoreCase("dog")){
        animal = new Dog();
    }else if(type.equalsIgnoreCase("cat")){
        animal = new Cat();
    }else if(type.equalsIgnoreCase("chick")){
        animal = new Chick();
    }
    animal.name();
}

简单工厂模式(为了职责单一,将创建对象这块进行剥离,工厂类总是以Factory结尾)

public class Zoo {
    public void countAninal(String type){
        Animal animal =  AninalFacory.getAnimalByType(type);
        animal.name();
    }
}
class AninalFacory{
    public static Animal getAnimalByType(String type){
        Animal animal=null;
        if(type.equalsIgnoreCase("dog")){
            animal = new Dog();
        }else if(type.equalsIgnoreCase("cat")){
            animal = new Cat();
        }else if(type.equalsIgnoreCase("chick")){
            animal = new Chick();
        }
        return animal;
    }
}

工厂模式如果在每个类创建的时候比较负责,或者又会对应多种情况,则这个时候用工厂模式呢,为每个类别生成单独的工厂类。抽象工厂则为一个工厂类,可以产生多个类别的对象。

建造者模式

当我们创建一个类的时候,初始化的时候参数列表很冗长时,且创建后,希望参数不在变时。这个时候我们可以采用构造者模式

public class ResourcePool {
    private String name;
    private String maxTotal;
    private String maxIdel;
    private String minTotal;
    public ResourcePool(ResourcePoolBuilder builder){
        this.name = builder.getName();
        this.maxTotal = builder.getMaxTotal();
        this.maxIdel = builder.getMaxIdel();
        this.minTotal = builder.getMinTotal();
    }
}
class ResourcePoolBuilder{
    private String name;
    private String maxTotal;
    private String maxIdel;
    private String minTotal;
    public static ResourcePoolBuilder custom(){
        ResourcePoolBuilder resourcePoolBuilder = new ResourcePoolBuilder();
        return  resourcePoolBuilder;
    }
    public ResourcePoolBuilder setName(String name){
        this.name = name;
        return  this;
    }
    public ResourcePoolBuilder setMaxTotal(String maxTotal){
        this.maxTotal = maxTotal;
        return  this;
    }
    public ResourcePool build(){
        return  new ResourcePool(this);
    }
    public String getName() {
        return name;
    }
    public String getMaxTotal() {
        return maxTotal;
    }
    public String getMaxIdel() {
        return maxIdel;
    }
    public String getMinTotal() {
        return minTotal;
    }
}

原型模型

如果创建一个对象成本太大,而同一个类的不同对象差别不大的时候,这个时候我们用原型模式进行拷贝。拷贝又分为深拷贝和浅拷贝。浅拷贝是指只拷贝引用对象地址,不拷贝对象本身。深拷贝是指既拷贝地址又拷贝对象本身,成为一个独立的对象。

深拷贝的方式一般有:通过代码逻辑进行对象的复制。通过序列化和反序列化形成对象的拷贝。

public Object deepCopyObjec(Object object) throws IOException, ClassNotFoundException {
    ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
    ObjectOutputStream objectOutputStream =  new ObjectOutputStream(byteArrayOutputStream);
    objectOutputStream.writeObject(object);
    ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(byteArrayOutputStream.toByteArray());
    ObjectInputStream objectInputStream = new ObjectInputStream(byteArrayInputStream);
    return objectInputStream.readObject();
}

以上为设计模式中的创建型。

原文地址:https://www.cnblogs.com/Keep-Going-Space/p/14767301.html