標籤:android 設計模式 線程
在Android中用於儲存Activity狀態的onSaveInstanceState()和恢複Activity狀態的onRestoreInstanceState(),
這種算不算是一種備忘錄模式呢?
1、定義:
在不破壞封裝的情況下,捕獲對象的內部狀態,並在對象之外儲存這個狀態,這樣以後就可以恢複以後儲存的狀態;
2、使用:
備忘錄模式,比較適合用於功能複雜,但是需要維護和紀錄曆史的類,或者是需要儲存一個或者是多個屬性的類,
在未來某個時段需要時,將其還原到原來紀錄的狀態;
Originator可以根據儲存的Memento還原到前一狀態;
3、其他:
備忘錄模式又稱之為:快照模式(Snapshot Pattern)或Token模式,是對象的行為模式;
4、簡單的demo:
首先是需要處理的對象資料:
package com.example.demo.Memento;/** * 對象 * @author qubian * @data 2015年6月20日 * @email [email protected] * */public class Bean {private String name;private String age;public String getName() {return name;}public void setName(String name) {this.name = name;}public String getAge() {return age;}public void setAge(String age) {this.age = age;}public Memento createMemento(String name,String age){return new Memento(name, age);}public void restore(Memento memento){this.name=memento.getName();this.age= memento.getAge();}}
備忘資料對象:
1、這個可以儲存和被處理的對象一樣的資料,也可以根據需要修改,設定自己的資料;
2、需要明確的功能僅僅是為了儲存和恢複被處理的對象,故其中的資料可以隨意約定,
3、那麼,問題來了,這個備份的資料,一般都是儲存在記憶體中,用於恢複對象,那麼如果將被處理的對象,序列化,或者是運用反射等技術用於儲存和恢複,那麼這樣儲存在磁碟中,這樣是否有意義,或者是違背了這樣的設計模式呢?
4、也就是原來的問題,在Android中onSaveInstanceState中的資料,一般都是使用的Android的儲存方式,是為了在Activity在記憶體中銷毀後的恢複問題,那麼備忘錄模式中儲存在記憶體的對象,在此時,似乎就沒有什麼意義了!?
package com.example.demo.Memento;/** * 備忘錄 備忘資料 * @author qubian * @data 2015年6月20日 * @email [email protected] * */public class Memento {private String name;private String age;public Memento(String name,String age){this.name=name;this.age= age;}public String getName() {return name;}public void setName(String name) {this.name = name;}public String getAge() {return age;}public void setAge(String age) {this.age = age;}}
備忘錄管理者以及使用者:
package com.example.demo.Memento;/** * 備忘錄模式 * 管理者 * @author qubian * @data 2015年6月20日 * @email [email protected] * */public class MementoManager {private Memento memento;public Memento getMemento() {return memento;}public void setMemento(Memento memento) {this.memento = memento;}}package com.example.demo.Memento;public class UseMemento {public void use(){Bean bean =new Bean();bean.setName("張三");bean.setAge("22");// 儲存狀態MementoManager manager = new MementoManager();manager.setMemento(bean.createMemento(bean.getName(), bean.getAge()));// 改變狀態bean.setAge("23");//恢複原來地狀態bean.restore(manager.getMemento());}}
在管理者其中,備忘資料對象Memento,可以放在管理者中統一管理;
在管理者中,也可以存在多種狀態的Memento,上例子中,僅僅存放了一個簡單的狀態;
5、在備忘錄模式的定義中,是說,在此對象之外儲存這個對象的狀態,那麼,如果這麼說來,存在記憶體和磁碟中,然後處理後返回原來的對象資料,這樣似乎也都是一種備忘錄模式咯?!
6、Android:
1、那麼如果這麼說來,Activity 本身就用到了這樣的設計模式了,
2、在橫豎屏切換的時候,線程Thread會重新啟動,這個問題是橫豎屏切換的時候需要處理的,那麼,我們在此需要也是需要考慮的這麼模式,就是線程重啟的時候,線程中的資料,我們也是肯定需要用到這個模式的,用來儲存原來的資料;
3、在JNI 調用本機資料中的Canvas中的Save() 和Restore()這兩個本地JNI 代碼中是否也運用這樣的設計模式呢?!
public class Canvas { /** * Saves the current matrix and clip onto a private stack. Subsequent * calls to translate,scale,rotate,skew,concat or clipRect,clipPath * will all operate as usual, but when the balancing call to restore() * is made, those calls will be forgotten, and the settings that existed * before the save() will be reinstated. * * @return The value to pass to restoreToCount() to balance this save() */ public native int save(); /** * Based on saveFlags, can save the current matrix and clip onto a private * stack. Subsequent calls to translate,scale,rotate,skew,concat or * clipRect,clipPath will all operate as usual, but when the balancing * call to restore() is made, those calls will be forgotten, and the * settings that existed before the save() will be reinstated. * * @param saveFlags flag bits that specify which parts of the Canvas state * to save/restore * @return The value to pass to restoreToCount() to balance this save() */ public native int save(int saveFlags); /** * This behaves the same as save(), but in addition it allocates an * offscreen bitmap. All drawing calls are directed there, and only when * the balancing call to restore() is made is that offscreen transfered to * the canvas (or the previous layer). Subsequent calls to translate, * scale, rotate, skew, concat or clipRect, clipPath all operate on this * copy. When the balancing call to restore() is made, this copy is * deleted and the previous matrix/clip state is restored. * * @param bounds May be null. The maximum size the offscreen bitmap * needs to be (in local coordinates) * @param paint This is copied, and is applied to the offscreen when * restore() is called. * @param saveFlags see _SAVE_FLAG constants * @return value to pass to restoreToCount() to balance this save() */ public int saveLayer(RectF bounds, Paint paint, int saveFlags) { return native_saveLayer(mNativeCanvas, bounds, paint != null ? paint.mNativePaint : 0, saveFlags); } /** * This call balances a previous call to save(), and is used to remove all * modifications to the matrix/clip state since the last save call. It is * an error to call restore() more times than save() was called. */ public native void restore();}
Android設計模式(十五)--備忘錄模式