Head First---状态模式

工作中设计到状态模式的功能是系统升级,在没有认识状态模式时,实现系统升级的功能,就是使用一大堆的int型来表示状态,如正在检查版本,检查失败,检查成功,下载中,下载失败,下载成功,系统更新中,更新失败,更新成功等。然后使用大量的if语句来判断状态后来继续后续的操作。

假如要添加一种状态,比如在升级前要检查rom包的状态,检测不成功清除所有数据重新开始,检测成功则开始升级。这时就需要大量修改代码,带来扩展上的困难,同时维护也比较麻烦。

首先看状态转换关系:

(1)检查版本:两种状态,失败或者成功。

(2)下载:当检查版本成功后,才能下载,下载成功或者失败。

(3)验证:当下载成功后,才能验证,验证失败或者成功。

(4)更新:当验证成功后,才能更新,更新失败或者成功。

使用状态模式设计,定义一个基类,包括检查,下载,验证,更新方法,提供给具体的状态继承实现。

package com.common.update;

public abstract class State {

	public void checkVersion() {
		// do nothing
	}

	public void download() {
		// do nothing
	}

	public void update() {
		// do nothing
	}

	public void verify() {
		// do nothing
	}

}

定义一个UpdateMachine,处理状态变换的具体逻辑,当检查,下载,验证,更新的具体操作会放在一个工作线程中,状态变化全部放在主线程中。

package com.common.update;

import android.os.Handler;
import android.os.HandlerThread;
import android.os.Process;

/**
 * @author minghuang
 * 
 *         创建一个工作线程用来检查版本,下载,更新。
 */
public class UpdateMachine {

	private static volatile UpdateMachine sInstance;

	// 主线程
	private Handler mMainHandler;

	// 工作线程
	private HandlerThread mWorkerThread;
	private Handler mWorkerHandler;

	// 以下状态在主线程上赋值
	// 无状态
	private State mNoState = new NoState();
	// 检查版本的状态
	private State mCheckingState = new CheckingState();
	private State mCheckSuccessState = new CheckSucessState();
	private State mCheckFailedState = new CheckFailedState();
	// 下载的状态
	private State mDownloadingState = new DownloadingState();
	private State mDownloadSuccessState = new DownloadSuccessState();
	private State mDownloadFailedState = new DownloadFailedState();
	// 验证升级更新文件的状态
	private State mVerifyingState = new VerifyingState();
	private State mVerifySuccessState = new VerifySuccessState();
	private State mVerifyFailedState = new VerifySuccessState();
	// 升级更新的状态
	private State mUpdatingState = new UpdatingState();
	private State mUpdateSuccessState = new UpdateSuccessState();
	private State mUpdateFailedState = new UpdateFailedState();
	// 保存前一个状态
	private State mPreState = null;
	// 保存当前状态
	private State mState = null;

	// 主线程上工作
	private boolean mIsWorking = false;

	private UpdateMachine() {
		mMainHandler = new Handler();

		mWorkerThread = new HandlerThread("worker thread");
		mWorkerThread.start();
		mWorkerHandler = new Handler(mWorkerThread.getLooper());

		setState(mNoState);
	}

	public static UpdateMachine getInstance() {
		if (sInstance == null) {
			synchronized (UpdateMachine.class) {
				if (sInstance == null) {
					sInstance = new UpdateMachine();
				}
			}
		}
		return sInstance;
	}

	// 主线程上工作
	public void checkVersion() {
		if (!isWorking()) {
			setState(mCheckingState);
		}
		mState.checkVersion();

	}

	// 主线程上工作
	public void download() {
		if (!isWorking() && mState == mCheckSuccessState) {
			setState(mDownloadingState);
		}

		mState.download();
	}

	// 主线程上工作
	public void verify() {
		if (!isWorking() && mState == mDownloadSuccessState) {
			setState(mVerifyingState);
		}

		mState.verify();
	}

	// 主线程上工作
	public void updateWithoutVerify() {
		if (!isWorking()
				&& (mState == mDownloadSuccessState || mState == mVerifySuccessState)) {
			setState(mUpdatingState);
		}

		mState.update();
	}

