一般单例模式的意思是全局中只用一个实例。下面示范使用单例的两个比较好的案例。
⑴ 懒汉模式
/** 懒汉模式,双重校验锁
* Created by chenjk on 2018/8/6.
*/
public class Single {
//单例
private static voletite Single _instant;
//注意设置为private,私有模式,只有通过内部生成实例,保证内部构造函数不被访问,保持单例
private Single(Context context ){
}
/** 懒汉模式
* @param context
* @return
*/
public static Single getInstance(Context context){
if (_instant==null){
//这里注意要加锁,保证线性安全
synchronized (Single.class){
if(_instant==null){
_instant = new Single(context);
}
return _instant;
}
}
return _instant;
}
}
⑵ 饿汉模式
/** 饿汉模式
* Created by chenjk on 2018/8/6.
*/
public class HungrySingle {
private static HungrySingle _intant; //单例
//同时构造函数需要私有化
private HungrySingle(){
}
public static HungrySingle getInstance(Context context){
return Holer.hungrySingle;
}
static class Holer{
static HungrySingle hungrySingle = new HungrySingle();
}
}
说明:饿汉模式与懒汉模式的区别在于, * 懒汉模式在需要的时候才初始化出来,饿汉模式在进程启动的时候就创建了实例了。饿汉模式使用了内部类的形式,比在外部类去实例化更合理一些,因为你无法确定外部类是否被被动的加载出来,这个时候初始化实例对象就有点浪费内存了,具有那么一点优势所在,所以更推荐。单例应该被慎用,尽量减少内存的使用。分情况使用懒汉单例和饿汉单例。
构建者模式在android开发中尤为常见,也是我比较常用和比较喜欢的设计模式之一。比较在我们的AlerDialog当中,如下:
AlertDialog.Builder builder = new AlertDialog.Builder(MainApplication.getApplication());
AlertDialog alertDialog = builder.setMessage("测试")
.setCancelable(false)
.create();
构造者模式,可以根据你的需求构造你需要的一些信息出来,其他的为默认。我在设计mvp框架中model实现层的时候经常会用到构造者模式去设计,以满足一些类似接口的需求。还有我应用在构建生成普遍的dialog当中去快捷的生成dialog,不用每次都去创建一个dialog类。
class Model {
protected boolean isFromCache;
protected int cacheTime;
protected boolean isLoading;
private Model(boolean isFromCache, int cacheTime, boolean isLoading) {
this.isFromCache = isFromCache;
this.cacheTime = cacheTime;
this.isLoading = isLoading;
}
static class Buidler{
protected boolean isFromCache;
protected int cacheTime;
protected boolean isLoading;
public Buidler setCacheTime(int cacheTime) {
this.cacheTime = cacheTime;
return this;
}
public Buidler setLoading(boolean loading) {
isLoading = loading;
return this;
}
public Buidler setFromCache(boolean fromCache) {
isFromCache = fromCache;
return this;
}
public Model create(){
return new Model(isFromCache,cacheTime,isLoading);
}
}
}
使用方法:
public class TestModel {
public Model getModelInstance(){
Model model = new Model.Buidler()
.setCacheTime(10*1000)
.setFromCache(true)
.setLoading(true)
.create();
return model;
}
}
也许你见过很多代码,伴随着很多的if else,或者switch case,有些分得清的还好,有些阅读性很差,这时候策略者模式发挥作用了。策略者模式表现为做的同一件事,而用不同的方法去实现。现实中的使用场景也很多,比如你是个管理者,你下面有多个手下,上级把任务分配了给你。这时候你要做的是,指示你的下级去做什么事,然而这件事是抽象的,比较开发安卓,开发ios,这个工作由你指派,具体实现是在下级那里去实现。
首先,你是管理者,你要先明确你的职责,你想让他们干什么,这个是抽象的,所以定义一个接口,这里就让他们开发出一个产品。
public interface IDev {
Product develop();
}
定义产品
public class Product {
/**
* 产品
*/
private String product;
public Product(String product) {
this.product = product;
}
}
这里时候你就需要指派他们工作去做了。
public class Factory {
private IDev iDev;
// private String type;
public Factory(IDev iDev){
this.iDev = iDev;
}
// public void Factory(String type){
// this.type = type;
// }
public Product doWork(){
Product product = null;
// if ("ios".equals(type)){
// product = new Product("this is ios product");
// }else if ("android".equals(type)){
// product = new Product("this is android product");
// }else if ("web".equals(type)){
// product = new Product("this is web product");
// }else if ("pc".equals(type)){
// product = new Product("this is pc product");
// }
//假如这里有一千种方式,那么这里将很长,业务拓展修改也很麻烦,下面是策略者模式实现方式,具体实现由IDev实例去实现
product = iDev.develop();
return product;
}
}
大概的策略者模式的工作就做完成了,下面看看我们怎么去使用他。
public class TestDevProduct {
public List getMutilProduct(){
List productList = new ArrayList<>();
productList.add(new Factory(new AndroidDev()).doWork());
productList.add(new Factory(new IOSDev()).doWork());
productList.add(new Factory(new WebDev()).doWork());
return productList;
}
}
总结:如Factory的dowork方法所示,拓展性提高了很多,阅读性也很高。所以建议大家赶快学起来吧。
代理模式在android也比较常见,比如okhttp中插入拦截器就是用的代理模式。举个工作的例子,比如你个android开发者,到了中午了,你需要出去打饭和取钱,又想留在公司解决点没解决的bug。而你的ios开发者同事,到了中午了,他也需要打饭,取钱,这时候就可以让你ios同事代理你去打饭取钱,你是代理者,你的ios同事是被代理者。 你的ios同事接受了你的代理,但是他不甘愿把时间花在打饭取钱时间上,想留点时间去打游戏啊,就委托web同事去打饭取钱。android开发委托ios去做,ios是被代理者,ios又委托web同事去做,ios也是代理者。
第一步。
抽象个主题出来: 打饭、取钱
public interface ISubject {
/** 买饭
* @return 饭
*/
String buyFood();
/** 取钱
*
*/
void drawMoney();
}
第二步,以架构的角度,抽取一个的代理类基类(注意java单继承)
** 代理类抽象出来的基类
* Created by chenjk on 2018/8/7.
*/
public abstract class BaseSubject implements ISubject {
//被代理的类
public ISubject proxySubject;
protected BaseSubject(ISubject proxySubject){
this.proxySubject = proxySubject;
}
@Override
public String buyFood() {
if (proxySubject!=null){
return proxySubject.buyFood();
}
return null;
}
@Override
public void drawMoney() {
if (proxySubject!=null){
proxySubject.drawMoney();
}
}
}
定义android开发者。继承代理成为代理类
public class AndroidDeveloper extends BaseSubject {
protected AndroidDeveloper(ISubject proxySubject) {
super(proxySubject);
}
/**
* 除了让别人去买饭,取钱之后,我可以单独干我自己事。
*/
public void playGame(){
Log.i("tag","i want to play game");
}
}
定位ios开发者
* Created by chenjk on 2018/8/7.
*/
public class IOSDeveloper extends BaseSubject {
public IOSDeveloper(ISubject proxy){
super(proxy);
}
/**
* 出了买饭,取钱,我想自己空点时间去取钱
*/
public void doWork(){
Log.i("tag","I want to work");
}
}
定义web开发者,他只是个被代理者,真正的执行者
** 被代理类
* Created by chenjk on 2018/8/7.
*/
public class WebDeveloper implements ISubject {
@Override
public String buyFood() {
return "chiken";
}
@Override
public void drawMoney() {
Log.i("tag","$100000000");
}
}
让我们写个类是去测试
public class TestProxy {
private void testProxy(){
WebDeveloper webDeveloper = new WebDeveloper();
//ios买饭取钱,代理web开发去做
IOSDeveloper iosDeveloper = new IOSDeveloper(webDeveloper);
//android 买饭取钱,代理ios去做;
AndroidDeveloper developer = new AndroidDeveloper(iosDeveloper);
//最后让web开发去做
webDeveloper.buyFood();
webDeveloper.drawMoney();
}
}
观察者模式在android开发中比较常见,相信使用过eventbus的开发者对观察者模式并不陌生,运行的就是订阅/被订阅的观察者模式。像我们baseAdapter也是用了观察者模式通知数据变化的。 你可以使用系统提供的Observable和Observer,但是Observable是个类,由于单继承的限制,使用上难免会有限制,下面我将使用我的方式来实现广播
类似Observer,我们定义一个 类似Observer接口。如下,采用泛型的方式,支持可以收到的数据
/** 观察者抽象接口
* @note 可以收到监听的数据
* Created by chenjk on 2018/8/8.
*/
public interface IObserver{
void onChange(T data);
}
下面我们定义两个观察者,android开发观察者和ios开发观察者
public class AndroidDev implements IObserver {
@Override
public void onChange(String data) {
Log.i("data",data);
}
}
public class IOSDev implements IObserver {
@Override
public void onChange(String data) {
Log.i("data",data);
}
}
收到数据后他们将打印出收到的内容。
由于单继承的限制,使得我们在使用上不方便,我们将采用接口的方式取代Observable。如下
/** 被观察者抽象接口
* Created by chenjk on 2018/8/8.
*/
public interface IObserverable{
/**
* 订阅观察
* 定义能注册Obect类型
*/
boolean registObserve(IObserver o);
/** 取消订阅观察
* @param o
* @return
*/
boolean unRegistObserve(IObserver o);
/**
* 给所有订阅者发送通知
*/
void sendChange();
void sendChangWithData(T data);
}
接下定义被观察者
public class ChatManager implements IObserverable{
private List iObserverList;
@Override
public boolean registObserve(IObserver o) {
if (iObserverList==null){
iObserverList = new ArrayList<>();
}
return iObserverList.add(o);//把它加入观察者队列
}
@Override
public boolean unRegistObserve(IObserver o) {
if (iObserverList!=null){
return iObserverList.remove(o);
}
return false;
}
@Override
public void sendChange() {
for (IObserver iObserver:iObserverList){
iObserver.onChange("");
}
}
@Override
public void sendChangWithData(String data) {
for (IObserver iObserver:iObserverList){
iObserver.onChange("");
}
}
}
public class ChatManager implements IObserverable{
private List iObserverList;
@Override
public boolean registObserve(IObserver o) {
if (iObserverList==null){
iObserverList = new ArrayList<>();
}
return iObserverList.add(o);//把它加入观察者队列
}
@Override
public boolean unRegistObserve(IObserver o) {
if (iObserverList!=null){
return iObserverList.remove(o);
}
return false;
}
@Override
public void sendChange() {
for (IObserver iObserver:iObserverList){
iObserver.onChange("");
}
}
@Override
public void sendChangWithData(String data) {
for (IObserver iObserver:iObserverList){
iObserver.onChange("");
}
}
}
如果你觉得每次都要去写这些复杂的操作,我建议将这个作为一个基类,定义为 abstract class(这样就跟系统的Observable一样了。)