设计模式实例学习-单例模式(Android中的使用场景)
2015-11-17 10:37
585 查看
设计模式实例学习-单例模式
原创博客,转载请注明出处:http://blog.csdn.net/u011035622/article/details/49884327
定义
单例模式,故名思议,是指在一个类中通过设置静态使得其仅创造一个唯一的实例。这样设置的目的是满足开发者的希望——这个类只需要被实例化创建一次,同时因为其为静态的缘故,加载的速度也应该快于正常实例化一个类的速度(理论上)。
代码分析
在Android开发中,当我们需要创建一个唯一的Fragment的时候常常会用到这样的模式,没有代码的学习是虚无的,接下来亮代码学习:public class SelectFrame extends Fragment { private final static String selectFrameKey = "SFKey"; private static SelectFrame mSelectFrame; private ArrayList<String> frameList; public static SelectFrame getInstance(ArrayList<String> frameList){ if (mSelectFrame == null) { mSelectFrame = new SelectFrame(); } Bundle bundle = new Bundle(); bundle.putStringArrayList(selectFrameKey, frameList); mSelectFrame.setArguments(bundle); return mSelectFrame; } }
这是我在一个Fragment类里面定义的其中一部分,首先必须要定义一个自身的静态mSelectFrame。然后通过一个静态方法getInstance()来实例化这个mSelectFrame,很明显,这里通过判断其是否为空的方式,使得每一次我们使用getInstance的时候都返回的是同一个对象mSelectFrame。
getInstance方法中有时我们也会放入一些我们需要传递的参数,比如我这个方法中放入了一个List对象,然后直接在里面用Bundle装载这个List对象,原本我们可能是在外部来做这些操作的,然而现在却直接通过这个方法将数据传入的操作集成到了这个Fragment中,即减少了外部Activity的逻辑代码,也使得这个Fragment在复用的时候操作更方便。(再通过setArguments的方法保存数据)。
接下来看我们的onCreateView方法:
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { view = inflater.inflate(R.layout.select_frame_fragment, container, false); Bundle bundle = mSelectFrame.getArguments(); frameList = bundle.getStringArrayList(selectFrameKey); return view; }
这里我们就将从前面getInstance中setArguments保存下来的数据通过Fragment的getArguments方法重新将数据读取出来。这样就完成了我们的目的。
接下来就是在Activity中创建我们这个Fragment对象了:
selectFrameFrag = SelectFrame.getInstance(nameFrameThumbnail); fm.beginTransaction().add(R.id.fragment_frame_container, selectFrameFrag).commit();
(fm是FragmentManager)
这样就OK了。
单例模式分类
单例模式有两种创建方式,分别为饿汉式和懒汉式。饿汉式
饿汉式,故名思议,很饿,在一开始就直接创建了这个对象。刚刚上面那个例子就是懒汉式的。懒汉式
懒汉式,顾名思义,很懒,只有在你要调用它的时候,通过自己写的方法里面来对他实例化。代码区别
也许这么说会有一点不明白,然后其实只要看代码的这个地方:private static SelectFrame mSelectFrame;
上面这个代码,这里一开始定义自身的静态时,没有实例化它,那么就是个懒汉.然后只有在我调用getInstance方法的时候,才在里面对他进行实例化(new SelectFrame()).
然后我们再看看饿汉:
private static SelectFrame mSelectFrame = new SelectFrame();
在定义的时候就已经实例化了.
单例模式线程安全问题
单例模式毕竟就是像上面讲的这么简单。但需要注意的是,单例模式实例化对象时,饿汉式是线程安全的,而懒汉式是线程不安全的,我们一般会再懒汉式的getInstance方法中通过synchronized上锁。类似于这样:if (mSelectFrame == null) { synchronized (SelectFrame.class) { if (mSelectFrame == null) { mSelectFrame = new SelectFrame(); } } }
有人说为什么要用两个if(XX==null),这里是为了提高效率,只有一个也是可以的,但效率上大大减低,因为不是每一次调用的时候我们要判断他是否同步,应该是如果判断当前为null的话,我们就直接不让他进入了,不需要判断是否同步。只有满足第一个条件的时候,我们才需要用锁来判断它是否线程安全。(这里的意思也是说明if一条语句的判断速度当然比synchronized (SelectFrame.class)快。。)
另外,在我们使用单例模式的时候,有些人会去私有化这个类的构造方法,使得这个类只能通过自己写的getInstance()来创建。类似于这样:
private SelectFrame() { // 并不需要做什么,只需要将这个外面的public改成private就好了=。= }
这么一来外部就只能按我要求的方法来创建这个对象了。
在这里也基本将单例模式的使用基本讲完了,接下来还会继续写其他的设计模式的使用,如果有涉及到Android上的都会尽力用Android上的例子来讲,加深印象。
相关文章推荐
- java对世界各个时区(TimeZone)的通用转换处理方法(转载)
- java-注解annotation
- java-模拟tomcat服务器
- java-用HttpURLConnection发送Http请求.
- java-WEB中的监听器Lisener
- Android IPC进程间通讯机制
- Android Native 绘图方法
- Android java 与 javascript互访(相互调用)的方法例子
- 介绍一款信息管理系统的开源框架---jeecg
- 聚类算法之kmeans算法java版本
- java实现 PageRank算法
- PropertyChangeListener简单理解
- 插入排序
- 冒泡排序
- 堆排序
- 快速排序
- 二叉查找树