zoukankan      html  css  js  c++  java
  • 设计模式中的创建型

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

    单例模式

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

    饿汉模式:

    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();
    }
    

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

  • 相关阅读:
    Java随笔
    Java随笔
    Java随笔
    CF1271D Portals(反悔贪心)
    CF938D Buy a Ticket(最短路)
    CF1117C Magic Ship(二分)
    HDU6820 Tree(树形dp)
    P2393 美味(主席树+贪心)
    HDU6831 Fragrant numbers(区间dp)
    HDU6832 A Very Easy Graph Problem(生成树)
  • 原文地址:https://www.cnblogs.com/Keep-Going-Space/p/14767301.html
Copyright © 2011-2022 走看看