面试题-2.设计模式

单例模式

:指一个类只有一个实例,且该类能自行创建这个实例的一种模式。例如,Windows
中只能打开一个任务管理器,这样可以避免因打开多个任务管理器窗口而造成内存资源的浪费,或出现各个窗口显示内容的不一致等错误。

在这里插入图片描述

通过提供一个静态的对象instance,利用private权限的构造方法和getInstance()方法来给予访问者一个单例。
缺点是,没有考虑到线程安全,可能存在多个访问者同时访问,并同时构造了多个对象的问题。之所以叫做懒汉模式,主要是因为此种方法可以非常明显的lazy
loading。 针对懒汉模式线程不安全的问题,我们自然想到了,在getInstance()方法前加锁,于是就有了第二种实现。
如果不删除这两个关键字就能保证线程安全,但是每次访问时都要同步,会影响性能,且消耗更多的资源,这是懒汉式单例的缺点。

在这里插入图片描述

双重检查[推荐用]

public class Singleton {
    
    

    private static volatile Singleton singleton;

    private Singleton() {
    
    }

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

进行了两次if (singleton == null)检查,这样就可以保证线程安全了。这样,实例化代码只用执行一次,后面再次访问时,判断if
(singleton == null),直接return实例化对象。 优点:线程安全;延迟加载;效率较高。

静态内部类[推荐用]

public class Singleton {
    
    

    private Singleton() {
    
    }

    private static class SingletonInstance {
    
    
        private static final Singleton INSTANCE = new Singleton();
    }

    public static Singleton getInstance() {
    
    
        return SingletonInstance.INSTANCE;
    }
}

类的静态属性只会在第一次加载类的时候初始化,所以在这里,JVM帮助我们保证了线程的安全性,在类进行初始化时,别的线程是无法进入的。
优点:避免了线程不安全,延迟加载,效率高。

代理模式

静态代理在使用时,需要定义接口或者父类,被代理对象与代理对象一起实现相同的接口或者是继承相同父类.
可以做到在不修改目标对象的功能前提下,对目标功能扩展.因为代理对象需要与目标对象实现一样的接口,所以会有很多代理类,类太多.同时,一旦接口增加方法,目标对象与代理对象都要维护.
如何解决静态代理中的缺点呢?答案是可以使用动态代理方式

Jdk

动态代理分为 基于jdk的动态代理和cglib的 首先基于jdk的动态代理:
目标对象要实现接口,但是代理对象不需要,代理对象是动态通过newProxyInstance方法生成的,方法里面有三个参数,
他实现了invocationHandler并冲洗了 invoke 方法对目标方法进行增强
注意该方法是在Proxy类中是静态方法,且接收的三个参数依次为:
ClassLoader loader:
指定当前目标对象使用类加载器,获取加载器的方法是固定的
Class<?>[] interfaces,:
目标对象实现的接口的类型,使用泛型方式确认类型
InvocationHandler h:
事件处理,执行目标对象的方法时,会触发事件处理器的方法,会把当前执行目标对象的方法作为参数传入

Cglib :

动态代理:目标对象不需要实现接口,代理对象是继承目标类,通过enhancer.create()产生,然后对对目标对象进行增强当需要使用目标对象时,只需要调用代理对象就可以完成。它用于解决无接口的代理问题

工厂模式

工厂模式是我们最常用的实例化对象模式了,是用工厂方法代替new操作的一种模式。著名的Jive论坛
,就大量使用了工厂模式,工厂模式在Java程序系统可以说是随处可见。因为工厂模式就相当于创建实例对象的new,我们经常要根据类Class生成实例对象,如A
a=new A()
工厂模式也是用来创建实例对象的,所以以后new时就要多个心眼,是否可以考虑使用工厂模式,虽然这样做,可能多做一些工作,但会给你系统带来更大的可扩展性和尽量少的修改量。(百度百科)
工厂模式又分为: 简单工厂模式:允许接口创建对象,但不会暴露对象的创建逻辑。 工厂方法模式:
允许接口创建对象,但使用哪个类来创建对象,则是交由子类决定的 抽象方法模式:
抽象工厂是一个能够创建一系列相关的对象而无需指定/公开其具体类的接口。该模式能够提供其他工厂的对象,在其内部创建其他对象。

原型模式

原型模式(Prototype
Pattern)是用于创建重复的对象,同时又能保证性能。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。
这种模式是实现了一个原型接口,该接口用于创建当前对象的克隆。当直接创建对象的代价比较大时,则采用这种模式。例如,一个对象需要在一个高代价的数据库操作之后被创建。我们可以缓存该对象,在下一个请求时返回它的克隆,在需要的时候更新数据库,以此来减少数据库调用。

扫描二维码关注公众号,回复: 12632971 查看本文章

猜你喜欢

转载自blog.csdn.net/zyf_fly66/article/details/114011895