Android中所涉及的常用设计模式.docx

上传人:b****6 文档编号:8121138 上传时间:2023-01-28 格式:DOCX 页数:29 大小:26.47KB
下载 相关 举报
Android中所涉及的常用设计模式.docx_第1页
第1页 / 共29页
Android中所涉及的常用设计模式.docx_第2页
第2页 / 共29页
Android中所涉及的常用设计模式.docx_第3页
第3页 / 共29页
Android中所涉及的常用设计模式.docx_第4页
第4页 / 共29页
Android中所涉及的常用设计模式.docx_第5页
第5页 / 共29页
点击查看更多>>
下载资源
资源描述

Android中所涉及的常用设计模式.docx

《Android中所涉及的常用设计模式.docx》由会员分享,可在线阅读,更多相关《Android中所涉及的常用设计模式.docx(29页珍藏版)》请在冰豆网上搜索。

Android中所涉及的常用设计模式.docx

Android中所涉及的常用设计模式

Android中所涉及的常用设计模式

1、单例模式

概念:

Ensureaclasshasonlyoneinstance,andprovideaglobalpointofaccesstoit.

动态确保某一个类只有一个实例,而且自行实例化并向整个系统提供这个实例。

优点:

1.1、由于单例模式在内存中只有一个实例,减少了内存开销。

对于那些耗内存的类,只实例化一次,大大提高性能,尤其是移动开发中。

1.2、单例模式可以避免对资源的多重占用,例如一个写文件时,由于只有一个实例存在内存中,避免对同一个资源文件的同时写操作。

1.3、单例模式可以在系统设置全局的访问点,优化和共享资源访问。

[java]viewplaincopy在CODE上查看代码片派生到我的代码片

publicclassSingleton{

privatevolatilestaticSingletoninstance=null;

privateSingleton(){

}

publicstaticSingletongetInstance(){

if(instance==null){

synchronized(Singleton.class){

if(instance==null){

instance=newSingleton();

}

}

}

returninstance;

}

}

构造函数私有化,定义静态函数获得实例就不多说了,这里着重说一下volatile:

