java设计模式

1. 单例模式

推荐直接使用饿汉式,不存在线程安全问题
单例模式懒汉式存在的问题

1.1 如何避免单例模式被破坏

避免破坏单例
单例模式被破坏主要有三种:

  1. 使用反射拿到对象,因反射最终还是调用了构造方法,只不过是有了更大的权限,调用的是private的构造方法,所以只需要在构造函数中抛出异常即可
  2. 使用clone方法,同理,在clone方法跑出异常
  3. 反序列化,反序列化会调readResolve,用在类中写上readResolve方法,方法直接返回单例
public class Singleton implements Serializable {

    private static Singleton instance = null;

    private Singleton() {

    }

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


    protected Object readResolve() {
        System.out.println("---------------------------readresolve_______");
        return instance;
    }
}

2 适配器模式

2.1 缺省适配器(接口适配器)

注意: 缺省的适配器设计模式和JDK8之后引入的一个新功能是一样的,JDK8中允许接口中有方法的实现,也即default方法。所以在jdk8中,可以直接使用这一特性取代缺省的适配器模式。
举例:springboot中WebMvcConfigurerAdapter已经标记为废弃,就是因为它采用的是缺省适配器模式,如果使用jdk8,可以直接实现WebMvcConfigurer ,不需要再WebMvcConfigurerAdapter 继承适配器,一下spring官方注释有说明


/**
 * An implementation of {@link WebMvcConfigurer} with empty methods allowing
 * subclasses to override only the methods they're interested in.
 *
 * @author Rossen Stoyanchev
 * @since 3.1
 * @deprecated as of 5.0 {@link WebMvcConfigurer} has default methods (made
 * possible by a Java 8 baseline) and can be implemented directly without the
 * need for this adapter
 */
@Deprecated
public abstract class WebMvcConfigurerAdapter implements WebMvcConfigurer {
}
2.1.1 缺省适配器(接口适配器)模式实现方式:
  1. 创建一个XXX接口,里面有若干方法;
  2. 创建一个XXXAdapter抽象类,实现XXX接口所有方法,不过方法体都是空的,没有具体实现
  3. 创建自己的业务类,实现XXXAdapter,重写需要用到的方法
2.1.2 缺省Adapter作用解释
  1. 一个接口有N多方法,可能我们需要的只是其中一个,如果直接实现接口,会造成每次都要实现一堆我用不上的方法,所以搞一个中间的Adapter帮我们实现所有方法,尽管没有方法体。
  2. 必须使用抽象类!!因为抽象类无法被实例化,这就提醒我们使用的时候必须要对Adapter进行实现,实现了以后我们只需要重写我们想用的那个方法即可,而不用重写一堆没用的。
2.2 类适配器
2.2.1 场景举例

手机(客户端)充电要用10V电压(目标),而我国直接提供的电压是220V(源头),现在给手机充电就需要把220V电压先转换成10V,这就需要用到充电头(适配器)来转换。

2.2.2 实现
  1. 有一个已存在的类,并且被其他代码多次使用,在新的代码中也要使用到它,不过不能直接使用,需要改造;——源
  2. 有一个接口,这个接口是新代码中要直接用到的;——目标
  3. 源和目标不一致,需要实现从源到目标的转换,转换工具就叫做Adapter——适配器
  4. 适配器需要继承接口(目标),同时实现类(源),重写接口(目标)中的方法,方法中的具体内容就是转换源——》目标。
2.2.3 代码
//目标电压
public interface Voltage5V {
    int out5V();
}
//源头电压
public class Voltage220V {
    public int out220V(){
        return  220;
    }
}
//适配器进行电压转换
public class Adapter extends Voltage220V implements Voltage5V{
    @Override
    public int out5V() {
        System.out.println("适配器进行电压转换");
        return out220V()/22;
    }
}

//客户端
public class Phone {
    public void charge(Voltage5V v){
        System.out.println("开始充电");
        System.out.println("充电电压," + v.out5V());
    }

    public static void main(String[] args) {
        Phone phone = new Phone();
        phone.charge(new Adapter());
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值