越来越多的应用登录操作不是进入的必须条件了。
很多都是在一些必要的操作的时候才会判断登录,例如评论,转发,支付等功能。
大部分童鞋应该都是在点击对应按钮的时候去判断登录的状态吧:
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();
}
});
}
}