单例模式和策略模式

目录
  • 设计模式
    • 单例模式-singleton
      • 工程中最常用版本-饿汉式
      • 双重锁检查-懒汉式
      • 完美版本,但不直观
    • 策略模式-Strategy
      • 修改关闭,扩展开放
      • Java的Comparator接口策略分析

设计模式

单例模式-singleton

  • Spring的Bean工厂就是单例模式,项目中自己写的情况越来越少

工程中最常用版本-饿汉式

/**
 * 优点:线程安全
 * 缺点:不管用到与否,类装载时就完成实例化
 */
public class Singleton_01 {
    private static final Singleton_01 INSTANCE = new Singleton_01();

    private Singleton_01() {};

    public static Singleton_01 getInstance() {
        return INSTANCE;
    }
    public static void main(String[] args) {
        Singleton_01 m1 = Singleton_01.getInstance();
        Singleton_01 m2 = Singleton_01.getInstance();
        System.out.println(m1 == m2);
    }
}

双重锁检查-懒汉式

/**
 * 完美版本
 * 缺点:加锁带来效率下降
 * 优点:volatile禁止指令重排序,防止半初始化现象。
 * 优点:双重检查保证锁的粒度更小,且消除重复new对象的问题
 */
public class Singleton_02 {
    private static volatile Singleton_02 INSTANCE; //JIT

    private Singleton_02() {
    }

    public static Singleton_02 getInstance() {
        if (INSTANCE == null) {
            synchronized (Singleton_02.class) {
            // 第二次检查如果其他线程完成了初始化,其他线程无法进入
                if(INSTANCE == null) {
                    try {
                        Thread.sleep(1);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    INSTANCE = new Singleton_02();
                }
            }
        }
        return INSTANCE;
    }
}

完美版本,但不直观

/**
 * 不仅可以解决线程同步,还可以防止反序列化。
 */
public enum Singleton_03 {

    INSTANCE;
    
    public static void main(String[] args) {
        for(int i=0; i<100; i++) {
            new Thread(()->{
               System.out.println(Singleton_03.INSTANCE.hashCode());
            }).start();
        }
    }
}

策略模式-Strategy

  • Java的Comparator接口,该接口只有一个抽象方法compare(T o1, T o2)就是策略模式的一个应用;

修改关闭,扩展开放

  • 实现排序方法,自己实现比较器传入,就是不同的策略传入,实现可扩展性,策略模式是封装的做一件事的不同的方式

Java的Comparator接口策略分析

  1. 策略:这里是比较策略,类比其他的比如售卖策略等
public interface Comparator {
    int compare(T o1, T o2);
}
  1. 具体策略实现:这里定义根据对象的id来比较。类比售货打八折销售,满减等策略
 Comparator comparator = new Comparator() {
        @Override
        public int compare(User o1, User o2) {
              return o1.getId() - o2.getId();
        }
 };
  1. 应用策略:事先定义好策略应用
// 比如list的sort方法,需要传入比较策略
public static void main(String[] args) {
        List l = new ArrayList<>();
        l.add(new User(2, "zhangsan", "123", "aaaa"));
        l.add(new User(3, "zhangsan", "123", "aaaa"));
        l.add(new User(1, "zhangsan", "123", "aaaa"));

        
        Comparator comparator = new Comparator() {
            @Override
            public int compare(User o1, User o2) {
                return o1.getId()-o2.getId();
            }
        };

        l.sort(comparator);

    }
    
// list的sort方法对比较策略的应用,事实上是用泛型接收具体类型
    default void sort(Comparator c) {
        Object[] a = this.toArray();
        Arrays.sort(a, (Comparator) c);
        ListIterator i = this.listIterator();
        for (Object e : a) {
            i.next();
            i.set((E) e);
        }
    }
  • 策略模式的实质是把具体的实现策略抽离出来,达到可扩展的目的,比如要进行比较,那么比较策略我们自己指定,“比较”动作可以识别我们传入的策略,和多态有点相似

你可能感兴趣的:(单例模式和策略模式)