设计模式

Spring 等框架中使用了哪些设计模式

  • BeanFactory和ApplicationContext应用了工厂模式
  • 在bean创建中,spirng也为不同的scope定义的对象提供了单例和原型等模式实现
  • aop则使用了代理模式、装饰器模式和适配器模式
  • 各种事件监听器,是观察者模式
  • 类似jdbctemplate则应用了模板模式

单例模式

1、常规单例模式

   public class Singleton {
       private static Singleton instance = new Singleton();
       public static Singleton getInstance() {
          return instance;
       }
    }

java会自动为没有声明构造函数的类,定义一个public的无参数的构造函数,所以上面的例子并不能保证额外的对象不被创建出来,完全可以new Singleton()创建对象
2、定义private的构造函数

   public class Singleton {
       private static Singleton instance = new Singleton();
       private Singleton() {
        }
       public static Singleton getInstance() {
          return instance;
       }
    }

3、懒加载模式(lazy-load),改善初始内存开销

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

4、并发场景,考虑线程安全

public class Singleton {
    private static volatile Singleton singleton = null;
    private Singleton() {
    }

    public static Singleton getSingleton() {
        if (singleton == null) { // 尽量避免重复进入同步块
            synchronized (Singleton.class) { // 同步.class,意味着对同步类方法调用
                if (singleton == null) {
                    singleton = new Singleton();
                }
            }
        }
        return singleton;
    }
}

这里的 volatile 能够提供可见性,以及保证 getInstance 返回的是初始化完全的对象。
在同步之前进行 null 检查,以尽量避免进入相对昂贵的同步块。
直接在 class 级别进行同步,保证线程安全的类方法调用。

在这段代码中,争论较多的是 volatile 修饰静态变量,当 Singleton 类本身有多个成员变量时,需要保证初始化过程完成后,才能被 get 到。
在现代 Java 中,内存排序模型(JMM)已经非常完善,通过 volatile 的 write 或者 read,能保证所谓的 happen-before,也就是避免常被提到的指令重排。换句话说,构造对象的 store 指令能够被保证一定在 volatile read 之前。
5、内部类持有静态对象的方式实现

 public class Singleton {
    private Singleton(){}
    public static Singleton getSingleton(){
        return Holder.singleton;
    }

    private static class Holder {
        private static Singleton singleton = new Singleton();
    }
}

一些人推荐利用内部类持有静态对象的方式实现,其理论依据是对象初始化过程中隐含的初始化锁(有兴趣的话你可以参考jls-12.4.2 中对 LC 的说明),这种和前面的双检锁实现都能保证线程安全,不过语法稍显晦涩,未必有特别的优势。

装饰者模式

IO 框架中InputStream是一个抽象类,标准库中提供了fileInputStream\ByteArrayInputSteam等各种不同的子类,分别从不同角度进行了功能扩展。
识别装饰器模式,可以通过识别类设计特征来进行判断,也就是其构造函数以相同的抽象类或者接口为输入参数。
装饰器本质是包装同类型实例,我们对目标对象的调用,往往通过包装类覆盖过的方法,迂回调用被包装的实例,自然实现增加额外逻辑的目的,这就是所谓的装饰。

工厂模式

JDK最新版本HTTP/2 Client API中创建HttpRequest的过程,就是构建器模式,通常会被实现为fluet风格的API,或者是方法链。

HttpRequest request = HttpRequest.newBuilder(new URI(uri))
                     .header(headerAlice, valueAlice)
                     .headers(headerBob, value1Bob,
                      headerCarl, valueCarl,
                      headerBob, value2Bob)
                     .GET()
                     .build();

谈谈你知道的设计模式?

大致按照模式的应用目标分类,设计模式可以分为创建型模式、结构型模式和行为型模式。

  • 创建型模式,是对对象创建过程的各种问题和解决方案的总结,包括各种工厂模式(Factory、Abstract Factory)、单例模式(Singleton)、构建器模式(Builder)、原型模式(ProtoType)。
  • 结构型模式,是针对软件设计结构的总结,关注于类、对象继承、组合方式的实践经验。常见的结构型模式,包括桥接模式(Bridge)、适配器模式(Adapter)、装饰者模式(Decorator)、代理模式(Proxy)、组合模式(Composite)、外观模式(Facade)、享元模式(Flyweight)等。
  • 行为型模式,是从类或对象之间交互、职责划分等角度总结的模式。比较常见的行为型模式有策略模式(Strategy)、解释器模式(Interpreter)、命令模式(Command)、观察者模式(Observer)、迭代器模式(Iterator)、模板方法模式(Template Method)、访问者模式(Visitor)。
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值