《Android源码设计模式解析与实战》读书笔记(八)——状态模式
2017-05-12 10:55
218 查看
这两章都比较简单,就不多说废话,直入主题。
2).代码中含有大量判断状态的if...else...或者switch...case...条件语句,并且这些语句都依赖于该对象的状态时。
状态模式跟策略模式一样,将每一个条件分支放到一个独立的类中,这样就可以根据对象自身的情况将对象的状态作为一个对象,这个对象不依赖于其他对象,可以独立变化从而决定不同的行为,这样通过多态就可以避免复杂的if...else语句。
两种状态的实现类:
然后定义一个状态管理类:
在MainActivity中定义了四个按钮,来调用登录、注销、转发、评论四个方法:
运行效果这里就不展示了,不出意外就会是未登录的状态下点击登录按钮显示登录对话框,点击注销按钮显示“已注销,无需重复注销”,点击转发按钮和评论按钮也会显示登录对话框;登录状态下点击登录按钮会显示“已登录,无需重复登录”,点击注销按钮显示“注销成功”,点击转发按钮显示“转发成功”,点击评论按钮显示“评论成功”。
点击了同一个按钮,在状态不同时却有不同行为,如果不用状态模式实现,是不是应该在调用login(),loginOut(),forward(),comment()方法时分别判断一下当前状态呢,这样如果再增加一个状态,还得增加if...else...判断语句,如果再增加一个功能,也会同样在这个功能里判断一下当前状态,一旦忘记了某次判断,可能就会导致整个程序状态出错,状态模式将这些行为封装到状态中,消除了if...else...判断,也增强了可扩展性和代码可读性,结构清晰,灵活性更高。
优点:
1).状态模式将所有与某个状态相关的行为都放到一个状态对象中,提供更好的方法来构建与该状态相关的代码,将繁琐的状态判断改为清晰的状态类族,避免代码臃肿的同时保证了可扩展性和可维护性。
缺点:
1).状态模式同样也会相应增加状态子类。
Demo下载
第八章 随遇而安——状态模式
顾名思义,状态模式,肯定跟状态有关系,它是根据状态来决定行为的,即不同状态有不同行为。听起来就跟策略模式很像,不错,都说状态模式和策略模式是“孪生兄弟”,它们的结构几乎一模一样,但是本质却是不一样的,策略模式各策略之间是相互独立、可以互相替换的,但是状态模式之间的行为却是平行的,不可替换。可能这么说还是不太好理解,等弄懂了状态模式再做个总结。1.定义
当一个对象的内在状态改变时允许改变其行为,这个对象看起来就像是改变了其类。2.使用场景
1).一个对象的行为取决于它的状态,并且它必须在运行时根据状态改变它的行为。2).代码中含有大量判断状态的if...else...或者switch...case...条件语句,并且这些语句都依赖于该对象的状态时。
状态模式跟策略模式一样,将每一个条件分支放到一个独立的类中,这样就可以根据对象自身的情况将对象的状态作为一个对象,这个对象不依赖于其他对象,可以独立变化从而决定不同的行为,这样通过多态就可以避免复杂的if...else语句。
3).简单实现
首先有一个状态的接口,在这个接口中定义四个方法:public interface UserState { void login(MainActivity activity); void loginOut(MainActivity activity); void forward(MainActivity activity); void comment(MainActivity activity); }
两种状态的实现类:
public class LoginState implements UserState { @Override public void login(MainActivity activity) { Toast.makeText(activity, "已登录,无需重复登录", Toast.LENGTH_SHORT).show(); } @Override public void loginOut(MainActivity activity) { Toast.makeText(activity, "注销成功", Toast.LENGTH_SHORT).show(); } @Override public void forward(MainActivity activity) { Toast.makeText(activity, "转发成功", Toast.LENGTH_SHORT).show(); } @Override public void comment(MainActivity activity) { Toast.makeText(activity, "评论成功", Toast.LENGTH_SHORT).show(); } }
public class LoginOutState implements UserState { @Override public void login(MainActivity activity) { activity.showCustomizeDialog(); } @Override public void loginOut(MainActivity activity) { Toast.makeText(activity, "已注销,无需重复注销", Toast.LENGTH_SHORT).show(); } /** * Description:未登录的情况下点击转发和评论将显示登录对话框 * Date:2017/5/12 */ @Override public void forward(MainActivity activity) { activity.showCustomizeDialog(); } @Override public void comment(MainActivity activity) { activity.showCustomizeDialog(); } }
然后定义一个状态管理类:
public class StateManager { private static StateManager sStateManager = new StateManager(); //默认为未登录状态 private UserState mUserState = new LoginOutState(); public static StateManager getInstance() { return sStateManager; } public void setmUserState(UserState mUserState) { this.mUserState = mUserState; } public void login(MainActivity activity) { mUserState.login(activity); } public void loginOut(MainActivity activity) { mUserState.loginOut(activity); } public void forward(MainActivity activity) { mUserState.forward(activity); } public void comment(MainActivity activity) { mUserState.comment(activity); } }
在MainActivity中定义了四个按钮,来调用登录、注销、转发、评论四个方法:
public class MainActivity extends AppCompatActivity { private StateManager sStateManager = StateManager.getInstance(); @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); findViewById(R.id.btn_login).setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { sStateManager.login(MainActivity.this); } }); findViewById(R.id.btn_login_out).setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { sStateManager.loginOut(MainActivity.this); sStateManager.setmUserState(new LoginOutState()); } }); findViewById(R.id.btn_forward).setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { sStateManager.forward(MainActivity.this); } }); findViewById(R.id.btn_comment).setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { sStateManager.comment(MainActivity.this); } }); } public void showCustomizeDialog() { final AlertDialog.Builder customizeDialog = new AlertDialog.Builder(this); final View dialogView = LayoutInflater.from(MainActivity.this) .inflate(R.layout.dialog_customize, null); customizeDialog.setTitle("登录微博"); customizeDialog.setView(dialogView); Button btnLogin = (Button) dialogView.findViewById(R.id.btn_login); Button btnCancel = (Button) dialogView.findViewById(R.id.btn_cancel); final AlertDialog alertDialog = customizeDialog.show(); btnLogin.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { sStateManager.setmUserState(new LoginState()); alertDialog.dismiss(); } }); btnCancel.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { alertDialog.dismiss(); } }); } }
运行效果这里就不展示了,不出意外就会是未登录的状态下点击登录按钮显示登录对话框,点击注销按钮显示“已注销,无需重复注销”,点击转发按钮和评论按钮也会显示登录对话框;登录状态下点击登录按钮会显示“已登录,无需重复登录”,点击注销按钮显示“注销成功”,点击转发按钮显示“转发成功”,点击评论按钮显示“评论成功”。
点击了同一个按钮,在状态不同时却有不同行为,如果不用状态模式实现,是不是应该在调用login(),loginOut(),forward(),comment()方法时分别判断一下当前状态呢,这样如果再增加一个状态,还得增加if...else...判断语句,如果再增加一个功能,也会同样在这个功能里判断一下当前状态,一旦忘记了某次判断,可能就会导致整个程序状态出错,状态模式将这些行为封装到状态中,消除了if...else...判断,也增强了可扩展性和代码可读性,结构清晰,灵活性更高。
4.总结
状态模式的关键点在于不同状态下,对于同一个行为有不同响应,这就是将if...else...用多态来实现,当然并不是所有的if...else...都应该用状态模式替换,也得考虑特定场景。刚开始说状态模式和策略模式是“孪生兄弟”,从刚才的示例中也能看出,它们俩的代码结构真的是差不多,策略模式是调用策略管理类中的set()方法来选择不同的策略,从而有不同的行为;而状态模式同样是调用状态管理类中的set()方法来设置不同的状态,从而有不同的响应。但是注意,策略模式是主动选择的执行具体哪种策略,而状态模式却是将具体实现封装到状态类中,你只知道当前处于哪种状态,不知道这个状态采用的是哪种策略,换言之,状态模式是根据状态来选择策略的,所以这就是它们最大的区别。优点:
1).状态模式将所有与某个状态相关的行为都放到一个状态对象中,提供更好的方法来构建与该状态相关的代码,将繁琐的状态判断改为清晰的状态类族,避免代码臃肿的同时保证了可扩展性和可维护性。
缺点:
1).状态模式同样也会相应增加状态子类。
Demo下载
相关文章推荐
- 【读书笔记】状态模式C++代码第二版
- 读书笔记13:状态模式
- 《设计模式之禅》读书笔记--(21)状态模式
- 【读书笔记】状态模式代码C#
- 设计模式读书笔记-----状态模式
- HeadFirst设计模式_读书笔记_010_状态模式
- 读书笔记13:状态模式
- 《Head First Design Patterns》读书笔记之状态模式
- 设计模式读书笔记-----状态模式
- 《游戏编程模式》读书笔记之二 - 状态模式
- 《Android源码设计模式》读书笔记 (8) 第8章 状态模式
- 设计模式读书笔记-状态模式
- 《Head First设计模式》 读书笔记11 状态模式 The State Pattern
- 设计模式读书笔记:State(状态)
- 【设计模式】《Head First 设计模式》读书笔记——状态模式
- 设计模式读书笔记之状态模式(State Pattern)
- 第十六章 无尽加班何时休--状态模式(读书笔记)
- 读书笔记13:状态模式
- 【读书笔记】状态模式C++第一版出炉