常见设计模式汇总介绍
设计模式在平时的工程实践中非常重要,一个好的设计模式可以让工程结构更加简单、可扩展性更强、维护性高。下面介绍几种常用的设计模式。
1.单例模式
1.1 懒汉模式
1.2 Double Check Lock实现单例
1.3 静态内部类实现单例
1.4 枚举实现单例
1.5 使用容器实现单例2.Builder模式
3.观察者模式
4.代理模式
5.MVC/MVP/MVVM架构
1.单例模式
单例模式确保一个类中只有一个实例,而且自行实例化并向整个系统提供这个实例。
适用场景:确保某个类有且只有一个对象的场景,避免产生多个对象消耗过多的资源,或者某种类型的对象只应该有一个,例如,创建一个对象需要消耗资源过多,如要访问IO和数据库等资源,这时候要考虑使用单例模式。
1.1 懒汉模式
public class Singleton {
private static Singleton instance;
private Singleton() {}
public static synchronized Singleton getInstance() {
if(instance == null) {
instance = new Singleton();
}
return instance;
}
}
优点:单例只有在使用的时候才会被实例化,在一定程度上节约资源。
缺点:第一次加载需要及时实例化,反应慢;每次调用getInstance都进行同步,造成不必要的同步开销。
1.2 Double Check Lock实现单例
public class Singleton {
private volatile static Singleton instance = null;
private Singleton() {}
public static Singleton getInstance() {
if(instance == null) {
synchronized(Singleton.class) {
if(instance == null) {
instance = new Singleton();
}
}
}
return instance;
}
}
优点:资源利用率高,第一次执行getInstance时单例才会实例化,效率高。
缺点:第一次加载反应慢,而且由于Java内存模型可能会失败;高并发下效率较低。
1.3 静态内部类实现单例
public class Singleton {
private Singleton() {}
public static Singleton getInstance() {
return SingletonHolder.sInstance;
}
private static class SingletonHolder {
private static final Singleton sInstance = new Singleton();
}
}
第一次调用getInstance方法会导致虚拟机加载SingletonHolder类,这种方式不仅能够确保线程安全,也能够保证单例对象的唯一性,同时也延迟了单例的实例化。
1.4 枚举实现单例
public enum SingletonEnum {
INSTANCE;
private Singleton instance;
private SingletonEnum() {
instance = new Singleton();
}
public Singleton getInstance() {
return instance;
}
}
SingletonEnum.INSTANCE.getInstance();
优点:写法简单,而且在反序列化的时候不会重新创建的对象,上面几种单例方法在反序列化时会重新创建对象。
1.5 使用容器实现单例
public class SingletonManager {
private static Map<String, Object> objMap = new HashMap<String, Object>();
private SingletonManager() {}
public static void registerService(String key, Object instance) {
if (!objMap.containsKey(key)) {
objMap.put(key, instance);
}
}
public static Object getService(String key) {
return objMap.get(key);
}
}
2.Builder模式
Builder模式是将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。
Builder模式是一步一步创建一个复杂对象的创建型模式,它允许用户在不知道内部构建细节的情况下,更精细地控制对象的构造流程。该模式是为了将构建复杂对象的过程和它的不见解耦,使得构建过程和部件的表示隔离开来。
优点:良好的封装性,使用建造者模式可以使客户端不必知道产品内部组成的细节;建造者独立,容易扩展。
缺点:会产生多余的Builder对象以及Director对象,消耗内存。
ImageLoaderConfig中的代码。
private void initImageLoader() {
ImageLoaderConfig config = new ImageLoaderConfig.Builder()
.setLoadingPlaceholder(R.drawable.loading)
.setNotFoundPlaceholder(R.drawable.not_found)
.setCache(new DoubleCache(this))
.setThreadCount(4)
.setLoadPolicy(new ReversePolicy()).create();
ImageLoader.getInstance().init(config);
}
3.观察者模式
定义:观察者模式是定义对象间一种一对多的依赖关系,使得每当一个对象改变状态,则所有依赖于它的对象都会受到通知并被自动更新。
使用场景:
observer.jpg
- 1.关联行为场景,需要注意的是,关联行为是可拆分的,不是组合关系。
- 2.事件多级触发场景。
- 3.跨系统的消息交换场景,如消息队列、事件总线的处理机制。
4.代理模式
定义:代理模式是为其他对象提供一种代理以控制对这个对象的访问。
使用场景:当无法或不想直接访问某个对象或访问某个对象存在困难时可以通过一个代理对象来间接访问,为了保证客户端使用的透明性,委托对象与代理对象需要实现相同的接口。
外人想调用RealSubject中的visit()方法,但不会直接通过RealSubject对象,会通过ProxySubject对象来实现代理访问RealSubject中的visit()方法。这就是代理问题的核心。
5.5.MVC/MVP/MVVM架构
比较MVC/MVP/MVVM三种架构很好的分析文章:
MVC、MVP、MVVM架构分析与比较