谈谈你知道的设计模式?手动实现单例模式,Spring 框架中使用了哪些设计模式?
大致按照模式的应用目标分类,设计模式可以分为创建型模式、结构型模式和行为型模式。
创建型模式是对对象创建过程的各种问题和解决方案的总结,包括各种工厂模式(Factσry、 Abstract factory)、单例模式(siη geton、构建器模式( Builder) 原型模式(ProtoType)
结构型模式是针对软件设计结构的总结,关注于类、对象继承、组合方式的实践经验。常见的结构型模式,包括桥接模式( Bridge)、适配器模式( Adapter)、装饰者模式 ( Decorator)、代理模式( Proxy)、组合模式( Composite)、外观模式( Facade)、享元模式( Flyweight)等。
行为型模式是从类或对象之间交互、职责划分等角度总结的模式。比较常见的行为型模式有策略模式( stratτegγ)、解释器模式( Interpreter)、命令模式( Commaηd观察者模式( observer)、迭代器模式( (Iterator)、模板方法模式( Template Method)、访问者模式( Visitor)。分析这个问题主要是考察你对设计模式的了解和掌握程度,更多相关内容你可以参考:
装饰器模式本质上是包装同类型实例,我们对目标对象的调用,往往会通过包装类覆盖过的方法,调用被包装的实例,这就可以很自然地实现增加额外逻辑的目的,也就是所谓的装饰"。
image
BufferedInputstream经过包装,为输入流过程增加缓存,类似这种装饰器还可以多断地增加不同层次的功能
public BufferedInputstream(Inputstream in)
image
创建型模式尤其是工厂模式,在我们的代码中随处可见,比如 Log4j2 中日志打印过程,就是典型的构建器模式(Builder),通常会被实现成 fluent风柊的API,也有人叫它方法链。
Log.newLog(false).keyword(null, null).keyword(map).keyword("key1", "val2").add("a").getMessage()
实现一个日常非常熟悉的单例设计模式。看起来似乎很简单,那么下面这个样例符合基本需求吗?
public class Singleton {
private static Singleton instance = new Singleton();
public static Singleton getInstance(){
return instance;
}
}
这样的实现有什么问题?可以完全不需要 getInstance() 声明出一个对象,完全可以使用 new Singleton() 方式 声明出一个对象。上面的这个方式,并不能保证单例。 那怎么办,为了避免声明出多个对象,可以声明一个 private 的构造函数。
public class Singleton {
private static Singleton instance = new Singleton();
private Singleton() {
}
public static Singleton getInstance(){
if (instance == null){
instance = new Singleton();
}
return instance;
}
}
上面的实现是否有问题呢?我们考虑一个并发的场景,多个线程在判断 instance = null 时,就会出现多个 Singleton 实例,并发场景也不能保证单例。怎么办呢,采用“双检锁”。
public class Singleton {
private static volatile Singleton instance = new Singleton();
private Singleton() {
}
public static Singleton getInstance(){
if (instance == null){// 避免重复进入同步块
synchronized(Singleton.class){
if(instance == null){
instance = new Singleton();
}
}
}
return instance;
}
}
这里说下 Java 核心类库的单例实现 java.lang.Runntime
private static final Runtime currentRuntime = new Runtime();
private static Version version;
public static Runtime getRuntime() {
return currentRuntime;
}
private Runtime() {}
当然还有一种,使用静态内部类的方式实现单例模式,写法比较晦涩。
public class singleton {
private Singleton(){}
public static singleton getsingleton(){
return Holder.singleton
}
private static class Holder {
private Static Singleton singleton new Singleton();
}