由于项目变更的频繁性,作为一名程序猿,我们须要掌握设计模式的必要性。就不言而喻~~。以下就是一些我自己学习的设计模式总结。
接下来,主要是针对几个比較经常使用模式进行解说,主要是以下几种:

  • 观察者模式
  • 适配器模式
  • 代理模式
  • 工厂模式
  • 单例模式
  • 命令模式

1.观察者模式(Observer Pattern)
释义:观察者模式定义了一种一对多的依赖关系,让多个观察者对象同一时候监听某一个主题对象,这个主题对象在状态上发生变化时,会通知全部观察者对象,使他们能够自己主动更新自己。
故事理解:观察者想知道公司全部MM的情况,仅仅要增加公司的MM情报邮件组即可了,tom负责搜集情报,当发现新情报时,不用一个一个通知我们,直接公布给邮件组。我们作为订阅者(观察者)就能够及时收到情报啦。
常见实例:1.BaseAdapter.registerDataSetObserver和BaseAdapter.unregisterDataSetObserver双方法来向BaseAdater注冊、注销一个DataSetObserver ; 2.使用ContentObserver去监听数据库变化。

适用场景:1.当对一个对象的改变须要同一时候改变其它对象,而不知道详细有多少对象有待改变。2.当一个对象必须通知其它对象。而它又不能假定其它对象是谁.

观察者模式主要有观察者和被观察者2个对象。在该模式中。Observable表示被观察者,这个对象是一个抽象类。仅仅能被继承。 Observer表示观察者,他是一个接口。所以观察者能够有多个。实现了该接口的类都是属于观察者。
这是网上一个生动仔细的demo:
被观察者:

public class MyPerson extends Observable {private int age;private String name;private String sax;public int getAge() {return age;}public void setAge(int age) {this.age = age;setChanged();notifyObservers();}public String getName() {return name;}public void setName(String name) {this.name = name;setChanged();notifyObservers();}public String getSax() {return sax;}public void setSax(String sax) {this.sax = sax;}@Overridepublic String toString() {return "MyPerson [age=" + age + ", name=" + name + ", sax=" + sax + "]";}
}

MyPerson是被观察者,类中调用了setChange()以及notifyObservers()两个方法。前者是告知数据改变,后者是发送信号通知观察者。

观察者:

