加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

《设计模式一》单例模式和策略模式

发布时间:2020-12-14 04:46:43 所属栏目:百科 来源:网络整理
导读:1.1 单例模式-singleton Spring的Bean工厂就是单例模式,项目中自己写的情况越来越少 1.1.1 工程中最常用版本-饿汉式 /** * 优点:线程安全 * 缺点:不管用到与否,类装载时就完成实例化 */public class Singleton_01 { private static final Singleton_01 I

1.1 单例模式-singleton

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

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

/**
 * 优点:线程安全
 * 缺点:不管用到与否,类装载时就完成实例化
 */
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);
    }
}

1.1.2 双重锁检查-懒汉式

/**
 * 完美版本
 * 缺点:加锁带来效率下降
 * 优点: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;
    }
}

1.1.3 完美版本,但不直观

/**
 * 不仅可以解决线程同步,还可以防止反序列化。
 */
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();
        }
    }
}

1.2 策略模式-Strategy

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

修改关闭,扩展开放

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

1.2.1 Java的Comparator接口策略分析

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

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

        l.sort(comparator);

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

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读