今天又是被rua的一天,第一篇文章呢,就献给了设计模式!!
单例模式
说到设计模式,怎么能少得了单例! 特点:
- 单例类只能有一个实例
- 单例类必须给自己创建自己的唯一实例
- 单例类必须向外部提供这个实例对象
常见的单例有5种
- 饿汉式
- 懒汉式(线程不安全)
- 懒汉式(线程安全)
- 双重检查锁定
- 静态内部类
- 枚举单例
饿汉式
public class Singleton{
//构造函数
private Singleton(){
}
//在类初始化的时候就已经自行实例化,所以可以保证线程安全
private staticfinal Singleton single = new Singleton();
//通过getInstance获取实例对象
public static Singleton getInstance(){
return single;
}
}
**优点:**在类初始化的时候已经自行进行了实例化,所以可以保证线程安全
**缺点:**没有实现懒加载机制,如果没有使用这个实例会造成内存的浪费
懒汉式(线程不安全)
public class Singleton{
public static Singleton single = null;
private Singleton(){
}
public static Singleton getInstance(){
if(single == null){
single = new Singleton();
}
return single;
}
}
优点: 实现了懒加载的效果
缺点: 不能够保证并发访问时的单例
懒汉式(线程安全)
public class Singleton(){
private Singleton(){
}
private static Singleton single = null;
//synchronized关键字进行上锁
public static synchronized Singleton getInstance(){
if(single == null){
single = new Singleton();
}
return single;
}
}
优点: 实现了懒加载的机制,保证了线程的安全性
缺点: 使用synchronized关键字进行修饰,会造成不必要的内存开销,因为大多数情况下不会用到同步
双重检查锁定(DCL)
public class Singleton{
public volatile static Singleton single = null;
private Singleton(){
}
public static Singleton getInstance(){
//第一次检查,避免不必要的同步
if(single == null){
synchronized(Singleton.class){
//第二次检查,为null时才创建实例
if(single == null){
single = new Singleton();
}
}
}
retuen single;
}
}
优点: 懒加载,线程安全,避免了不必要的同步
缺点: volatile会对性能产生一定的影响,高并发的情况下会导致一些缺陷,而且小概率的情况下会导致DCL失效
静态内部类
public class Singleton{
private Singleton(){
}
public static Singleton getInstance(){
return SingletonHolder.mSingleton;
}
private static class SIngleHolder{
private static final mSIngleton = new Singleton();
}
}
优点: 懒加载,线程安全
一些避免对单例模式进行破坏的方法:
避免反射破坏
单例模式虽好,但是可以通过反射机制进行破坏,所以可以通过第二次调用构造函数时抛出异常防止单例模式进行破坏
public class Singleton {
private static boolean flag = true;
private static Singleton single = null;
private Singleton() {
if (flag) {
flag = !flag;
} else {
throw new RuntimeException("单例模式被破坏!");
}
}
public static Singleton getInstance() {
if (single == null) {
single = new Singleton();
}
return single;
}
}
避免反序列化破坏
public class Singleton implements Serializable {
private Singleton() {
}
private static final Singleton single = new Singleton();
public static Singleton getInstance() {
return single;
}
//重写readResolve()
private Object readResolve() throws ObjectStreamException {
//直接返回单例对象
return single;
}
}
Buidler模式
首先第一个就是建造者模式啦, 使用OkHttp进行网络交互的时候,就会创建一个OkHttpClient对象,或者是Request对象的时候都有用到,以及AlertDialog等等
OkHttpClient okHttpClient = new OkHttpClient.Builder();
那这个模式的好处在于:在创建一个复杂参数的时候,将其构造过程进行隔离,这样使得使用者只需要根据具体的需求来创建对象即可,不用关心其内部具体的构造过程以及细节。
优点
- 封装性良好,隐藏了内部实现细节
- 易于解耦,将对象本身与创建过程进行了一个解耦操作
缺点
- 当创建的对象过于复杂的时候就会导致其内部有很多的具体创建类来实现这种变化
责任链模式
请求沿着一个链条传递,直到在该链上的找到处理它的某个结点。事件分发机制或者是OkHttp拦截器链都是采用的这种设计模式。
介绍
- 对于多个对象而言,每个对象都持有下一个对象的引用,就构成了链式结构
- 责任链模式一般分为处理者和请求者两个角色。
场景应用
- 多个对象处理同一个请求的时候,但是具体由那个对象去处理需要运行时做判断
优点
- 易于代码的解耦,将请求者与处理者隔离开来
- 易于扩展,新增的处理者往链上添加新结点即可
缺点
- 责任链过长的话,或者链上的结点处理时间太长的话可能会影响性能
- 请求在遍历完所有的结点之后可能都得不到处理
好了,今天就先记录到这里,希望能够坚持下来。