zoukankan      html  css  js  c++  java
  • 简明 状态模式(5.8)

    当一个类A的某个成员变量的值变化时,可能导致多个行为表现得不同。将该成员变量封装成类型的模式,即为状态模式(state pattern)。

    编程技巧:以多态来重构分支结构。

    设计思路:解决状态加入、状态转换、状态对行为的影响问题。



    状态决定行为

    不考虑状态转换,非常easy看到状态决定行为的场景。“朋友来了有好酒,若是那豺狼来了,迎接它的有猎枪”。

    不在状态。该赢的比赛都会输。

    例程 4-3 又见分支结构
    package property.state;
    public class Man{
        private boolean isHappy;//典型的flag,两种状态
        public String sayHello() {
            String greeting="";
            if(isHappy){
                greeting ="你好,我的朋友";
            }else{
                greeting ="好";
            }
            return greeting;
        }
        public String sayGoodbye() {
            return isHappy? "再抱抱!

    ":"再见,再也不见"; } public static void main(String[] args) { Man one = new Man(); one.isHappy =true;//false System.out.println(one.sayHello()); System.out.println(one.sayGoodbye()); } }

    这样的Man没有城府,当成员变量isHappy取值不同一时候,Man的sayHello()和sayGoodbye()等多个行为表现得不同。

    在简单场景中,if-else更简洁。然而。关键成员变量能够是int或枚举类型表示的好感度。或某个类型如顾客(土豪、凡人、钓丝)。

    • 随着状态取值可能性的加入,分支块越来越大。sayHello()和sayGoodbye()代码都变得庞大。

    • 特别是添加新的状态值,在分支结构下违反OCP

    从编程技巧上看,状态模式和策略模式、工厂方法模式一样。以多态来重构分支结构

    重构的要点:①以状态类State替代boolean、int、枚举类型或类型(注意这样的情况)的分支推断參数。显然有多少分支。State将相应有多少子类。②状态类State将全部具有上述分支推断的方法,提取为自己的接口,State的子类分别给出配套的实现

    例程 4-4 State的子类们
    package property.state;
    public interface State{
        public String sayHello();
        public String sayGoodbye();
    }
    package property.state;
    public class FriendState implements State{
        @Override public String sayHello(){
            return "你好,我的朋友";
        }
        @Override public String sayGoodbye(){
            return "再抱抱!";
        }
    }//OpposingState略
    package property.state;
    public class Man2{
        private State state;
        public String sayHello() {
            return state.sayHello();       
        }
        public String sayGoodbye() {
            return state.sayGoodbye();        
        }
        
        public static void main(String[] args) {
    		Man2 one = new Man2();
    		one.state  =new FriendState();//isHappy = true
    		System.out.println(one.sayHello());
    		System.out.println(one.sayGoodbye());
    	}
    }
    

    在不考虑状态转换时,单纯从代码上看,状态模式的State封装多个方法,而策略模式仅封装一个方法。此时,

    状态模式与策略模式的关系,如同抽象工厂与工厂方法的关系。

    尽管状态模式封装多个方法,与抽象工厂一样,不会出现[3.2.4方法类型化]的例程3-5那样的组合爆炸,由于多个方法在一个状态下是配套的,而非随意的组合。


    yqj2065在设计模式学习难度系数排名中。状态模式给的难度系数高达5分(10分制)。

    假设不过策略模式基础上的一变多,难度系数应该是1.难过


    在Man的代码中是通过设置isHappy的值改变其状态。在Man2中是通过设置State的对象类型改变其状态。状态之间的变换由外界控制,或者说,多种状态是切割的、无关的。这样的情况下,学习状态模式的难度系数最多是1。

    可是,状态模式最有趣的地方正是其状态的变迁。

    将涉及一个比較高端的术语Finite State Machine 有限状态机



    2.状态的变迁

    .....


  • 相关阅读:
    uniapp、小程序之swiperitem内容过多显示不全的解决方案
    PingFang(苹方)字体的引用
    Vue项目中使用websocket
    uniapp页面跳转传递参数过长
    uniapp开发的h5,使用微信授权登录(前置条件+具体代码)
    Maven工具安装使用
    Lombok代码生成插件使用
    对不起,我的文章暂时无法公开!
    [iOS]学习笔记7(CATransform3DFlip效果)
    [iOS]学习笔记8 (iOS之阻塞)
  • 原文地址:https://www.cnblogs.com/gccbuaa/p/7340408.html
Copyright © 2011-2022 走看看