设计模式-创建型模式

1、单例模式

对于某个类只存在一个实例,并且该类只提供一个取得实例的方法(静态方法)。

实现单例模式的八种方法

  • 饿汉式(静态常量)

   初始化时会加载对象,没有使用对象,会造成内存的浪费,但避免了多线程的同步问题。

class Singleton{

    //构造器私有化
    private Singleton(){}

    //类的内部创建对象 fianl static
    private static final Singleton singleton = new Singleton();

    //对外提供公共的静态方法,返回该类的唯一实例
    public static Singleton getInstance(){

        return singleton;
    }
}
  • 饿汉式(静态代码块)

   初始化时会加载对象,没有使用对象,会造成内存的浪费,但避免了多线程的同步问题。

class Singleton{

    //构造器私有化
    private Singleton(){}

    //类的内部创建对象
    private static final Singleton singleton;

    static {
        singleton = new Singleton();
    }

    //对外提供公共的静态的方法
    public static Singleton getInstance(){

        return singleton;
    }
}
  • 懒汉式(线程不安全)

有懒加载的效果,不会造成内存的浪费,但线程不安全


class Singleton{

    //构造器私有化
    private Singleton(){}

    //类的内部提供对象
    private static Singleton singleton;

    //对外提供公共的静态方法的时候,来判断
    public static Singleton getInstance(){

        if (singleton == null){

            singleton = new Singleton();
        }

        return singleton;
    }

}
  • 懒汉式(线程安全,同步方法)

利用 synchronized 关键字来实现线程安全,但是效率较低。


class Singleton{

    //构造器私有化
    private Singleton(){}

    //类的内部提供对象
    private static Singleton singleton;

    //对外提供公共的静态方法的时候,来判断
    public static synchronized Singleton getInstance(){

        if (singleton == null){

            singleton = new Singleton();
        }

        return singleton;
    }

}
  • 懒汉式(线程不安全,同步代码块)

该方法无任何意义,线程不安全(不推荐)

class Singleton{

    //构造器私有化
    private Singleton(){}

    //类的内部提供对象
    private static Singleton singleton;

