6. Interview-GoF

2020-07-21  本文已影响0人  allen锅
23种GoF(5+7+11) 设计模式之间的关系

1 设计模式的设计原则(6大原则)

2 设计模式分类

设计模式起源于建筑行业,1995年四人帮GoF提出了23种设计模式。大致可以分为三类:

3 工厂模式

3.1 简单工厂/静态工厂

创建型模式,其实不算做23种GoF中的设计模式。根据不同的参数返回不同类的实例。一般被创建的实例都有共同的父类。

3.2 工厂方法模式

3.3 抽象工厂模式

4 单例模式

4.1 两种方式

懒汉式:空间换时间,延迟加载,线程非安全

public class Singleton {

    private static Singleton instance;

    private Singleton() {

    }

    public static Singleton getInstance() {
        if (instance == null) {
            instance = new Singleton();
        }
        return instance;
    }
}

恶汉式:时间换空间,线程安全,利用了static的特性,只会在JVM加载类的时候初始化一次,不会出现并发

public class Singleton {

    // 4.定义一个静态变量存储创建的实例,直接new实例,主动利用static特性(static变量在JVM加载类的时候初始化一次,不会出现并发)
    private static Singleton instance = new Singleton();

    // 1.私有化构造方法
    private Singleton() {

    }

    // 2.提供一个方法返回实例
    // 3.这个方法要定义成类方法,要加上static
    public static Singleton getInstance() {
        // 5.直接返回这个实例
        return instance;
    }
}

4.2 懒汉式线程安全问题

synchronized同步方法

public class Singleton {

    // 4.定义一个变量存储创建的实例
    // 5.因为要在静态方法中使用,所以被迫加上static,并非主动使用static的特性
    private static Singleton instance = null;

    // 1.私有化构造方法
    private Singleton() {
    }

    // 2.提供一个方法返回实例
    // 3.这个方法要定义成类方法,要加上static
    public static synchronized Singleton getInstance() {
        // 6.判断是否有实例
        if (null == instance) {
            // 6.1 没有就创建一个实例
            instance = new Singleton();
        }

        // 6.2 如果有直接使用
        return instance;
    }
}

synchronized同步代码块,双重检查加锁

public class Singleton {

    // 4.定义一个变量存储创建的实例
    // 5.因为要在静态方法中使用,所以被迫加上static,并非主动使用static的特性
    private volatile static Singleton instance = null;

    // 1.私有化构造方法
    private Singleton() {
    }

    // 2.提供一个方法返回实例
    // 3.这个方法要定义成类方法,要加上static
    public static  Singleton getInstance() {
        // 6.判断是否有实例
        if (null == instance) {
            // 6.1 没有就创建一个实例
            synchronized (Singleton.class) {
                if (null == instance) {
                    instance = new Singleton();
                }
            }
        }
        // 6.2 如果有直接使用
        return instance;
    }
}

静态内部类+多线程缺省同步锁

public class Singleton {

    private static class SingletonHolder {
        private static Singleton instance = new Singleton();
    }

    private Singleton() {
    }

    public static Singleton getInstance() {
        return SingletonHolder.instance;
    }
}
public static void main(String[] args) throws Exception {
    Singleton singleton = Singleton.getInstance();
    Constructor<Singleton> constructor = Singleton.class.getDeclaredConstructor();
    constructor.setAccessible(true);
    Singleton newSingleton = constructor.newInstance();
    System.out.println(singleton == newSingleton);
}
<dependency>
    <groupId>org.apache.commons</groupId>
    <artifactId>commons-lang3</artifactId>
    <version>3.8.1</version>
</dependency>

public class Singleton implements Serializable {

    private static class SingletonHolder {
        private static Singleton instance = new Singleton();
    }

    private Singleton() {

    }

    public static Singleton getInstance() {
        return SingletonHolder.instance;
    }

    public static void main(String[] args) {
        Singleton instance = Singleton.getInstance();
        byte[] serialize = SerializationUtils.serialize(instance);
        Singleton newInstance = SerializationUtils.deserialize(serialize);
        System.out.println(instance == newInstance);
    }
}

枚举

public enum Singleton {

    // 定义一个枚举元素,代表Singleton的唯一实例
    INSTANCE;

  public EnumSingleton getInstance(){
        return INSTANCE;
    }
}
public class User {
    //私有化构造函数
    private User(){ }
 
    //定义一个静态枚举类
    static enum SingletonEnum{
        //创建一个枚举对象,该对象天生为单例
        INSTANCE;
        private User user;
        //私有化枚举的构造函数
        private SingletonEnum(){
            user=new User();
        }
        public User getInstnce(){
            return user;
        }
    }
 
    //对外暴露一个获取User对象的静态方法
    public static User getInstance(){
        return SingletonEnum.INSTANCE.getInstnce();
    }
}

public class Test {
    public static void main(String [] args){
        System.out.println(User.getInstance());
        System.out.println(User.getInstance());
        System.out.println(User.getInstance()==User.getInstance());
    }
}
结果为true
public class Main {

    public static void main(String[] args) {
        Singleton.INSTANCE.doSomething();
    }
}

5 枚举为什么能实现单例模式?

6 枚举为什么不能继承?

7 枚举为什么是线程安全的?

8 为什么反序列化枚举类型也不会创建新的实例?

9 原型模式

10 建造者模式 / 生成器模式

11 代理模式(Proxy)

静态代理:编译时就创建代理对象

动态代理 / JDK动态代理

CGlib动态代理

12 适配器模式(Adapter)

适配器模式

13 外观模式 / 门面模式(Facade)

门面模式/外观模式

14 装饰模式(Decorator)

15 桥接模式(Bridge)

16 组合模式(Composite)

组合模式

17 享元模式(Flyweight)

享元模式

18 观察者模式(Observer)

19 职责链模式 / 责任链模式(Chain of Responsibility)

职责链模式

20 策略模式(Strategy)

策略模式

解决什么问题?

实现逻辑

扩展性

新增加一种策略的两种实现方式:

策略模式的本质

分离算法,选择实现

21 模板方法模式(Template Method)

22 状态模式(State)

状态模式

解决什么问题?

23 备忘录模式(Memento)

备忘录模式

24 中介者模式(Mediator)

中介者模式

25 命令模式(Command)

命令模式

26 解释器模式(Interpreter)

解释器模式

27 迭代器模式(Iterator)

迭代器模式

28 访问者模式(Visitor)

访问者模式

29 spring用到了哪些设计模式?用在什么场景?

30 Tomcat用到了哪些设计模式?

上一篇 下一篇

猜你喜欢

热点阅读