• 状态模式(理解此模式了)


    v2第二次复习:
    基本上看第一次总结,是正确的,还有一个补充就是,如果状态的判定又涉及到多个字段的话,那么用状态模式的附带的好处就是把状态用单独key表示出来了。就是每个状态的派生类。这样更简洁。
    另外状态类,都是包含行为的,而行为一般是会对状态类的母体做修改。所以状态类的方法一般会传递this过去。




    第一次学习
    官方的一句话:允许对象在内部状态发生改变时改变它的行为,对象看起来好像修改了它的类。

    自己的一句话:状态不同,一系列动作不同,如各种机器,贩卖机,电梯,mp3等,有多个状态,并且有多个按钮。它突出的是状态会增加,或减少的场景。

    策略模式是一个最底层的模式,很多模式都包含策略模式。
    状态模式是有状态的,它突出的是状态会增加,或减少的策略模式,可以说策略是基础模式,状态是有状态的策略模式。

    使用场景,如果状态多。并且动作也不只一个,如果加新状态 if else 不直观,要到内部修改。所以用状态模式。
    //没太看懂,恩,直接写例子吧。根据这个模式的说明,大量增加状态时,会需要状态模式,自己看看是否会迭代出状态模式
    //v1:建一个机器人,有3个状态,开心,平静,愤怒。 有2个行为,吃饭和睡觉。
    //v2:试图增加状态,并符合开闭状态。
    //看网上很多例子。各不一样。但是根本意思是一样。
    //如这里,机器人有不同的情绪,那么吃饭的结果完全不同。如果情绪更丰厚。那么吃饭的结果就太多了。
    //干脆把吃饭作为一个类,那么有高兴吃饭类,平静吃饭类。生气吃饭类。等等,想加什么加什么。当然必须把机器人传递给吃饭类,因为毕竟吃饭类是要知道谁吃饭吧。
    //个人总结,除非非常符合情景,否则使用的也不多。因为会宁愿修改代码也不会去实现状态模式。
    // 有一点像命令模式,虽然目的不同,一个为了存储,一个为了变化。但是根本手段是一致。把方法提出来放到类中。总的指导思想是一致的。
    public class MyState
    {
        public void Run()
        {
            Robot robot=new Robot("v1");
            robot.changeState(0);
            robot.eat();
            robot.sleep();
            robot.changeState(2);
            robot.eat();
        }
    
        public void Runv2()
        {
            Robotv2 robot2=new Robotv2("v2");
            happy happystats=new happy();
            Calm calmstats=new Calm();
    
            robot2.eat();
            robot2.sleep();
    
            calmstats.eat(robot2);
        }
    
        //region v1 ,存在增加状态时,必须需改函数内部,违反开闭原则。
        public class Robot
        {
            private int MState=0;//0:calm    1:happy   2:angry.
            private String mName;
    
            public Robot(String name)
            {
                mName=name;
            }
    
            public void changeState(int ss)
            {
                MState=ss;
            }
    
            public void eat()
            {
                if(MState==0)
                {
                    LSComponentsHelper.LS_Log.Log_INFO(mName+"eat half");
                }
                else if(MState==1)
                {
                    LSComponentsHelper.LS_Log.Log_INFO(mName+"eat all");
                }
                else if(MState==2)
                {
                    LSComponentsHelper.LS_Log.Log_INFO(mName+"eat nothing");
                }
    //            else if(MState==3)
    //            {
    //                LSComponentsHelper.LS_Log.Log_INFO(mName+"eat nothing");
    //            }
            }
    
            public void sleep()
            {
                if(MState==0)
                {
                    LSComponentsHelper.LS_Log.Log_INFO(mName+"sleep slowly");
                }
                else if(MState==1)
                {
                    LSComponentsHelper.LS_Log.Log_INFO(mName+"sleep fast");
                }
                else if(MState==2)
                {
                    LSComponentsHelper.LS_Log.Log_INFO(mName+"sleep ,hardly");
                }
                //            else if(MState==3)
    //            {
    //                LSComponentsHelper.LS_Log.Log_INFO(mName+"eat nothing");
    //            }
            }
        }
        //endregion
    
        //region  常见的对修改关闭的手段,就是把要修改的部分放到一个类中,并让他们继承某个接口。那么原来需要修改的地方。只要使用接口就可以。变化可以由增加新类来实现。
        //把增加的内部判断,改为了到外部增加新类
        public class Robotv2
        {
            private int MState=0;//0:calm    1:happy   2:angry.
            private String mName;
    
            public Robotv2(String name)
            {
                mName=name;
            }
    
            public void changeState(int ss)
            {
                MState=ss;
            }
    
    
    
            public void eat()
            {
                MState=0;
                LSComponentsHelper.LS_Log.Log_INFO(mName+"start eat");
                MState=1;//初始状态,吃完东西会变开心。
            }
    
    
            public void sleep()
            {
                MState=0;
                LSComponentsHelper.LS_Log.Log_INFO(mName+"start sleep");
                MState=2;//初始状态,睡觉,会变不开心.
            }
        }
    
        public interface IAction
        {
            public void eat(Robotv2 robotv2);
            public void sleep(Robotv2 robotv2);
        }
    
        public class happy implements IAction
        {
            @Override
            public void eat(Robotv2 robotv2)
            {
                LSComponentsHelper.LS_Log.Log_INFO(robotv2.mName+"eat all");
                robotv2.changeState(2);
            }
    
            @Override
            public void sleep(Robotv2 robotv2)
            {
                LSComponentsHelper.LS_Log.Log_INFO(robotv2.mName+"sleep fast");
            }
        }
    
        public class Calm implements IAction
        {
            @Override
            public void eat(Robotv2 robotv2)
            {
                LSComponentsHelper.LS_Log.Log_INFO(robotv2.mName+"eat half");
                robotv2.changeState(1);
            }
    
            @Override
            public void sleep(Robotv2 robotv2)
            {
                LSComponentsHelper.LS_Log.Log_INFO(robotv2.mName+"sleep slowly");
            }
        }
    
    
    
        //endregion
    }
  • 相关阅读:
    saltstack源码详解一
    linux的yum报错
    django restframework
    列表生成式
    面向对象的封装
    linux对于zombie的处理
    Flask学习目录
    #1_两数之和
    LeetCode入门
    Struts2(一)——基本使用
  • 原文地址:https://www.cnblogs.com/lsfv/p/11145020.html
Copyright © 2020-2023  润新知