一篇文章搞定23种设计模式,持续更新中

目录

  • 前言
    • 设计模式类型
      • 1 创建型模式
        • 1.1 单例模式
          • 1.1.1 饿汉式(静态常量)
          • 1.1.2 饿汉式(静态代码块)
          • 1.1.3 懒汉式(线程不安全)
          • 1.1.4 懒汉式(线程安全,同步方法)
          • 1.1.5 懒汉式(线程不安全,同步代码块)
          • 1.1.6 双重检查
          • 1.1.7 静态内部类
          • 1.1.8 枚举
        • 抽象工厂模式
        • 原型模式
        • 建造者模式
        • 工厂模式
      • 2.结构性模式
        • 适配器模式
        • 桥接模式
        • 装饰模式
        • 组合模式
        • 外观模式
        • 享元模式
        • 代理模式
      • 3.行为型模式
        • 模板方法模式
        • 命令模式
        • 访问者模式
        • 迭代器模式
        • 观察者模式
        • 中介者模式
        • 备忘录模式
        • 解释器模式(Interpreter模式)
        • 状态模式
        • 策略模式
        • 职业链模式(责任链模式)

前言

设计模式不是代码,是某类问题的通用解决方案,设计模式代表了最佳的实践

设计模式类型

1 创建型模式

1.1 单例模式

所谓的单例设计模式,就是采取一定的方法保证在整个软件系统中,对某个类而言只存在一个对象实例,并且该类只提供一个取得其对象实例的方法

1.1.1 饿汉式(静态常量)

1)构造器私有化(防止new)
2)类的内部创建对象
3)向外暴露一个静态的公共方法 getInstance
4)代码实现
以下是实验代码

//饿汉式(静态变量)
public class Singleton1 {
    public static void main(String[] args) {
        //测试
        Singleton instance = Singleton.getInstance();
        Singleton instance1 = Singleton.getInstance();
        System.out.println(instance==instance1);//ture
        System.out.println("instance.hashCode= "+instance.hashCode());// 相同
        System.out.println("instance1.hashCode= "+instance1.hashCode());//相同


    }
}
//饿汉式(静态变量)
class Singleton{
    //1.构造器私有化,外部不能new
    private Singleton(){
    }
    //2.本类内部创建对象实例
    private final static Singleton instance = new Singleton();

    //3.对外提供一个公有的静态方法,返回实例对象
    public static Singleton getInstance(){
        return instance;
    }
}

优缺点:
1)优点:写法简单,在类加载的时候就完成实例化,避免了线程同步问题。
2)缺点:在类装载的时候就完成实例化,没有达到Lazy Loading的效果;如果从始至终没用过这个实例,则会造成内存的浪费。
3)这种方式基于classloader机制避免了多线程的同步问题。不过,instance在类装载就实例化,但是导致类加载的原因有很多,不能确定有没有其他方式(或其他静态方法)导致类装载,这时候初始化instance就没有达到lazy loading的效果
conclusion:这种单例模式可能会造成内存浪费。
专业名词:
lazy loading:懒加载其实就是延时加载,即当对象需要用到的时候再去加载

1.1.2 饿汉式(静态代码块)

优缺点:
1)这种方式跟**1.1.1饿汉式(静态常量)**相似,只不过将实例化操作放在静态代码块中,也是在类装载的时候、就执行静态代码块中的代码,初始化类的实例。
conclusion:同样地,有可能会造成内存浪费
专业名词
静态代码块:随着类的加载而执行,而且只执行一次
扩展
类中初始化执行顺序:静态代码块----->非静态代码块-------->构造函数

以下是实验代码


//饿汉式(静态代码块)
class Singleton{
    //1.构造器私有化,外部不能new
    private Singleton(){ }

    //2.本类内部创建对象实例
    private static Singleton instance;

    static{ //在静态代码块中,创建单例对象
        instance = new Singleton();
    }

    //3.对外提供一个公有的静态方法,返回实例对象
    public static Singleton getInstance(){
        return instance;
    }
}
1.1.3 懒汉式(线程不安全)
package demo02.singleton.type3;
public class Singleton03 {
    public static void main(String[] args) {
        System.out.println("懒汉式1,线程不安全");
        Singleton insatnce = Singleton.getInsatnce();
        Singleton insatnce1 = Singleton.getInsatnce();
        System.out.println(insatnce==insatnce1);
        System.out.println("instance.hashCode= "+insatnce.hashCode());// 相同
        System.out.println("instance1.hashCode= "+insatnce1.hashCode());//相同
    }
}