volatile本质是在告诉jvm当前变量在寄存器中的值是不确定的,需要从内存中读取,synchronized则是锁定当前变量,只有当前线程可以访问该变量,其他线程被阻塞住.(首先我们要先意识到有这样的现象,编译器为了加快程序运行的速度,对一些变量的写操作会先在寄存器或者是CPU缓存上进行,最后才写入内存.

而在这个过程,变量的新值对其他线程是不可见的.而volatile的作用就是使它修饰的变量的读写操作都必须在内存中进行!

synchronized

同步块大家都比较熟悉,通过synchronized关键字来实现,所有加上synchronized和块语句,在多线程访问的时候,同一时刻只能有一个线程能够用

synchronized修饰的方法或者代码块。

volatile

用volatile修饰的变量,线程在每次使用变量的时候,都会读取变量修改后的最的值。

volatile很容易被误用,用来进行原子性操作。

再就是这个双重判断null:

这是因为如果线程A进入了该代码,线程B在等待,这是A线程创建完一个实例出来后,线程B获得锁进入同步代码,实例已经存在,木有必要再创建一个,所以双重判断有必要。

Android中用到的地方很多,比如Android-Universal-Image-Loader中的单例,EventBus中的单例

最后给出一个管理我们activity的类,可以作为一个简单工具类

[java]viewplaincopy在CODE上查看代码片派生到我的代码片

publicclassActivityManager{

privatestaticvolatileActivityManagerinstance;

privateStackmActivityStack=newStack();

privateActivityManager(){

}

publicstaticActivityManagergetInstance(){

if(instance==null){

synchronized(ActivityManager.class){

if(instance==null){

instance=newActivityManager();

}

}

returninstance;

}

publicvoidaddActicity(Activityact){

mActivityStack.push(act);

}

publicvoidremoveActivity(Activityact){

mActivityStack.remove(act);

}

publicvoidkillMyProcess(){

intnCount=mActivityStack.size();

for(inti=nCount-1;i>=0;i--){

Activityactivity=mActivityStack.get(i);

activity.finish();

}

mActivityStack.clear();

android.os.Process.killProcess(android.os.Process.myPid());

}

}

单例模式在Android源码中的应用:

在Android源码中,使用到单例模式的例子很多,如:

InputMethodManager类

[html]viewplaincopy在CODE上查看代码片派生到我的代码片

publicfinalclassInputMethodManager{

staticfinalbooleanDEBUG=false;

staticfinalStringTAG="InputMethodManager";

staticfinalObjectmInstanceSync=newObject();

staticInputMethodManagermInstance;

finalIInputMethodManagermService;

finalLoopermMainLooper;

创建唯一的实例staticInputMethodManagermInstance;

[html]viewplaincopy在CODE上查看代码片派生到我的代码片

/**

*RetrievetheglobalInputMethodManagerinstance,creatingitifit

*doesn'talreadyexist.

*@hide

*/

staticpublicInputMethodManagergetInstance(Contextcontext){

returngetInstance(context.getMainLooper());

}

/**

*Internally,theinputmethodmanagercan'tbecontext-dependent,so

*wehavethisherefortheplacesthatneedit.

*@hide

*/

staticpublicInputMethodManagergetInstance(LoopermainLooper){

synchronized(mInstanceSync){

if(mInstance!

=null){

returnmInstance;

}

IBinderb=ServiceManager.getService(Context.INPUT_METHOD_SERVICE);

IInputMethodManagerservice=IInputMethodManager.Stub.asInterface(b);

mInstance=newInputMethodManager(service,mainLooper);

}

returnmInstance;

}

防止多线程同时创建实例:

synchronized(mInstanceSync){

if(mInstance!

=null){

returnmInstance;

}

当没有创建实例对象时,调用mInstance=newInputMethodManager(service,mainLooper);

其中类构造函数如下所示:

[html]viewplaincopy在CODE上查看代码片派生到我的代码片

InputMethodManager(IInputMethodManagerservice,Looperlooper){

mService=service;

mMainLooper=looper;

mH=newH(looper);

mIInputContext=newControlledInputConnectionWrapper(looper,

mDummyInputConnection);

if(mInstance==null){

mInstance=this;

}

}

2、建造者模式(Builder模式)

定义:

将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示

概念就是比较抽象的,让大家很难理解的,如果简单从这个一个概念就搞懂了这个模式的话,那就不用费力的去查资料整理后边的东西了。

这里我们通过一个例子来引出Build模式。

假设有一个Person类,他的一些属性可以为null,可以通过这个类来构架一大批人

[java]viewplaincopy在CODE上查看代码片派生到我的代码片

publicclassPerson{

privateStringname;

privateintage;

privatedoubleheight;

privatedoubleweight;

publicStringgetName(){

returnname;

}

publicvoidsetName(Stringname){

this.name=name;

}

publicintgetAge(){

returnage;

}

publicvoidsetAge(intage){

this.age=age;

}

publicdoublegetHeight(){

returnheight;

}

publicvoidsetHeight(doubleheight){

this.height=height;

}

publicdoublegetWeight(){

returnweight;

}

publicvoidsetWeight(doubleweight){

this.weight=weight;

}

}

然后为了方便,你可能会写这么一个构造函数来传属性

[java]viewplaincopy在CODE上查看代码片派生到我的代码片

publicPerson(Stringname,intage,doubleheight,doubleweight){

this.name=name;

this.age=age;

this.height=height;

this.weight=weight;

}

或者为了更方便还会写一个空的构造函数

[java]viewplaincopy在CODE上查看代码片派生到我的代码片

publicPerson(){

}

有时候还会比较懒,只传入某些参数,又会来写这些构造函数

[html]viewplaincopy在CODE上查看代码片派生到我的代码片

publicPerson(Stringname){

this.name=name;

}

publicPerson(Stringname,intage){

this.name=name;

this.age=age;

}

publicPerson(Stringname,intage,doubleheight){

this.name=name;

this.age=age;

this.height=height;

}

于是就可以来创建各种需要的类

[html]viewplaincopy在CODE上查看代码片派生到我的代码片

Personp1=newPerson();

Personp2=newPerson("张三");

Personp3=newPerson("李四",18);

Personp4=newPerson("王二",21,180);

Personp5=newPerson("麻子",16,170,65.4);

其实这种写法的坏处在你写的过程中想摔键盘的时候就该想到了,既然就是一个创建对象的过程,怎么这么繁琐,并且构造函数参数过多,其他人创建对象的时候怎么知道各个参数代表什么意思呢,这个时候我们为了代码的可读性,就可以用一下Builder模式了

给Person类添加一个静态Builder类,然后修改Person的构造函数,如下:

[java]viewplaincopy在CODE上查看代码片派生到我的代码片

publicclassPerson{

privateStringname;

privateintage;

privatedoubleheight;

privatedoubleweight;

privatePerson(Builderbuilder){

this.name=builder.name;

this.age=builder.age;

this.height=builder.height;

this.weight=builder.weight;

}

publicStringgetName(){

returnname;

}

publicvoidsetName(Stringname){

this.name=name;

}

publicintgetAge(){

returnage;

}

publicvoidsetAge(intage){

this.age=age;

}

publicdoublegetHeight(){

returnheight;

}

publicvoidsetHeight(doubleheight){

this.height=height;

}

publicdoublegetWeight(){

returnweight;

}

publicvoidsetWeight(doubleweight){

this.weight=weight;

}

staticclassBuilder{

privateStringname;

privateintage;

privatedoubleheight;

privatedoubleweight;

publicBuildername(Stringname){

this.name=name;

returnthis;

}

publicBuilderage(intage){

this.age=age;

returnthis;

}

publicBuilderheight(doubleheight){

this.height=height;

returnthis;

}

publicBuilderweight(doubleweight){

this.weight=weight;

returnthis;

}

publicPersonbuild(){

returnnewPerson(this);

}

}

}

从上边代码我们可以看到我们在Builder类中定义了一份跟Person类一样的属性,通过一系列的成员函数进行赋值,但是返回的都是this,最后提供了一个build函数来创建person对象,对应的在Person的构造函数中,传入了Builder对象,然后依次对自己的成员变量进行赋值。

此外,Builder的成员函数返回的都是this的另一个作用就是让他支持链式调用,使代码可读性大大增强

于是我们就可以这样创建Person对象

[java]viewplaincopy在CODE上查看代码片派生到我的代码片

Person.Builderbuilder=newPerson.Builder();

Personperson=builder

.name("张三")

.age(18)

.height(178.5)

.weight(67.4)

.build();

是不是有那么点感觉了呢

Android中大量地方运用到了Builder模式,比如常见的对话框创建

[java]viewplaincopy在CODE上查看代码片派生到我的代码片

AlertDialog.Builderbuilder=newAlertDialog.Builder(this);

AlertDialogdialog=builder.setTitle("对话框")

.setIcon(android.R.drawable.ic_dialog)

.setView(R.layout.custom_view)

.setPositiveButton(R.string.positive,newDialogInterface.OnClickListener(){

@Override

publicvoidonClick(DialogInterfacedialog,intwhich){

}

})

.setNegativeButton(R.string.negative,newDialogInterface.OnClickListener(){

@Override

publicvoidonClick(DialogInterfacedialog,intwhich){

}

})

.create();

dialog.show();

其实在java中StringBuilder和StringBuffer都用到了Builder模式,只不过是稍微简单一点了

Gson中的GsonBuilder

[java]viewplaincopy在CODE上查看代码片派生到我的代码片

GsonBuilderbuilder=newGsonBuilder();

Gsongson=builder.setPrettyPrinting()

.disableHtmlEscaping()

.generateNonExecutableJson()

.serializeNulls()

.create();

网络框架OKHttp

[html]viewplaincopy在CODE上查看代码片派生到我的代码片

Request.Builderbuilder=newRequest.Builder();

Requestrequest=builder.addHeader("","")

.url("")

.post(body)

.build();

可见大量框架运用了Builder设计模式,总结一下吧:

定义一个静态内部类Builder,内部成员变量跟外部一样

Builder通过一系列方法给成员变量赋值,并返回当前对象(this)

Builder类内部提供一个build方法方法或者create方法用于创建对应的外部类,该方法内部调用了外部类的一个私有化构造方法,该构造方法的参数就是内部类Builder

外部类提供一个私有化的构造方法供内部类调用,在该构造函数中完成成员变量的赋值

3、观察者模式

定义:

Defineaone-to-manydependencybetweenobjectssothatwhenoneobjectchangesstate,allitsdependentsaernotifiedandupdatedautomatically.

定义对象间一种一对多的依赖关系,使得当一个对象改变状态,则所有依赖于它的对象都会得到通知并被自动更新。

主要包括四个部分:

  1.Subject被观察者。

是一个接口或者是抽象类,定义被观察者必须实现的职责,它必须能偶动态地增加、取消观察者,管理观察者并通知观察者。

  2.Observer观察者。

观察者接收到消息后,即进行update更新操作,对接收到的信息进行处理。

  3.ConcreteSubject具体的被观察者。

定义被观察者自己的业务逻辑,同时定义对哪些事件进行通知。

  4.ConcreteObserver具体观察者。

每个观察者在接收到信息后处理的方式不同,各个观察者有自己的处理逻辑。

这个好像还好理解那么一点点,不过还是先来讲个情景,

天气预报的短信服务,一旦付费订阅,每次天气更新都会向你及时发送

其实就是我们无需每时每刻关注我们感兴趣的东西,我们只需要订阅它即可,一旦我们订阅的事务有变化了,被订阅的事务就会即时的通知我们

我们来看一下观察者模式的组成:

观察者,我们称它为Observer,有时候我们也称它为订阅者,即Subscriber

被观察者,我们称它为Observable,即可以被观察的东西,有时候还会称之为主题,即Subject

至于观察者模式的具体实现,java里为我们提供了Observable类和Observer接口供我们快速实现该模式,但是这里为了加深印象,不用这个两个类

我们来模拟上边的场景,先定义一个Weather的类

[java]viewplaincopy在CODE上查看代码片派生到我的代码片

publicclassWeather{

privateString

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 高等教育 > 工学

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1