Android实战设计模式-----状态模式
定义:
当一个对象的内在状态改变时允许改变其行为,这个对象看起来像是改变了其类
使用使用场景:
1.一个对象的行为取决于它的状态,并且它的状态必须在运行时根据状态改变它的行为
2.代码中包含大量与对象状态有关的条件语句,例如,一个操作中含有庞大的多分支语句 if -else且这些分支依赖该对象的状态
实战
用户登录系统
取在普通的应用中,一个转发按钮,判断用户登录状态,如果未登录会先让用户登录,然后在执行转发操作
如果是已登录,可以直接执行转发操作。可见,对于一个按钮的操作对于不同状态处理完全不同,
MainActivity代码
- public class MainActivity extends Activity {
- @Override
- public void onCreate(Bundle savedInstanceState, PersistableBundle persistentState) {
- super.onCreate(savedInstanceState, persistentState);
- //转发按钮
- findViewById(R.id.activity_main).setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View view) {
- LoginContext.getLoginContext().forward(MainActivity.this);
- }
- });
- //注销按钮
- findViewById(R.id.activity_main).setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View view) {
- LoginContext.getLoginContext().setState(new LogoutState());
- }
- });
- }
- }
LoginActivity
- public class LoginActivity extends Activity {
- EditText user;
- EditText pwd;
- @Override
- public void onCreate(Bundle savedInstanceState, PersistableBundle persistentState) {
- super.onCreate(savedInstanceState, persistentState);
- findViewById(R.id.activity_main).setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View view) {
- login();
- finish();
- }
- });
- }
- private void login() {
- String name = user.getText().toString();
- String pwd1 = pwd.getText().toString();
- //执行网络请求
- //登录成功后修改为已登录状态
- LoginContext.getLoginContext().setState(new LoginedState());
- }
- }
LoginContext
- /******************************************
- * 类名称:LoginContext
- * 类描述:用户接口和状态管理类
- *
- * @version: 2.3.1
- * @author:
- * @time: 2016/11/16 14:12
- ******************************************/
- public class LoginContext {
- UserState mState = new LogoutState();
- static LoginContext sLoginContext = new LoginContext();
- private LoginContext() {
- }
- public static LoginContext getLoginContext() {
- return sLoginContext;
- }
- public void setState(UserState aState) {
- this.mState = aState;
- }
- public void forward(Context context) {
- mState.forward(context);
- }
- public void comment(Context context) {
- mState.comment(context);
- }
- }
用户状态类 UserState
- public interface UserState {
- public void forward(Context context);
- public void comment(Context context);
- }
已登录状态LoginedState
- /******************************************
- * 类名称:LoginedState
- * 类描述:已登录状态
- * @time: 2016/11/16 14:13
- ******************************************/
- public class LoginedState implements UserState {
- @Override
- public void forward(Context context) {
- Log.i("TAG", "转发");
- }
- @Override
- public void comment(Context context) {
- Log.i("TAG", "评论");
- }
- }
注销状态未登录状态LogoutState
- public class LogoutState implements UserState {
- @Override
- public void forward(Context context) {
- goToLogin(context);
- }
- @Override
- public void comment(Context context) {
- goToLogin(context);
- }
- private void goToLogin(Context context) {
- Intent intent = new Intent(context, LoginActivity.class);
- context.startActivity(intent);
- }
- }
如果不使用状态模式,在任何调用这些功能时都要进行是否登录的判断,代码逻辑就变成If-else,如果再增加用户一个状态,还需要再支持对这个状态的判断,使得模块很脆弱,一单忘记某个用户状态进行判断,很容易引发用户权限问题,
总结:
状态模式的关键在于不同状态下对同一行为有不同的响应,其实就是一个将if -else用多态来实现的一个例子。
优点:
State模式将所有与一个特定的状态相关的行为都放入一个状态对象中,它提供了一个更好的方法来组织与特定状态相关的代码,将繁琐的状态判断转换成结构清晰的状态类族,在避免代码膨胀的同事也保证了可扩展性与可维护性
缺点:
增加系统类和对象的个数