Android状态模式实践

越来越多的应用登录操作不是进入的必须条件了。

很多都是在一些必要的操作的时候才会判断登录,例如评论,转发,支付等功能。

大部分童鞋应该都是在点击对应按钮的时候去判断登录的状态吧:

if(已登录){
            
        }else {
            
        }

这样不好,其实大家都知道不好,每加一个按钮或者需要这样的入口你就需要写一次上面的代码。

如果又加了第三个状态判断你就要在每一个上面代码的地方再加一个else if。

那应该怎么办呢?

下面介绍一下状态模式:

状态模式中的行为是由状态来决定的,不同状态下有不同的行为。

它的意图是让一个对象在其内部状态改变的时候,其行为也随之改变。


状态模式使用场景:

1.一个对象的行为取决于她的状态,并且她的必须在运行时根据状态改变她的行为。

2.代码中包含大量与对象状态有关的条件语句,例如,一个操作中含有庞大的多分枝语句(if else或switch-case),并且这些分支依赖于该对象的状态。


状态模式将每一个条件分支放入一个独立的类中,这使得你可以根据对象自身的情况将对象的状态作为一个对象,这一对象可以不依赖于其他对象而独立变化,这样通过多态来去除过多的,重复的if-else。


说了这么多太抽象,下面贴出一段简单的代码。

代码场景:有三个按钮,分别是购买 发表评论  退出登录。默认是未登录状态,点击了购买或者发表评论按钮时候会将操作动作发送给用户状态管理类来处理。

这样好处就是,当突然加了某一个判断条件,或者加了一个需要判断的入口的时候,可以统一的去处理。


状态模式使用场景还是比较广泛的,多用几次就能熟练了。

下面的例子是《Android 设计模式  解析与实战》第八章 状态模式中整理出来的。


首先将用户动作抽象出来:

/**
 * 用户状态
 * Created by ge on 2017/5/2.
 */

public interface UserState {

    // 购买
    void payment(Context context);

    // 发表评论
    void comment(Context context);

}

然后是已登录状态的操作类,如下:

已登录状态下就进行具体对应的操作即可

/**
 * 登录状态下
 * Created by ge on 2017/5/2.
 */

public class LoginState implements UserState {
    @Override
    public void payment(Context context) {
        Toast.makeText(context, "购买成功", Toast.LENGTH_SHORT).show();
    }

    @Override
    public void comment(Context context) {
        Toast.makeText(context, "评论成功", Toast.LENGTH_SHORT).show();
    }
}

对应已登录状态的就是未登录状态的操作类:

未登录状态下就跳转到登录界面。

/**
 * 为登录状态
 * Created by ge on 2017/5/2.
 */

public class LogoutState implements UserState{

    @Override
    public void payment(Context context) {
        goLogin(context);
    }

    @Override
    public void comment(Context context) {
        goLogin(context);
    }

    /**
     * 跳转登录页
     */
    private void goLogin(Context context) {
        context.startActivity(new Intent(context, LoginActivity.class));
    }
}

然后就是用户状态统一管理类了:

将判断用户是否登录发送给下面的logincontext类来处理。

/**
 * 用户状态管理类
 * Created by ge on 2017/5/2.
 */

public class LoginContext {

    // 默认未登录状态
    UserState userState = new LogoutState();

    // 单例
    private static LoginContext loginContext = new LoginContext();

    private LoginContext(){

    }

    public static LoginContext getLoginContext() {
        return loginContext;
    }

    public void setUserState(UserState userState){
        this.userState = userState;
    }

    // 购买
    public void payment(Context context){
        userState.payment(context);
    }

    // 发表评论
    public void comment(Context context){
        userState.comment(context);
    }

}

登录界面:

只有一个按钮,点击登录按钮设置用户的状态。

/**
 * 登录页面
 * Created by ge on 2017/5/2.
 */

public class LoginActivity extends Activity {

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_login);

        // 登录
        findViewById(R.id.btn_login).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {

                // 设置已登录状态
                LoginContext.getLoginContext().setUserState(new LoginState());
                LoginActivity.this.finish();
            }
        });
    }
}

最后看一下那三个按钮的界面:

点击对应按钮,将处理交给用户状态统一的操作类。

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);


        // 购买
        findViewById(R.id.btn_payment).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                LoginContext.getLoginContext().payment(MainActivity.this);
            }
        });


        // 发表评论
        findViewById(R.id.btn_comment).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                LoginContext.getLoginContext().comment(MainActivity.this);
            }
        });


        // 退出登录
        findViewById(R.id.btn_logout).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {

                // 设置退出登录状态
                LoginContext.getLoginContext().setUserState(new LogoutState());
                Toast.makeText(MainActivity.this, "已退出登录", Toast.LENGTH_SHORT).show();
            }
        });
    }
}










  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Android源码设计模式解析与实践是一本关于Android系统中的设计模式的书籍,旨在通过解析Android源码中的实际案例来理解和应用设计模式Android系统是一个庞大而复杂的开源项目,其中包含了大量的设计模式。这些设计模式不仅帮助Android系统实现了高效、稳定、易于扩展的特性,也可以为Android开发者提供参考和借鉴的经验。 本书首先介绍了设计模式的概念和基本原理,包括单例模式、工厂模式、观察者模式、策略模式等。然后,结合Android源码中的具体实例,详细讲解了这些设计模式Android系统中的应用场景和实践方法。 例如,书中通过分析Android系统中的Activity、Fragment、View等核心组件的源码,解析了它们是如何应用观察者模式状态模式来实现界面更新和事件传递的。又如,书中通过分析Android系统中的Handler、Looper、MessageQueue等核心类的源码,讲解了它们是如何应用责任链模式来实现线程间通信和消息处理的。 此外,本书还探讨了Android系统中的一些特殊设计模式,如MVC模式、MVP模式、MVVM模式等,帮助读者理解和应用这些模式来构建更加优雅和可维护的Android应用程序。 总之,通过学习和实践本书中介绍的Android源码设计模式,读者可以更深入地了解Android系统的设计原则和实践经验,提升自己的Android开发技能,并能够更加高效地开发出高质量的Android应用程序。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值