Android开发中的设计模式实践理解(一)

原创 2016年08月29日 21:29:28
以文本和思维导图的方式简明扼要的介绍了GoF的23个经典设计模式,可当成学习设计模式的一个小手册,偶尔看一下,说不定会对大师的思想精髓有新的领悟。
GoF(“四人帮”,又称Gang of Four,即Erich Gamma, Richard Helm, Ralph Johnson & John Vlissides)
设计模式是在软件开发过程中,对于一些普适需求总结的设计模板。根据目的可以分为三类:
(1).创建型:与对象的创建相关。
(2).结构型:处理类或者是对象的组合。
(3).行为型:对类或者对象怎么进行交互,怎样分配职责进行描述。
需要注意:设计模式只是提供一种思路,能够直接套用的情况不多,更多的是处理问题的思路。


面向对象的六大原则
(1)单一职责原则:就一个类而言,应该仅有一个引起它变化的原因。关键是职责划分
(2)开闭原则:软件中的对象(类·模块·函数)应该对扩展是开放的,对于修改是封闭的。关键是通过抽象实现。
(3)里式替换原则:所以引用基类的地方必须能透明的使用其子类替换。依赖继承与多态特性。
(4)依赖倒置原则:模块间的依赖通过抽象发生,实现类之间不发生直接的依赖关系,其依赖关系通过接口或抽象类产生的。
(5)接口隔离原则:客户端不应该依赖它不需要的接口。类间的依赖关系应该建立在最小的接口上。接口隔离原则将非常庞大,臃肿的接口拆分成更小的和更具体的接口,这样客户端只需要关注他们感兴趣的方法。
(6)迪米特原则【最少知识原则】:一个对象应该对其他对象有最少的了解。一个类应该最自己需要耦合或调用的类知道的最少,类的内部如何实现与调用者或依赖者没关系,调用者或者依赖者只需要知道它需要的方法即可。

1.单例模式-应用最广的模式
定义:确保某一个类只有一个实例,而且自行实例化并向整个系统提供这个实例。
实现单例模式主要有以下几个关键点:
(1)构造函数不对外开放,一般为private。
(2)通过一个静态方法或者枚举返回单例类对象。
(3)确保单例类的对象有且只有一个,特别是在多线程环境下。
(4)确保单例类对象在反序列化时不会重新构建对象。

实现方式:
(1)饿汉模式:默认初始化一个自身的静态对象,对外的静态方法每次返回该实例。
(2)懒汉模式:静态方法加同步锁,第一次调用时,如果该实例为空,才会构造。每次调用都同步,造成不必要开销。
(3)Double Check Lock(DCL)双重检查锁定。
     if(mInstance==null){
           synchronized(Instance.class){
            if(mInstance==null){
                mInstance=new Instance();
            }
           }
      }
这个关键在与进行了2此mInstance判空,加了类同步锁。由于java编译器允许处理器乱序执行。因此在1.6以下或者并发场景比较复杂时不推荐。这是我们平时用的最多的一种方式。
(4)静态内部类单例模式:
这种方式只在第一次调用静态方法时,才会导致其静态内部类加载到虚拟机,初始化对象。不仅能够保证线程安全,也能够保证单例对象的唯一性,同时延迟了单例的实例化,所以是推荐使用的实现方式。
(5)枚举单例:枚举实例的创建时线程安全的,并且在任何情况下都是一个单例
(6)使用容器实现单例模式:将多种单例类型注入到统一管理器中,根据key获取。

序列化相关:
通过序列化可以将一个单例的实例对象写到磁盘,然后读回来,从而有效获得一个实例。
即使构造函数是私有的,反序列化依然尅通过特殊的途径去创建类的一个实例,相当于调用该类的构造函数。
反序列化操作提供了一个很特别的钩子函数,类中具有一个私有,被实例化得方法readResolve(),这个方法可以让开发人员控制对象的反序列化。
要杜绝单例被反序列化重新生成对象,必须加入如下方法:

private  Object readResolve() throws ObjectStreamException{
 return mInstance;
}

