本文是本人从事开发中学习到的一些Java知识,在这里共享给大家
Builder模式
我们都知道新建一个对象一般都是通过其构造方式产生,但是如果我们的类具有多个属性,我们就可能需要生成多个构造方法,去实现不同的需求。但是这样的方式明显是非常繁琐的。所以builder模式很好的解决了这一问题。builder模式根据不同的需求可以随意更改任意属性。(在Android开发中Dialog就是采用的这种方式,灵活的更改属性值,下面我们就以它为例)
1 | public class AndroidDialog { |
1 | public class AndroidDialog { |
通过上面两种方式的比较,我们可以明显的看出区别在哪儿,builder更适合那种参数多,自定义性强的类。下面是使用方法:
1 | AndroidDialog androidDialog = new AndroidDialog.Builder() |
getInstance()单例模式
单例模式,在我们的日常开发中当然随处可见。但是各种单例模式方式的实现各有不同。先简单介绍下单例模式的功能
序号 | 特点 |
---|---|
1 | 构造函数不对外开放,一般为private |
2 | 单例类必须自己创建自己的唯一实例 |
3 | 单例类必须给所有其他对象提供这一实例 |
实现单例模式的方式有很多。 我们来以逼格的等级来看看这里方式。
菜逼(简单暴力)
1 | public class Person { |
这种方式简单容易理解,但是缺点是线程是非安全的。比如线程同时执行getInstance()
,可能会同时创建出两个不同的对象。所以尽量在方法外面加上synchronized
。
当然你也可以使用该变量之前就将该变量进行初始化,这个是线程安全的,写法也很简单。
1 | public class Person { |
在程序启动时Person就会创建你的static instance,消耗资源(优点:启动快)。不推荐。
==注意我要开始装逼了==
刚刚提到使用synchronized
来加同步锁。看起来不错了,但是每次调用getInstance()
都需要synchronized
,似乎还可以改进。
1 | public class Person { |
看起来似乎不错,但是却存在着大BUG。 如果两个线程同时进入null判断。但是还没有进入synchronized
,那么这个时候肯定会排着队产生两个Person
。继续改善:
1 | public class Person { |
进入synchronized
再做判断,这样就可以避免同时产生两个对象了。是的吗? 好像还是不行。因为还有种可能线程1还在 new Person()
的过程中,这个时候线程2冲进来。这下就会返回一个没完全初始化好的Peson,程序必然报错。错误详情可参见 http://www.race604.com/java-double-checked-singleton/?hmsr=toutiao.io&utm_medium=toutiao.io&utm_source=toutiao.io
==看来装逼还得抓把劲==
这个时候我们需要引用volatile(自行百度,大致就是我没初始化完成,别人就拿不到这个对象)。
1 | public class Person { |
擦,这个逼终于装完了。
还没完, 据说这才是最高境界的装逼(哦 不,单例)。
1 | public enum Person { |
下次再有谁和你提单例,直接甩他一脸枚举。
是不是已经学会装逼(单例)了?
Adapter模式
对于Android开发者来说一定离不开各种Adapter
。那么这些adapter
是怎么来设计的呢?下面一起来探索一下。
首先我们来了解下Adapter
是一种什么模式,一般的来解释就是,将一种无法直接使用的东西,通过Adapter
来转换成我们需要的东西。(Android中将Model数据转换成视图),还有一种功能就是通过抛出统一的接口实现通用适配。(Android中listview
,gridview
都可以通过BaseAdapter
提供数据)
1 | ListView->Adapter: RecycleBin |
Android在继承BaseAdapter
中强制实现了,getCount
,getView
方法。我们知道这两个方法是必须填返回值的,否则视图无法展现。那么ListView
中setAdapter
后做了哪些操作使得Model数据能够展示在View上呢? 我们自己简单的新建一个横向ListView。 上车了。滴滴
1 | public class HorizontalView extends HorizontalScrollView{ |
注意:这里的BaseAdapter是我们自定义的
1 | /** |
这里我们只是为了了解基础的使用方法,所以就简单的定义了两个方法。下面该怎么做应该都清楚了。 只需继承BaseAdapter
实现其方法,就能够将我们的model数组根据下标设置到HorizontalView
上了。 不做解释了,上车
1 | protected void onCreate(Bundle savedInstanceState) { |
1 | public class TestAdapter extends BaseAdapter{ |
大家应该能看懂吧。这个ListView
就是这么设置Adapter的。这样我们在Adapter中将model数据绑定到视图上了。那么Adapter的转换功能就顺利完成了。下面就是for
循环将视图绑定到ListView
上了。
1 | public class HorizontalView extends HorizontalScrollView{ |
好吧。至此为止我们的横向listView已经打造好了。在过程中可以学习到adapter的大概工作模式(当然listView的数据绑定远远没有这么简单)。