public class MyObserver implements Observer {private int i;private MyPerson myPerson;//观察的对象public MyObserver(int i){System.out.println("我是观察者---->" + i);this.i = i;}public int getI() {return i;}public void setI(int i) {this.i = i;}public MyPerson getMyPerson() {return myPerson;}public void setMyPerson(MyPerson myPerson) {this.myPerson = myPerson;}@Overridepublic void update(Observable observable, Object data) {System.out.println("观察者---->"+ i +"得到更新!");this.myPerson = (MyPerson)observable;System.out.println(((MyPerson)observable).toString());}}

观察者须要实现Observer接口,当中仅仅有一个update方法。当观察者收到 (被观察者)的通知信号。就会执行该动作。

详细demo源代码以及实现效果可点连接

2.适配器模式(Adapter Pattern)
释义:把一个类的接口变换成client所期待的还有一种接口,从而使原本因接口原因不匹配而无法一起工作的两个类能够一起工作。

适配类能够依据參数返还一个合适的实例给client。

故事理解:在朋友聚会上碰到了一个美女Sarah。从香港来的,可我不会说粤语。她不会说普通话,仅仅好求助于我的朋友kent了,他作为我和Sarah之间的Adapter,让我和Sarah能够相互交谈了(也不知道他会不会耍我)。
常见实例:ListView用于显示列表数据,可是作为列表数据集合有非常多形式。有Array,有Cursor,我们须要相应的适配器作为桥梁,处理相应的数据(并能形成ListView所须要的视图)。
适用场景:1.业务的接口与工作的类不兼容,(比方:类中缺少实现接口的某些方法)但又须要两者一起工作。2. 在现有接口和类的基础上为新的业务需求提供接口。

适配器模式分为类适配器模式和对象适配器模式。

关于类适配模式。由于java的单继承,所以在已继承一个类时。另外的仅仅能是接口,须要手动实现相应的方法,这样在client就能够创建任一种符合需求的子类。来实现详细功能。而第二种对象适配器,它不是使用继承再实现的方式,而是使用直接关联,或者称为托付的方式,详细可见该博客详细介绍适配器模式(Adapter):类适配器、对象适配器

接下来就以ListView与ArrayAdapter来解说下
ListAdapter:

public interface ListAdapter {public int getCount();Object getItem(int position);long getItemId(int position);View getView(int position, View convertView, ViewGroup parent);boolean isEmpty();
}

ListView作为一个client,所须要的目标接口就是ListAdapter,包括getCount(),getItem(),getView()等几个方法。为了兼容List< T >数据类型的数据源。专门定义了ArrayAdapter适配器,说白了。就是针对目标接口对数据源进行兼容修饰。

抽象类BaseAdapter,省略了其它代码,这里仅仅列出两个方法:

public abstract class BaseAdapter implements ListAdapter, SpinnerAdapter {// ... ...public View getDropDownView(int position, View convertView, ViewGroup parent) {return getView(position, convertView, parent);}public boolean isEmpty() {return getCount() == 0;}
}

ArrayAdapter对List< T >进行封装成ListAdapter的实现,满足ListView的调用:

public class ArrayAdapter<T> extends BaseAdapter implements Filterable {private List<T> mObjects;//我仅仅列出这一个构造函数。大家懂这个意思即可public ArrayAdapter(Context context, int textViewResourceId, T[] objects) {init(context, textViewResourceId, 0, Arrays.asList(objects));}private void init(Context context, int resource, int textViewResourceId, List<T> objects) {mContext = context;mInflater = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);mResource = mDropDownResource = resource;mObjects = objects; //引用对象,也是表达了组合优于继承的意思mFieldId = textViewResourceId;}public int getCount() {return mObjects.size();}public T getItem(int position) {return mObjects.get(position);}public View getView(int position, View convertView, ViewGroup parent) {return createViewFromResource(position, convertView, parent, mResource);}// ... ...
}

我们就如此成功的把List< T > 作为数据源以ListView想要的目标接口的样子传给了ListView。这事实上也是对象适配器的一种。

3.代理模式(Proxy Pattern)
释义: 通过引入一个新的对象来实现对真实对象的操作或将新的对象作为真实对象的一个替身,这种实现机制是代理模式(为其它对象提供一种代理以控制对这个对象的訪问).
故事理解:校园代理是为他相应的上司作代理,而这个校园代理的工作就是訪问校园中的学生。比如对学生进行问卷之类的事。

学生就是官方说法中的其它对象,校园代理的上司就通过控制这个校园代理来控制对学生的訪问。
常见实例:ActivityManagerProxy类就是一个代理。它是ActivityManagerNative的代理,也就是说ActivityManagerProxy是所说的Proxy类。而ActivityManagerNative就相当于“上司角色“类,它们都有一个共同拥有的接口IActivityManager。ActivityManager。它相当于代理模式的client。在这个类中,能够看到大量的getxxx函数,这些函数,都会调用到ActivityManagerNative类的getDefault()方法,而该方法会获得一个共用的单例的IActivityManager引用。然后通过多态来调用代理中的实现
适用场景:代理模式的应用场合分几种:远程代理,虚拟代理,安全代理等,详细可见为别人做嫁衣—-代理模式

请看以下一张结构图(网上看到的一个仔细生动的样例):

Subject类:定义了RealSubject和Proxy的共用接口,这样就能够在不论什么 使用RealSubject的地方都能够用Proxy。
RealSubject类:定义Proxy所代表的真实实体。
Proxy类:保存一个引用使得代理能够訪问实体,并提供一个与Subject的接口同样的接口。这样代理就能够用来替代实体。

接下来,我们来实现该模式:
1.Subject类 :Image.java

/*** Subject类*/
public abstract class Image {public abstract void displayImage();}

2.RealSubject类:RealImage.java


import com.andyidea.patterns.subject.Image;  /**  * RealSubject类  */
public class RealImage extends Image {  private String filename;  public RealImage(String filename) {   this.filename = filename;  loadImageFromDisk();  }  private void loadImageFromDisk() {  System.out.println("Loading   " + filename);  }  @Override  public void displayImage() {  System.out.println("Displaying " + filename);   }  } 

3.proxy类:ProxyImage.java

import com.andyidea.patterns.realsubject.RealImage;
import com.andyidea.patterns.subject.Image;/*** Proxy类*/
public class ProxyImage extends Image {private String filename;private Image image;public ProxyImage(String filename) { this.filename = filename; }@Overridepublic void displayImage() {if(image == null){image = new RealImage(filename);}image.displayImage();}}

4.client測试类:ProxyClient.java

import com.andyidea.patterns.proxy.ProxyImage;
import com.andyidea.patterns.subject.Image;/*** 代理模式client測试类*/
public class ProxyClient {public static void main(String[] args) {System.out.println("Welcome to my Blog!" +"\n" +"Proxy Patterns." +"\n"+"-------------------------------");Image mImage1 = new ProxyImage("My.Image1");Image mImage2 = new ProxyImage("My.Image2");mImage1.displayImage();mImage2.displayImage();}
}

执行结果例如以下:

        Welcome to my Blog!  Proxy Patterns------------------------------- Loading   My.Image1 Displaying My.Image1 Loading   My.Image2  Displaying My.Image2

总结来说,代理类就是对实体保存一个引用。同一时候也实现了实体一样的接口方法,这样。就能够替代实体了!!

以上就是观察者模式。适配器模式,代理模式的认识,接下来会在 Android 经常使用设计模式(二)里,继续对余下的三种模式进行阐述。

Android 经常使用设计模式(一)相关推荐

  1. Android中的设计模式之代理模式