也就是在readResolve方法中将,mInstance返回,而不是默认重新生成一个对象。枚举不存在这个问题。

优点:
(1)单例模式在内存中只有一个实例,减少内存开支,特别一个对象模块需要频繁创建销毁,而创建销毁时性能又无法优化,单例模式就非常有用。
(2)单例模式可以在系统设置全局的访问点,优化和共享资源访问。
(3)利用单例模式可以避免对资源的多重占用,解决线程安全,统一解决访问问题
缺点:
(1)单例模式没有接口,扩展困难。只能修改源码。
(2)单例对象如果持有context容易引发内存泄漏,此时需要注意传递给单例对象的context最好是Application的context。

2.建造者模式-Builder
定义:将一个复杂对象的构建和表示分离,使得同样的构造过程创建不同的表示结果。
使用:实际开发中,我们一般是直接使用一个builder来进行对象的组装,里面全部是构造或者表示的参数,我们可以设置链式调用,关键点是每个setter方法返回自身,return this;这样就可以链式调用。
AlertDialog.Builder的实现,就是为了构建复杂的AlertDialog,将dialog的构造和表示分开。
这个的使用,在开源项目中比较常见,比如Universal image loader中,通过将ImageLoaderConfig的构造函数,字段私有化,使得外部不能访问内部属性,用户只能通过设计Builder对象的属性,通过Builder构造出ImageLoaderConfig对象,这样就实现构造和表示的分离。

通过配置类的构造器Builder将配置的构造和表示分离开来,同时又将配置从目标类中隔离处理,避免过多的setter方法污染目标类。以及方便的链式调用。

优点:
(1)良好封装性,使用建造者模式可以是客户端不必知道产品内部组成的细节。
(2)构造者独立,容易扩展。
缺点:
产生多余的Builder对象,消耗内存。

3.原型模式-使程序运行更高效
定义:用原型实例,指定创建对象的种类,并通过拷贝这些原型创建新的对象。
使用场景:
(1)类初始化需要消耗非常多的资源,这个资源包括数据,硬件资源等,通过原型靠包避免这些消耗。
(2)通过new产生一个对象需要非常繁琐的数据准备或者访问权限,这是可以使用原型模式。
(3)一个对象需要提供给其他对象访问,而且各个调用者可能读需要修改其值时,可以考虑使用使用原型模式拷贝多个对象供调用者使用,即保护性拷贝。
注意:
(1)通过实行Cloneable接口的原型模式在调用clone函数构造实例时并不一定比new操作更快,只有当通过new构造对象较为耗时或者成本较高时,才能获得效率提升。
(2)clone()方法并不是Cloneable接口中的,而是Object中的方法,,Cloneable是一个标识接口,它表明这个类的对象是可拷贝的,如果没有实现Cloneable接口,但是调用了clone()函数将抛出异常。所以我们一般的都是实现Cloneable接口,覆些clone()方法实现对象的拷贝实现,来实现原型模式。
(3)通过clone拷贝对象时不会执行构造函数。在使用Cloneable实现拷贝的时候,是调用了clone()方法实现,对象的构造韩式是不会执行的。如果构造函数中需要一些特殊初始化,可能发生问题。
(4)深拷贝与浅拷贝:区别在于拷贝对象时,深拷贝对引用型的字段同样采用拷贝的方法。浅拷贝只是单纯拷贝引用的形式。对于引用类型的,如果只是拷贝应用,那么调用者会连原型对象的值一起改变,因为他们引用的最终指针地址是一处。而深拷贝,引用类型的会有新地址内存。

intent就是原型模式。
public Object clone(){
return new Intent(this);
}
只不过它是new比clone效率高,所以内部这么实现。
比如平时应用比较多的,应该是保护性拷贝。
比如订单提交界面,服务器接口,要求在提交的数据里进行一些特定操作,会修改订单数据。但是修改了这些数据在本地显示就会有一些问题,或者上一次提交网络异常,重新提交是原型数据发生了改变。
这种情况,我们就应该讲本地初始数据,当作原型,深拷贝对象给其他调用者去处理,对应流程,那么流程异常后,回退,原型数据是不变的,我们可以继续对原型数据修改,后继续提交等其他处理操作。