    //对外提供公共的静态方法的时候,来判断
    public static Singleton getInstance(){

        if (singleton == null){

            synchronized (Singleton.class){

                singleton = new Singleton();
            }

        }

        return singleton;
    }

}
  • 双重检查(推荐使用

该方法既起到了懒加载的效果,又解决了线程安全问题且效率较高。


class Singleton{

    private Singleton(){}


    //禁止指令重排
    private static volatile Singleton singleton;

    //加入双重检查机制
    public static Singleton getInstance(){
        if (singleton == null){

            synchronized (Singleton.class){
                if (singleton == null){
                    singleton = new Singleton();
                }
            }
        }

        return singleton;
    }
}
  • 静态内部类(推荐)

  利用静态内部类的方式实现模式,在类加载时静态内部类是不会装载的,只有用到了getInatance方法用到了静态变量的时候类才会被装载,利用了jvm的特性来实现了线程的安全。

class Singleton{

    private Singleton(){}

    private static class SingletonInstance{

        public static final Singleton INSTANCE = new Singleton();
    }

    public static Singleton getInstance(){

        return SingletonInstance.INSTANCE;
    }
}
  • 枚举方法(推荐)

线程安全

enum Singleton{

    INSTANCE; //属性
}

单例模式的使用场景

对于一些需要频繁创建和销毁的对象

重量级对象

工具类

经常使用到的对象

数据源,session。。。。

2、工厂模式

定义一个可以创建对象的类,由这个类来封装实例化对象的行为,在简单工厂模式中可以根据参数的不同返回不同的实例。

避免了业务逻辑和创造对象代码的大量耦合。

工厂方法模式:定义一个创建对象的抽象实例化方法,由子类来决定实例化哪些类。将对象实例化延迟到子类。

工厂方法模式是简单工厂模式的衍生,实现了可扩展,层次结构复杂,可以应用到更复杂的场景。

3、抽象工厂模式

定义一个接口,用于创建相关或有依赖关系的对象簇,而无需指明具体的类。

对象簇:一系列的对象。

4、原型模式

用原型实例指定创建对象的种类,并通过拷贝这些原型创建新的对象,既实现一个原型接口,该接口用于创建当前对象的克隆,当直接创建对象代价较大时使用这种模式。

利用object对象中的clone方法实现。

  • 浅拷贝

对于数据类型时基本数据类型,浅拷贝就是值传递。

对于数据类型是应用型数据类型,浅拷贝就是引用传递(只是克隆之前的对象,不会创建新对象)。

  • 深拷贝

复制对象的所有基本类型的成员变量值

为所有引用数据类型变量申请存储空间,并复制每个引用数据类型成员变量所引用的对象,直到该对象可达的所有对象。

使用深拷贝会复制整个对象,包括引用型数据类型。

实现深拷贝的俩种方法 1、重写clone方法。2、对象序列化。

重写clone

public class DeepProtoType implements Cloneable{

    public String name; //String类型

    public DeepCloneableTarget deepCloneableTarget; //引用类型  ???

    public DeepProtoType() {
        super();
    }

    //完成深拷贝
    //实现方式一:重写clone方法


    @Override
    protected Object clone() throws CloneNotSupportedException {

        //要拷贝的对象
        Object deep = null;

        //分布进行
        //完成对于基本数据类型或者String类型的拷贝
        deep = super.clone();

        //对引用类型进行处理
        DeepProtoType deepProtoType = (DeepProtoType) deep;

        deepProtoType.deepCloneableTarget = (DeepCloneableTarget) deepCloneableTarget.clone();


        return deepProtoType;
    }
}

该方法繁琐,需要得一个一个的对引用型数据类型进行处理。

对象序列化

一劳永逸,无需反复操作。

//完成深拷贝
    //实现方式二:通过对象序列化的方式

    public Object deepClone(){

        //类需要实现序列化接口
        //创建流对象
        ByteArrayOutputStream bos  = null;
        ObjectOutputStream oos  = null;
        ByteArrayInputStream bis = null;
        ObjectInputStream ois = null;

        //序列化操作
        try {
            bos = new ByteArrayOutputStream();

            oos = new ObjectOutputStream(bos);

            oos.writeObject(this); //序列化

            //反序列化操作
            bis = new ByteArrayInputStream(bos.toByteArray());

            ois = new ObjectInputStream(bis);

            DeepProtoType deepProtoType = (DeepProtoType) ois.readObject();

            return deepProtoType; //输出

        } catch (Exception e) {
            e.printStackTrace();
        } finally {

            //关闭流对象
            try {
                bos.close();
                oos.close();
                bis.close();
                ois.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

        return null;

    }

5、建造者模式

创建细节不要暴露,可以在内部创建。

创建者模式又叫生成器模式,是一种对象创建模式。

他可以将复杂对象的建造过程抽象出来,使这个抽象过程的不同实现方法可以构造出不同表现得对象。

建造者模式是一步一步创建一个复杂的对象,他允许用户只通过指定复杂对象的类型和内容就可以构建他们,用户不需要直到内部的构建细节

 

建造者模式的四个角色:

产品角色(product):一个具体的产品对象。

抽象建造者(builder):创建一个各个对象产品部件指定的一个接口或者是抽象类。

具体建造者(concreatebuilder):具体建造者,实现builder接口,构建和装配各个部件,来实现具体的细节。

指挥者(director):构建一个用来使用builder接口的对象,用来创建复杂的对象,主要有俩个作用。1、隔离了客户与对象的生产过程。2、负责控制产品的生产过程。

建造者模式适用于以下的几种场景:
1、相同的方法,不同的执行顺序,产生不用的结果时
2、多个部件或者零件,都可以装配到一个对象中,但是产生的结果又不相同
3、产品非常复杂,或者产品类中的调用顺序不用产生不同的作用
4、当时初始化一个对象特别复杂,参数多,而且很多参数都具有默认值时

若产品差异较大就不适合了。

抽象工厂模式,不需要关心创建的流程是怎样的,只需要关心用怎样的对象创建怎样的产品。

建造者模式,按照指定的蓝图构建产品,需要关注装配的顺序及过程。

stringbuilder就是使用了创建者模式

设计模式是一种思想。

不要为了使用而使用。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值