    参考 <设计模式:可复用面向对象软件的基础 >4.7 Proxy 代理--对象结构型模式 <Android源码设计模式解析与实战>第18章 编程好帮手--代理模式 意图 为其它 ...

  2. Android常见的设计模式详解

    前言: Android开发的设计模式,基本设计思想源于java的设计模式,java的设计模式有N多种,据不完全统计,迄今为止,网络出现最频繁的大概有23种.Java只是一门开发语言,学会并掌握这门语言 ...

  3. android 构建者设计模式,Android中的设计模式之构建者模式

    参考 <设计模式:可复用面向对象软件的基础 >3.2 Builder 生成器--对象创建型模式 <Android源码设计模式解析与实战>第3章 Builder模式 意图 将一个 ...

  4. Android中的设计模式之观察者模式

    参考 <设计模式:可复用面向对象软件的基础 >5.7 Observer 观察者 对象行为型模式 <设计模式解析> 18.4 Observer模式 <Android源码设计 ...

  5. Android与MVC设计模式相关操作

    指导教材:Android编程权威指南 本教程为第二章操作 由于参考书上好多地方都是先敲代码上去,最后又删掉,所以本人就直接发布完整代码,可对第一章代码进行添加,也可直接粘贴本人敲好的代码,节约时间.书 ...

  6. Android与MVC设计模式

    Android与MVC设计模式 写在前面,之前做过一段时间移动开发,后来因为工作原因搁浅了,最新重新拿起Android权威编程指南学习,顺道做个学习笔记. 首先呢,我想说无论是计算机科班出身还是培训班 ...

  7. 《Android源码设计模式解析与实战》读书笔记(十三)

    第十三章.备忘录模式 备忘录模式是一种行为模式,该模式用于保存对象当前的状态,并且在之后可以再次恢复到此状态,有点像是我们平常说的"后悔药". 1.定义 在不破坏封闭的前提下,捕获 ...

  8. Android架构演进 · 设计模式· 为什么建议你一定要学透设计模式?

    一.引言 Hello,我是小木箱,欢迎来到小木箱成长营Android架构演进系列教程,今天将分享Android架构演进 · 设计模式· 为什么建议你一定要学透设计模式? 今天分享的内容主要分为四部分内 ...

  9. 寻找android中的设计模式(三)

     寻找android中的设计模式(三) 寻找工厂模式 工厂模式的家族分四种:静态工厂模式.简单工厂模式.工厂方法模式.抽象工厂模式. 下面以开冒菜店为例,假设我定义了一家冒菜店: <pre ...

  10. Android常用面向对象设计模式

    对于开发人员来说,设计模式有时候就是一道坎,但是设计模式又非常有用,过了这道坎,它可以让你水平提高一个档次.而在android开发中,必要的了解一些设计模式又是必须的,因为设计模式在Android源码 ...

最新文章

  1. mybatis-plus团队新作:mybatis-mate 轻松搞定数据权限
  2. PNAS-皮肤微生物群综合分析揭示人类皮肤的独特性并为其在哺乳动物的系统发育共生现象提供证据
  3. 制药行业验证过程中的偏差如何处理?
  4. 使用__FILE__和__LINE__定位错误
  5. VC++6中的一些快捷键(陆续补充中。。。)
  6. 关于zookeeper中session timeout
  7. 大三了,计算机专业学生的困惑。 [转]
  8. Java编程:普里姆算法(已知起点求最小生成树)
  9. 计算机课堂小游戏活跃气氛,适合小学生在课堂上玩的游戏,简单有趣活跃课堂气氛...
  10. 软考高级信息系统项目管理师/高项和PMP的区别,以及对比
  11. 信息安全工程师自学笔记(1)
  12. 贝塞尔曲线(Bezier Curve)
  13. codeup 1006
  14. 认知篇---嵌入式工程师的未来发展前景怎么样
  15. Linux 根文件系统的制作(busybox)
  16. android获取按键键值,android中按键的扫描码和键值
  17. ReactOS学习笔记--编译和调试
  18. 计算机不能识别监控硬盘分区,MBR 分区电脑无法识别 3TB 及以上硬盘的原因!
  19. Nginx系列教程(六)| 手把手教你搭建 LNMP 架构并部署天空网络电影系统
  20. Vue vuex vue-router

热门文章

  1. Atitit ati licenseService    设计原理
  2. Atitit。Time base gc 垃圾 资源 收集的原理与设计
  3. Atitit.go语言golang语言的新的特性  attilax总结
  4. 远程服务器返回错误 (411) 所需的长度。
  5. 加密电子邮件是最安全高效的工作通信方式
  6. 不确定性原理的前世今生 · 数学篇(三)
  7. 图解Linux下如何搭建C#开发环境
  8. 在中国在行其道的智慧城市,为何折戟多伦多? | 凌云时刻
  9. 英特尔王庆连续四年担任OpenStack基金会个人独立董事
  10. 【车牌识别】基于matlab投影模板匹配车牌识别【含Matlab源码 1359期】