前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >每天5分钟-创建型模式(二)

每天5分钟-创建型模式(二)

作者头像
用户8902830
发布2021-08-12 11:02:17
2360
发布2021-08-12 11:02:17
举报
文章被收录于专栏:CodeNone

这篇就是设计模式的最后一篇文章了,写的非常简洁,基本上是通过例子来解释模式。虽然并没有很深挖,但是如果能帮到你们理解到是什么这个地步我觉得就够了。

下一个系列的话,大概率是spring全家桶这方面的,也有可能是其它方面的。

单例模式

单例模式应该算是最常用的设计模式了叭,著名的双重校验也是单例模式的一种实现。所谓单例模式就是用来保证一个对象只能创建一个实例,除此之外,它还提供了对实例的全局访问方式。

单例模式UML类图

单例模式饿汉式

所谓饿汉式,人饿了看到啥都想吃。同样,不管需不需要这个实例,反正我都先给你创建好

普通实现

代码语言:javascript
复制
public class SingletonHungry {
    
    //在类加载的时候就已经创建了唯一的实例
    private static final SingletonHungry instance = new SingletonHungry();
    
    //保证外部不能调用构造函数
    private SingletonHungry() {
    }

    //外部调用这个方法,就返回实例
    public static SingletonHungry getInstance() {
        return instance;
    }
    
    //类中其它方法,尽量是static
    public static void func(){}
    
}

静态代码块

代码语言:javascript
复制
public class SingletonHungryStatic {
    //其实就是把new的部分移到了静态代码块中
    private static SingletonHungryStatic instance = null;
    static {
        instance = new SingletonHungryStatic();
    }

    private SingletonHungryStatic() {
    }

    public static SingletonHungryStatic getInstance() {
        return instance;
    }

    //类中其它方法,尽量是static
    public static void func(){}
}

单例模式懒汉式

所谓懒汉,就是要不是有人催促,就不肯去劳动。同理,只有你找我要这个实例,才创建出来

普通实现

代码语言:javascript
复制
public class SingletonLazy {
    //volatile之前已经讲过,防止指令的重排序,这个volatile是不能省略的
    private static volatile SingletonLazy instance = null;
    private SingletonLazy(){}

    public static SingletonLazy getInstance() throws Exception {

        if(instance == null) {
            synchronized (SingletonLazy.class) {
                if(instance == null) {
                    instance = new SingletonLazy();
                }
            }
        }
        return instance;
    }
}

静态内部类

代码语言:javascript
复制
public class SingletonLazyStatic {
    
    /**
     * 静态内部类注意事项
     *  1. 类加载的时,静态内部类不会随着加载
     *  2. 静态内部类只会初始化一次
     *  3. 线程安全的
     */
    
    private static class StaticClassInstance{
        private static final SingletonLazyStatic INSTACE = new SingletonLazyStatic();
    }
    private SingletonLazyStatic() {
    }
    
    public static SingletonLazyStatic getInstance() {
        return StaticClassInstance.INSTACE;
    }
}

其实还有一种更为优雅的实现方式,那就是使用枚举,不过之前看那些文章好像都说什么少用,所以本文就不粘出来给各位增加学习成本了。

Client

代码语言:javascript
复制
public class Client {
    public static void main(String[] args) throws Exception {
//        hungry();
//        hungryStatic();
//        lazy();
        lazyStatic();
    }

    public static void lazyStatic() {
        SingletonLazyStatic instance = SingletonLazyStatic.getInstance();
        SingletonLazyStatic instance1 = SingletonLazyStatic.getInstance();
        System.out.println(instance);
        System.out.println(instance1);
    }
 
    //下面3中和上面实现是类似的,只需要更换类名
    public static void lazy() throws Exception {}

    public static void hungry() {}

    public static void hungryStatic() {}

}

原型模式

原型模式听起来高大上,其实就是一种克隆对象的方法。

说到克隆不得不简单说下浅拷贝和深拷贝,浅拷贝就是指两个指针指向了同一个对象,原对象和拷贝对象只要有一个修改,另外一个也随着修改。深拷贝是指,重新创建了一个和原对象一模一样内容的拷贝对象,两者是独立的。基本数据类型是不参与拷贝过程的

Prototype: 抽象原型类,声明了clone方法的接口或者基类,其中clone方法必须由派生对象实现。 Concrete Prototype: 具体实现类,主要是用于实现或扩展clone方法的类。

原型模式UML类图

原型模式

Prototype

代码语言:javascript
复制
public abstract class PrototypePhone implements Cloneable {
    private String cpu;
    private int price;

    @Override
    public  Object clone() throws CloneNotSupportedException {
        return super.clone();
    }
    
    //省略构造函数,get,set方法

}

Concrete Prototype

代码语言:javascript
复制
public class ConcretePrototypeOnePlus extends PrototypePhone {
    public ConcretePrototypeOnePlus(String cpu, int price) {
        super(cpu, price);
        System.out.println("调用了构造函数");
    }

    @Override
    public Object clone() throws CloneNotSupportedException {
        return super.clone();
    }
}

Client

代码语言:javascript
复制
public class Client {
    public static void main(String[] args) throws CloneNotSupportedException {
        PrototypePhone phone = new ConcretePrototypeOnePlus("865", 3999);
        System.out.println("原型:" + phone);
        for (int i = 0; i < 100; i++) {
            System.out.println("生产第" + (i + 1) + "台手机:" + phone.clone());
        }
    }
}

运行的话就会发现构建的手机只通过了一次构造函数,其它的使用phone.clone() 也能同样构造出手机实例对象。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2021-05-10,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 CodeNone 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 单例模式
    • 单例模式UML类图
      • 单例模式饿汉式
        • 单例模式懒汉式
        • 原型模式
          • 原型模式UML类图
            • 原型模式
            领券
            问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档