设计模式专题

设计模式的六大设计原则

  1. 单一职责:一个类只负责实现一个功能
  2. 开闭原则:对于软件实体尽量在不修改原代码的基础上扩展
  3. 里氏代换:在软件中将一个基类对象替换成它的子类对象,程序将不会产生任何错误和异常
  4. 依赖倒转原则:在程序代码中传递参数时或在关联关系中,尽量引用层次高的抽象层类,而不要用具体类来做这些事情。
  5. 接口隔离原则:使用多个专门的接口,而不使用单一的总接口,即客户端不应该依赖那些它不需要的接口
  6. 迪米特法则:一个软件实体应当尽可能少地与其他实体发生相互作用

经验之谈:

一般情况下,不建议使用懒汉方式,建议使用饿汉方式。只有在要明确实现 lazy loading 效果时,才会使用静态内部类登记方式。如果涉及到反序列化创建对象时,可以尝试使用枚举方式。如果有其他特殊的需求,可以考虑使用双检锁方式。

1.单例模式

单例模式保证了系统内存中该类只存在一个对象。JDK中, java.lang.Runtime就是经典的单例模式。
使用场景:对于一些需要频繁创建销毁的对象,使用单例模式可以提高系统性能(springboot默认创建的bean是单实例)。

5种实现方式
1.1 饿汉式
//饿汉式(静态变量)
class Singleton{
    // 1. 构造器私有化,防止外部new
    private Singleton(){
    }
    // 2.本类内部创建对象实例
    private final static Singleton instance = new Singleton();
    // 3.提供一个公有的静态方法,返回实例对象
    public static Singleton getInstance(){
        return instance;
    }
}

优点:在类装载的时候就完成了实例化,线程安全,调用效率高;
缺点:不能延时加载,可能会造成内存浪费。

1.2 懒汉式
//懒汉式
class Singleton{
    // 1. 构造器私有化,防止外部new
    private Singleton(){
    }
    // 2.本类内部创建对象实例
    private static Singleton instance;
    // 3.提供一个公有的静态方法,当使用到该方法时,才去创建instance,即懒汉式,加入同步处理的代码,解决线程安全问题
    public static synchronized Singleton getInstance(){ 
        if(instance==null){
            instance = new Singleton();
        }
        return instance;
    }
}

优点:线程安全;能延时加载
缺点:效率低(因为每个线程在想获得类的实例时候,执行getInstance()方法都要进行同步。而其实这个方法只执行一次实例化代码就够了,后面的想获得该类实例,直接return就行了。方法进行同步效率太低,在实际开发中,不推荐这种方式)

1.3 Double-Check(推荐使用)
class Singleton{
    // 1. 构造器私有化,防止外部new
    private Singleton(){
    }
    // 2.本类内部创建对象实例,volatile保证instance可见性
    private static volatile Singleton instance;
    // 3.提供一个公有的静态方法,加入双重检查代码,解决线程安全问题,同时解决懒加载问题(效率低问题),同时保证了效率
    public static Singleton getInstance(){
        if(instance==null){
            synchronized (Singleton.class){
                if(instance==null){
                    instance=new Singleton();
                }
            }
        }
        return instance;
    }
}

优点:线程安全;(利用静态内部类特点实现)延迟加载;效率较高

Double-Check概念是多线程开发中常使用到的,如代码中所示,我们进行了两次 if(instance == null)检查,这样就可以保证线程安全了。这样,实例化代码只用执行一次,后面再次访问时,判断 if(instance==null),直接return实例化对象,也避免了反复进行方法同步。

1.4 静态内部类(推荐)

内部静态类的特性: static内部类是内部类中一个比较特殊的情况,一旦内部类使用static修饰,那么此时这个内部类就升级为顶级类(具备外部类的特性),static内部类不仅可以在内部定义static元素(普通内部类不可以),而且在构建对象的时候也可以一次完成(普通内部类需要先实例化外部类,然后用外部类的对象创建自己的对象)

class Singleton{
    // 1. 构造器私有化,防止外部new
    private Singleton(){
    }
    // 2.一个静态内部类,该类中有一个静态属性Singleton
    private static class SingletonInstance{
        private static final Singleton INSTANCE = new Singleton();
    }
    // 3.提供一个静态的方法,直接返回SingletonInstance.INSTANCE
    public static synchronized Singleton getInstance(){
        return SingletonInstance.INSTANCE;
    }
}

优点:线程安全;延时加载;效率高;静态内部类在使用的时候才加载,而且只加载一次。

1.5 枚举(推荐)
public class SingletonTest01 {
    public static void main(String args[]){
        Singleton instance = Singleton.INSTANCE;
        Singleton instance2 = Singleton.INSTANCE;
        System.out.println(instance==instance2);
        System.out.println("instance.hashCode:"+instance.hashCode()+"instance.hashCode2"+instance2.hashCode());
        instance.sayOK();

    }
}

enum Singleton{
    INSTANCE;//属性
    public void sayOK(){
        System.out.println("OK");
    }
}

优点:线程安全,调用效率高,不能延时加载,可以天然的防止反射和反序列化调用

如何选用:

-单例对象 占用资源少,不需要延时加载,枚举 好于 饿汉

-单例对象 占用资源多,需要延时加载,静态内部类 好于 懒汉式

2.享元模式

3.原型模式

作用:对象的复制。

原型模式由来:

通常我们创建一个对象都是通过new一个实例来创建,假如需要多个相同的实例即重复创建许多相同对象的时候,每次都去new,会增加创建对象的复杂度以及消耗内存空间。

这时候就需要原型模式来解决。原型就是已经存在的某一个实例,如果后面需要更多的这样的实例,可以通过对原对象进行拷贝来完成创建。

4.观察者设计模式

5.工厂设计模式

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值