设计模式学习记录(持续更新)

169 阅读2分钟
# 设计模式

## 七大原则

1\. 开闭原则:对拓展开放,对修改关闭。
2\. 里氏替换:继承必须确保超类所拥有的性质在子类中仍然成立。尽量不替换父类的方法
3\. 依赖倒置原则:面向接口变成,而不是面向实现编程。
4\. 单一职责原则:控制类的大小、将类解耦、提高内聚性。
5\. 接口隔离原则:为各个类建立他们需要的专用接口。
6\. 迪米特法则:只与你的“朋友交谈”,不与陌生人交流。
7\. 合成复用原则:尽量先使用组合或者聚合等关联关系来使用,而不是继承和实现。 

## 创建型模式 :cat:

### 单例模式

#### 懒汉式

```java
public class LazyMan {
    private static LazyMan lazyMan;
    private LazyMan(){}

    public static LazyMan getInstance() throws InterruptedException {
        if (lazyMan==null){
            lazyMan=new LazyMan();
        }
        return lazyMan;
    }

    public static void main(String[] args) throws InterruptedException {
        /**
         * 线程不安全 a,b 同时进入==null
         * 这样会导致都会new
         * 单例创建不成功
         */
        LazyMan a=LazyMan.getInstance();
        LazyMan b=LazyMan.getInstance();

        System.out.println(a.hashCode());
        System.out.println(b.hashCode());
    }
}
```

#### 饿汉式

```java
public class Hungry {
    private static Hungry hungry = new Hungry();
    private Hungry() {}
    private static Hungry getInstance() {
        return hungry;
    }

    public static void main(String[] args) {
        /**
         * 线程安全,但是较为浪费空间
         * 如果没有用到则会一直占用空间
         */
        Hungry a=Hungry.getInstance();
        Hungry b=Hungry.getInstance();

        System.out.println(a.hashCode());
        System.out.println(b.hashCode());
    }
}
```

#### 双重检查锁

```java
public class DoubleCheckLock {
/**
     * 错误版,没有volatile,会导致可能存在的指令重排
     * 对象初始化过程分为三步
     *      1、分配空间
     *      2、创建对象
     *      3、对象指向空间
     *      correct step is 123,but maybe exist 132,when a process 13,b return a null object  
     */
    private static DoubleCheckLock doubleCheckLock;

    private DoubleCheckLock() {
    }

    public static DoubleCheckLock getInstance() {
        if (doubleCheckLock == null) {
            synchronized (DoubleCheckLock.class) {
                if (doubleCheckLock == null) {
                    doubleCheckLock = new DoubleCheckLock();
                }
            }
        }
        return doubleCheckLock;
    }

    public static void main(String[] args) {
        DoubleCheckLock a=DoubleCheckLock.getInstance();
        DoubleCheckLock b=DoubleCheckLock.getInstance();

        System.out.println(a.hashCode());
        System.out.println(b.hashCode());
    }
}
//正确版
public class DoubleCheckLock {
    /**
     * 正确版,volatile防止指令重排
     * 第一个volatile内的synchronized,进行线程同步防止指令,这样就能保证第二个if线程安全
     */
    private static volatile DoubleCheckLock doubleCheckLock;

    private DoubleCheckLock() {
    }

    public static DoubleCheckLock getInstance() {
        if (doubleCheckLock == null) {
            synchronized (DoubleCheckLock.class) {
                if (doubleCheckLock == null) {
                    doubleCheckLock = new DoubleCheckLock();
                }
            }
        }
        return doubleCheckLock;
    }

    public static void main(String[] args) {
        DoubleCheckLock a=DoubleCheckLock.getInstance();
        DoubleCheckLock b=DoubleCheckLock.getInstance();

        System.out.println(a.hashCode());
        System.out.println(b.hashCode());
    }
}

```

#### 枚举

```java
public enum  EnumF {
    /**
     * 枚举可以保证单例,建议使用
     * 反射安全
     */
    INSTANCE;
    private EnumF(){}
    public static EnumF getInstance(){
        return INSTANCE;
    }

    public static void main(String[] args) {
        EnumF a=EnumF.getInstance();
        EnumF b=EnumF.getInstance();

        System.out.println(a.hashCode());
        System.out.println(b.hashCode());
    }
}
```

#### 静态内部类

```java
public class StaticClass {
    /**
     * 利用静态内部类可以天然访问外部类的方法
     * 有反射,单例不安全
     */
    private StaticClass(){}
    public static StaticClass getInstance(){
        return InnerClass.staticClass;
    }
    private static class InnerClass{
        private static final  StaticClass staticClass= new StaticClass();
    }
}

```