优点:
原型模式是在内存中二进制流的拷贝,要比直接new一个对象性能好很多,特别是在一个循环体内产生大量对象时,原型模式可以更好的体现其优点。
缺点:
直接在内存中执行,构造函数不会执行,实际开发中要注意这一点。

4工厂方法模式-应用最广泛的模式 
版权声明:本文为博主原创文章,未经博主允许不得转载。

MVP模式在Android开发中的最佳实践

这篇文章拖了好久了,一直存在草稿箱里没有继续写,趁几天有空,撸撸完。回想一下,你刚刚学习Android的时候,总会看到一些书上写着,Android使用的是MVC模式,Activity就是一个Contr...
  • sbsujjbcy
  • sbsujjbcy
  • 2016年02月21日 13:47
  • 5154

【学习笔记javascript设计模式与开发实践----1】

个人吐槽 读了不少的关于js的基础书箱,有必要在js的编码结构和编码效率上有所提高(个人资质很差,所以只代表个人观点。如有说的不对的,还请大神们见谅……),个人一直觉得,不会用设计模式不代表你就不是一...
  • pigpigpig4587
  • pigpigpig4587
  • 2015年09月21日 18:09
  • 2144

Android开发MVP模式实践

现在用一个基于MVP模式的APP项目进一步分析MVP的实际ying
  • guxiao1201
  • guxiao1201
  • 2014年10月16日 17:14
  • 24351

从设计模式开android开发

  • 2012年05月06日 15:30
  • 768KB
  • 下载

Android开发常用的设计模式

、  下面每一种设计模式,都开一篇来写: 开发常用模式:单利模式; Build模式(建造者模式); 观察者模式; 原型模式; 策略模式; 工厂模式; 代理模式; 装饰者模式; 适配器模式; 组合模式;...
  • u014769864
  • u014769864
  • 2017年09月25日 17:13
  • 185

Android开发中常用的设计模式初步解析

15·常用的设计模式单例设计模式 所谓单例设计模式简单说就是无论程序如何运行,采用单例设计模式的类(Singleton类)永远只会有一个实例化对象产生。具体实现步骤如下: (1) 将采用单例设...
  • u012301501
  • u012301501
  • 2016年12月12日 21:50
  • 170

Android开发中常用到的设计模式

单例模式保证一个类仅有一个实例,并提供一个访问它的全局访问点。热门词汇:单例 唯一 私有构造单例模式好处 由于单例模式在内存中只有一个实例,减少了内存开销。对于那些耗内存的类,只实例化一次,大大提高性...
  • johnWcheung
  • johnWcheung
  • 2017年06月12日 20:49
  • 283

【博客试用】【转】Android开发之Java设计模式基础篇

【博客试用】今天我们就Android开发中的一些设计模式做一些基础性的掌握,在上一次的 Android开发之Java设计模式入门篇 中我们提到了一些有关 Java基础内容,本次就Android项目的架...
  • stevenwwin
  • stevenwwin
  • 2012年02月22日 15:54
  • 192

Android开发设计模式05

策略模式其实特别简单(听到这句话,大家是不是心里一下子放松了?)。 比如排序,官方告诉大家我这里有一个排序的接口ISort的sort()方法,然后民间各尽其能,实现这个排序的方法:冒泡,快速,堆等等...
  • Mr_Data_Mining
  • Mr_Data_Mining
  • 2013年11月25日 11:02
  • 955

Android开发之Java设计模式

对于很多c/c++程序员初入android开发来说,如果你没有认证学习过java的设计模式,不理解托管语言的oop设计方法,可能你的应用变得很结构化,对于项目管理、架构扩展来说将会存在很多问题,and...
  • javazhuanzai
  • javazhuanzai
  • 2012年01月10日 07:24
  • 188
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:Android开发中的设计模式实践理解(一)
举报原因:
原因补充:

(最多只允许输入30个字)