class Singleton{
    private static Singleton instance;
    private Singleton(){

    }
    //提供一个静态的公有方法,当使用到该方法时,才去new instance
    public static Singleton  getInsatnce(){
        if(instance ==null)//第一次为空 new Singleton
            return  instance=new Singleton();
        else
            return instance;//不为空,直接返回
    }
}

优缺点:
1)达到lazy loading效果,但只能单线程下使用
2)如果在多线程的情况,一个线程进入if(instance ==null)判断语句块,还未来得及往下执行,另一个线程也通过了和这个语句,这时会产生多个实例。所以,多线程下不可用这种方式
conclusion:实际开发中,不要用这种方式

1.1.4 懒汉式(线程安全,同步方法)
class Singleton{
    private static Singleton instance;
    private Singleton(){

    }
    //在方法级别上使用synchronized,解决线程安全问题
    public static synchronized Singleton getInsatnce(){
        if(instance ==null)
            return  instance=new Singleton();
        else
            return instance;
    }

}

优缺点:
1)解决线程安全问题
2)效率低,每个线程想要得到实例时,执行instance()都要同步进行。但是instance()只需要执行一次,就已经实例化;后面想要获得实例直接return即可。在方法级别进行同步效率低下
conclusion:不推荐使用

1.1.5 懒汉式(线程不安全,同步代码块)
class Singleton{
    private static Singleton instance;
    private Singleton(){

    }
    public static  Singleton getInsatnce(){
        if(instance ==null)
          synchronized (Singleton.class){
            return instance =new Singleton();
          }
        else
            return instance;
    }

}

优缺点:
1)这种同步并不能起到线程同步的作用;跟上述1.1.3的线程不安全问题一样;有可能会产生多个实例对象
conclusion:不能使用

1.1.6 双重检查
class Singleton{
    private static  volatile Singleton instance;//加入了volatitle关键字
    private Singleton(){

    }
    //加入双重检查代码,解决线程安全问题,同时解决懒加载问题
    //同时保证了效率
    public static Singleton getInsatnce(){
        if(instance ==null)
          synchronized (Singleton.class){
           if(instance ==null){
               return instance =new Singleton();
           }
          }

            return instance;
    }

}

优缺点:
1)Double-Check概念是多线程开发中常用到的;如代码中,我们进行了两次if(singleton == null)检查,这样保证了线程安全
2)实例化代码在任何情况下,都只能执行一次
3)线程安全;延迟加载;效率高。
conclusion:推荐使用这种单例设计模式

1.1.7 静态内部类
//静态内部类完成
class Singleton{
    private static  volatile Singleton instance;//加入了volatitle关键字

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

    //写一个静态内部类,该类中有一个静态属性 Singleton
    private static class SingletonInstance{
        private static final Singleton INSTANCE=new Singleton();
    }

    //同时保证了效率
    public static Singleton getInsatnce(){
        //只有在调用这个方法时,静态内部类才会被装载。
        return SingletonInstance.INSTANCE;
    }

}

优缺点:
1)采用类装载机制保证初始化实例时只有一个线程
2)静态内部类只有被调用时才会实例化,不会随着主类装载而装载。
3)类的静态属性表明,只有在第一次加载类时才会初始化;在类初始化时,别的线程是无法访问的。
conclusion:推荐使用这种方式

1.1.8 枚举

public class Singleton08 {
    public static void main(String[] args) {
        Singleton instance = Singleton.INSTANCE;
        Singleton instance1 = Singleton.INSTANCE;
        System.out.println(instance==instance1);
        System.out.println("instance.hashCode= "+instance.hashCode());// 相同
        System.out.println("instance1.hashCode= "+instance1.hashCode());//相同
    }
}

//使用枚举,可以实现单例,推荐使用
enum Singleton{
    INSTANCE;
    public void OK(){
        System.out.println("ok");
    }
}

优缺点:
1)借助JDK1.5添加的enum实现,避免了多线程问题,而且能够防止反序列化问题
2)这种方式是 Effective Java 作者Josh Bloch 所提倡的方式
conclusion:推荐使用这种方式

抽象工厂模式

原型模式

建造者模式

工厂模式

2.结构性模式

适配器模式

桥接模式

装饰模式

组合模式

外观模式

享元模式

代理模式

3.行为型模式

模板方法模式

命令模式

访问者模式

迭代器模式

观察者模式

中介者模式

备忘录模式

解释器模式(Interpreter模式)

状态模式

策略模式

职业链模式(责任链模式)

你可能感兴趣的:(设计模式)