设计模式之状态模式

概念:状态模式中的行为是由状态来决定的,不同的状态有不同的行为,状态模式把对象的行为包装在不同的状态对象里,每一个对象都有一个共同的抽象状态基类,状态模式的意图是让一个对象在他的内部状态改变的时候,其行为也随之改变。
常见使用场景:
微博的转发和评论,在登录状态和未登录状态执行的行为也是不一样的。
示例:
这里写图片描述
1、定义一个UserState接口,里面声明了所有行为的方法:


/**
 * Created by jin.li on 2017/6/3.
 * 表示用户的当前状态
 */

public interface UserState {
    //转发
    public void forward(Context context);

    //评论
    public void comment(Context context);
}

2、LoginState和LogouState实现了UserState

/**
 * Created by jin.li on 2017/6/3.
 */

public class LoginState implements UserState {
    @Override
    public void forward(Context context) {
        //转发
    }

    @Override
    public void comment(Context context) {
        //评论
    }
}
/**
 * Created by jin.li on 2017/6/3.
 */

public class LogouState implements UserState {
    @Override
    public void forward(Context context) {
        //goto LoginActivity
    }

    @Override
    public void comment(Context context) {
        //goto LoginActivity
    }
}

3、MainActivity完成了转发、评论及注销的功能:

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Button btn_forward = (Button) findViewById(R.id.btn_forward);
        Button btn_logout = (Button) findViewById(R.id.btn_logout);

        //转发
        btn_forward.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                LoginContext.getLoginContext().forward(MainActivity.this);
            }
        });

        //注销
        btn_logout.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
            //注销后,同步更新状态
                LoginContext.getLoginContext().setState(new LogouState());
            }
        });
    }
}

4、LoginActivity为地登录页面:

  private EditText usernameEdit;
    private EditText pwdEdit;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        usernameEdit = (EditText) findViewById(R.id.username);
        pwdEdit = (EditText) findViewById(R.id.pwd);
        Button btn = (Button) findViewById(R.id.btn);

        btn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                login();
                finish();
            }
        });
    }

    private void login() {
        String username = usernameEdit.getText().toString().trim();
        String pwd = pwdEdit.getText().toString().trim();

        //修改状态为登录状态
        LoginContext.getLoginContext().setState(new LoginState());

    }
}

5、LoginContext,用户接口和状态管理类,通过setState来对状态进行改变,并且把操作委托给状态对象,不同的状态对象对于同一个操作进行不同的车处理。

public class LoginContext {

    //默认为未登录状态
    UserState mState = new LogouState();
    public static LoginContext sLoginContext = new LoginContext();

    public static LoginContext getLoginContext() {
        return sLoginContext;
    }

    public void setState(UserState state) {
        this.mState = state;
    }

    public void forward(Context context) {
        mState.forward(context);
    }

    public void comment(Context context) {
        mState.comment(context);
    }
}

6、总结:
UserState中有两个方法:转发和评论,在已登录的状态下,执行转发和评论,反之进入登录页面,登录后更新状态为已登录状态。避免了大量的if else,即使用户增加了状态,代码结构也依然很清晰,反之,如果使用if else,那么每一个功能函数的if else都要全部重新修改,这样使得这个模块变得很脆弱。

参考:《Andorid源码设计模式解析与实战》

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值