设计模式之状态模式

来源:互联网 发布:c语言截断 编辑:程序博客网 时间:2024/06/11 12:24

概念:状态模式中的行为是由状态来决定的,不同的状态有不同的行为,状态模式把对象的行为包装在不同的状态对象里,每一个对象都有一个共同的抽象状态基类,状态模式的意图是让一个对象在他的内部状态改变的时候,其行为也随之改变。
常见使用场景:
微博的转发和评论,在登录状态和未登录状态执行的行为也是不一样的。
示例:
这里写图片描述
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源码设计模式解析与实战》

原创粉丝点击