	// 主线程上工作
	public void updateAfterVerify() {
		if (!isWorking() && mState == mVerifySuccessState) {
			setState(mVerifyingState);
		}

		mState.verify();
	}

	private void notifyCheckResult(final boolean success) {
		Runnable r = new Runnable() {

			@Override
			public void run() {
				setState(success ? mCheckSuccessState : mCheckFailedState);
			}
		};
		runOnMainThread(r);
	}

	private void notifyDownloadProgress(final int progress) {
		Runnable r = new Runnable() {

			@Override
			public void run() {
			}
		};
		runOnMainThread(r);
	}

	private void notifyDownloadResult(final boolean success) {
		Runnable r = new Runnable() {

			@Override
			public void run() {
				setState(success ? mDownloadSuccessState : mDownloadFailedState);
			}
		};
		runOnMainThread(r);
	}

	private void notifyUpdateResult(final boolean success) {
		Runnable r = new Runnable() {

			@Override
			public void run() {
				setState(success ? mUpdateSuccessState : mUpdateFailedState);
			}
		};
		runOnMainThread(r);
	}

	private void notifyVerifyResult(final boolean success) {
		Runnable r = new Runnable() {

			@Override
			public void run() {
				setState(success ? mVerifySuccessState : mVerifyFailedState);
				if (success) {
					updateAfterVerify();
				}
			}
		};
		runOnMainThread(r);
	}

	private void notifyIsWorking(final boolean isWorking) {

		Runnable r = new Runnable() {

			@Override
			public void run() {
				mIsWorking = isWorking;
			}
		};

		runOnMainThread(r);
	}

	private void runOnMainThread(Runnable r) {
		if (mWorkerThread.getThreadId() == Process.myTid()) {
			mMainHandler.post(r);
		} else {
			r.run();
		}
	}

	private void runOnWorkerThread(Runnable r) {
		if (mWorkerThread.getThreadId() == Process.myTid()) {
			r.run();
		} else {
			mWorkerHandler.post(r);
		}
	}

	public boolean isWorking() {
		return mIsWorking;
	}

	public void setState(State state) {
		mPreState = mState;
		mState = state;
	}

	public State getState() {
		return mState;
	}

	class NoState extends State {
	}

	class CheckingState extends State {

		@Override
		public void checkVersion() {
			notifyIsWorking(true);
			Runnable r = new Runnable() {

				@Override
				public void run() {
					boolean success = false;

					// check before
					// do something
					// check after

					notifyCheckResult(success);
					notifyIsWorking(false);
				}
			};
			runOnWorkerThread(r);
		}

	}

	class CheckSucessState extends State {
	}

	class CheckFailedState extends State {
	}

	class DownloadingState extends State {

		@Override
		public void download() {
			notifyIsWorking(true);
			Runnable r = new Runnable() {

				@Override
				public void run() {
					boolean success = false;
					int progress = 0;

					// download before
					notifyDownloadProgress(progress);
					// download after

					notifyDownloadResult(success);
					notifyIsWorking(false);
				}
			};
			runOnWorkerThread(r);
		}
	}

	class DownloadSuccessState extends State {
	}

	class DownloadFailedState extends State {
	}

	class VerifyingState extends State {

		@Override
		public void verify() {
			notifyIsWorking(true);
			Runnable r = new Runnable() {

				@Override
				public void run() {
					boolean success = false;

					// verify before
					// do something
					// verify after

					notifyVerifyResult(success);
					notifyIsWorking(false);
				}
			};
			runOnWorkerThread(r);
		}

	}

	class VerifySuccessState extends State {
	}

	class VerifyFailedState extends State {
	}

	class UpdatingState extends State {

		@Override
		public void update() {
			notifyIsWorking(true);
			Runnable r = new Runnable() {

				@Override
				public void run() {
					boolean success = false;

					// update before
					// do something
					// update after

					notifyUpdateResult(success);
					notifyIsWorking(false);
				}
			};
			runOnWorkerThread(r);

		}
	}

	class UpdateSuccessState extends State {
	}

	class UpdateFailedState extends State {
	}

}

状态模式的定义:允许对象在内部状态改变时改变它的行为,对象看起来好像修改了它的类。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值