andorid用到的常见的Java设计模式
2015-05-09 23:56
197 查看
单例设计模式
概念
单例模式(Singleton)主要作用是保证在Java应用程序中,一个类只有一个实例存在。如何实现
私有的构造方法,可以防止多个实例产生,英文私有,其他类无法new该类。私有静态实例变量,私有是防止外部滞空,下面要说到的静态的方法不能访问非静态变量。
公有的静态访问方法,公有是因为要提供对外访问,静态是因为该类不能在外部实例化。
[code]public class MySingleTon { // 单例(singleton)=1.私有的构造方法+2.私有静态实例变量+3.公有的静态访问方法 private MySingleTon() { } private static MySingleTon mySingleTon = new MySingleTon(); public static MySingleTon getInstance() { return mySingleTon; } }
懒汉和饿汉模式
说到单例模式就得提到懒汉和饿汉模式,饿汉模式是上来就搞对象,不考虑是否使用就直接分配内存,上面的代码就是饿汉模式。而懒汉模式则是需要时才搞对象,这可以避免内存浪费。[code]public class MySingleTon { // 单例(singleton)=1.私有的构造方法+2.私有静态实例变量+3.公有的静态访问方法 private MySingleTon() { } private static MySingleTon mySingleTon = null; public static MySingleTon getInstance() { if(mySingleTon==null){ mySingleTon=new MySingleTon(); } return mySingleTon; } }
不过懒汉模式是线程不安全的。假如现在有两个线程,线程中都有这句代码
[code]MySingleTon mySingleTon=MySingleTon.getInstance();
线程1运行到了if(mySingleTon==null)时被线程2抢去了,线程2同样运行到了if(mySingleTon==null)时被线程1抢去了,这时问题就发生了,由于线程1在被抢之前就已经判断了mySingTon不为空,这时就会实例mySingleTom,而但线程2重新抢到执行权时,它也已经完成非空的判断,并会往下,又实例了一遍mySingleTom,此时程序中就产生了两个实例,这与我们所期望的不同。对此,正确的做法是采用双重锁来处理
[code]public static LazySingleTon2 getInstance() { if (sSingleTon == null) {//提交效率,如果不为空,直接return synchronized (LazySingleTon2.class) {//代码线程安全 if (sSingleTon == null) { sSingleTon = new LazySingleTon2(); } } } return sSingleTon; }
Android 系统里在服务方面大量使用单例
TelephonyManager里的代码:
[code] /** @hide */ private TelephonyManager() { } private static TelephonyManager sInstance = new TelephonyManager(); /** @hide /* @deprecated - use getSystemService as described above */ public static TelephonyManager getDefault() { return sInstance; }
适配器模式
概念
将控件(Adaptee(被适配者))与内容(Adaptor(适配器))相分离的一种设计Adaptee(被适配者):ListView ,GridView,Gallery,ViewPager,….
Adaptor(适配器):SimpleAdapter ,CursorAdapter,ArrayAdapter BaseAdapter
一般通过Adaptee.setadapter(Adaptor)来绑定。
观察者模式
概念
一个目标对象(Observable)会发生敏感数据的变化,通常我们需要获取该数据,创建一个观察者对象(Observer)放置到目标内部,一旦有数据变化,就及时获取,很多地方都用到了观察者模式,比如当我们取钱时,会受到到银行的短信通知,我们追的剧更新了,收到系统的通知如何实现
确定目标对象(Observable),发生敏感数据变化目标对象得继承Observable,extends Observable,但目标发生变化是,要setChanged,要通知观察者notifyObservers(Object Data);
[code]public class TemperatureObservable extends Observable { private int temperature = 0; public void start() { //模拟温度每秒提升1度 for (int i = 0; i < 100; i++) { try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } temperature++;//数据变化 setChanged();//标记 notifyObservers(temperature);//通知观察者 } } }
3.写观察者,implements Observer,重写public void update(Observable observable, Object data)方法,其中observable为目标对象,data为目标对象中notifyObservers传进的obj。
[code]public class DisPlayer implements Observer{ //接收数据变化 的方法 @Override public void update(Observable observable, Object data) { int temperature=(Integer) data; System.out.println("显示屏幕:"+temperature+"度"); } }
4.为目标对象设置观察者
[code] //温度实例 TemperatureObservable temperatureObservable =new TemperatureObservable(); //显示屏幕 DisPlayer displayer=new DisPlayer(); //添加 temperatureObservable.addObserver(displayer); temperatureObservable.start();
我们常见的ListView里就用了观察者模式,当数据发生变化时,通过adapter.notifyDataSetChanged()通知listview刷新。
[code]public class MainActivity extends Activity implements View.OnClickListener { private ListView lv; private Button bt; private List<String> list; ArrayAdapter<String> adapter; View footview; int i=0; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); list=new ArrayList<String>(); for(;i<20;i++){ //初始数据为0-19 list.add(i+""); } lv=(ListView) findViewById(R.id.lv); footview=View.inflate(MainActivity.this, R.layout.listviewfoot, null); //添加listview的地步视图,加载更多按钮,当滚到listview最底边的时候会看到 lv.addFooterView(footview); bt=(Button) findViewById(R.id.bt); bt.setOnClickListener(this); adapter=new ArrayAdapter<String>(MainActivity.this, android.R.layout.simple_list_item_1, list); lv.setAdapter(adapter); } @Override public void onClick(View v) { // TODO Auto-generated method stub switch (v.getId()) { case R.id.bt: //假数据,一次加载20条数据 int j=i; for(;i<j+20;i++){ list.add(i+""); } //通知更新 adapter.notifyDataSetChanged(); break; default: break; } } }
现在的加载更多更多的是采用手势的方式,往上拉实现加载更多。
android还有四大组件之一的内容提供者ContentProvider也使用了观察者模式
[code]public class MainActivity extends Activity { private TextView sms_tv; ContentResolver resolver; MyObserver observer; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); sms_tv=(TextView) findViewById(R.id.sms_tv); resolver=getContentResolver(); Uri uri=Uri.parse("Content://sms/"); observer=new MyObserver(new Handler()); //注册内容观察者 //resolver.registerContentObserver(观察的uri, 为ture表示uri子路径也属于观察范围,false则不属于, observer) resolver.registerContentObserver(uri, true, observer); } //内容观察者 class MyObserver extends ContentObserver{ public MyObserver(Handler handler) { super(handler); // TODO Auto-generated constructor stub } //当内容观察者观察到数据库的内容变化了,调用这个方法 @Override public void onChange(boolean selfChange) { // TODO Auto-generated method stub super.onChange(selfChange); Toast.makeText(MainActivity.this, "数据库内容发生变化了", 1).show(); Uri uri=Uri.parse("content://sms/"); ContentResolver resolver=getContentResolver(); Cursor cursor=resolver.query(uri, new String[]{"address","date","type","body"}, null, null, null); //因为短信是倒序排列,因此获取最新一个就是第一个 cursor.moveToFirst(); String address=cursor.getString(cursor.getColumnIndex("address")); String body=cursor.getString(cursor.getColumnIndex("body")); sms_tv.setText("短信内容:"+body+"\n短信地址:"+address); cursor.close(); } } @Override protected void onDestroy() { // TODO Auto-generated method stub super.onDestroy(); if(resolver!=null){ resolver.unregisterContentObserver(observer); } observer=null; resolver=null; } }
事件驱动模型
两大机制
事件驱动/监听器,如点击事件 setOnclick(Listener)回调机制 , 点击事件传进的接口实例会回调onClick(View v)
概念
事件驱动模型=事件源+监听器+事件处理1. 事件源:接收事件的对象,如控件
2. 监听器:设置在事件源内部,捕获事件转换成参数,如点击事件的监听器为onClickListener
3. 事件处理,监听器回调函数
[code]bt=(Button) findViewById(R.id.bt); bt.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { // TODO Auto-generated method stub } });
监听器一般有四种写法,可以看这里
监听器四种写法
Command 模式
概念
Command命令模式,主要是降低控件与事件处理程序之间的耦合性,我们平常常见的按钮Button,就用了Command命令模式,让控件与事件相分离,所以Button什么场合都能用实现步骤
[code]public class MyButton { // 1.申明一个接口interface interface MyOnClickListener{ // 2.定义接口方法参数 public void MyOnClick(View view); } // 3.控件内部声明成员变量(监听器) private MyOnClickListener listener=null; // 4.通过set方法设置监听器对象 public void setMyOnClickListener(MyOnClickListener l){ this.listener=l; } }
[code]//在系统调用的地方调用方法,是不是跟平常点击事件写法一样 MyButton button=new MyButton(); button.setMyOnClickListener(new MyOnClickListener() { @Override public void MyOnClick(View view) { // TODO Auto-generated method stub } });
相关文章推荐
- Java常见设计模式之代理模式
- Java 常见设计模式
- Java中常见的设计模式之工厂设计模式
- 黑马程序员——java常见设计模式
- 【我的Java笔记】Java面向对象思想设计原则及常见设计模式
- java知识小结之常见设计模式
- JAVA设计模式之常见模式-单例模式
- java 之 面向对象思想设计原则及常见设计模式
- Java中常见的设计模式之代理设计模式
- java之 ------ DAO设计模式的【详解】及常见设计模式的【应用】
- Java开发中常见的23种设计模式概述
- Java中23种常见的设计模式
- java 之 面向对象思想设计原则及常见设计模式
- Java常见的23中设计模式
- Java常见设计模式应用场景
- java常见的设计模式
- Java 常见设计模式
- java 类库和框架中用到的设计模式
- java开发常见设计模式
- Java中常见的设计模式之适配器模式