[设计模式]单体模式及实现
单体模式解决的问题:
1. 描述问题域唯一存在的实体。这样很符合设计上的语意,便于理解设计模型。比如移动应用中的APP对象,就应该是单体,一个应用对应N个APP对象,从语意上就显得不合理。
2. 实现方案域只需要一份的对象。这样可能是为了符合语言,也可能是为了节省内存。
单体模式常见场景(现在临时想到的)
1. 应用配置。比如windows的注册表。
2. 全局唯一对象。比如移动应用中的APP.Andorid系统中的孵化器,资源管理器等等。
单体模式的实现:
在Head first设计模式一书中有非常易懂的介绍。实现单体模式,核心是要解决以下问题:
1. 对象的创建效率。
单体模式属于对象创建模式中的一种,当然需要一样关心对象创建的效率。对象创建效率提升的常见方式就是延时创建。就是虽然使用者申请了创建。单体本身可以告诉使用者已经创建了。但内部实际上没有创建。只有等到用户实际使用该对象的时候再创建。另外就是,一旦创建,就缓存起来,下次使用的时候,实际不用再进行任何创建工作。
2. 多线程并发下的对象创建。
并发问题,作为程序员永远无法回避。如果可以肯定不会存在并发,实现的时候,完全不用考虑并发问题,这样代码不但简单,也给review代码的人传递了不存在并发场景的信息。这样是非常合理的。
但是,更多时候是,我们忽略了并发场景。并发是很诡异的。如果需要解决并发问题,我觉得做尽量多的并发考虑是非常必要的。
public class Singleton {
private static volatile Singleton sl; //volatile是必要的,否则其他线程改变,无法及时同步给其他线程。
public static SingletongetInstance()
{
if(null == sl)
{
synchronized (Singleton.class)
{
if(null == sl) //这里必要的,当多个线程都在等待锁的时候,通过这个判断,可以避免重复创建对象。
{
sl = new Singleton();
return sl;
}
}
}
return sl;
}
}
在实现的时候,既要考虑效率,还要考虑并发,就已经很需要功底了。但还有个很多程序员容易忽略的情况是,支持效率和并发的操作系统/语言以及平台等因素。比如在head first中提到的,在不同的java版本上,对并发的支持力度是不同的。也许在最新平台的java上,不需要写这么复杂的代码,因为语言本身可能会更直观直接的支持并发场景。
所以,这片文章,更多地是抛出大家可能忽略的问题,以及可能存在的方案。但更重要的是给大家一个提醒。在设计和开发中可能需要考虑的问题。但解决问题的思路会有很多,也可以很简单。大胆假设,小心验证是必要的。