行为型模式(五)状态模式

一句话的概要

允许一个对象在内部改变其对象的行为。让对象看起来就像是改变了它的类。

剧情

恋爱会改变一个人的态度,小明和女神今天回想起恋爱时候的态度,偶然提到。恋爱之前,小明请女神吃饭,约会,女神都是拒绝的。

现在请女神吃饭,约会,女神缺欣然接收。这就是两人状态的不同,导致的不同结果。

那么我们用状态模式,去构造以上场景。让女神不同的状态,做出不同的反应。

任务一:创建恋爱的抽象类

我们创建恋爱时期的抽象类,定义反应方法。我们后面会继承这个抽象类,并进行不同的反应。

public abstract class Love
    {
        //状态
        public Account Account { get; set; }

        //好感度
        public int GoodWill { get; set; }

        //吃饭
        public abstract void Eat();

        //约会
        public abstract void YueHui();

        //增加好感度
        public abstract void AddGoodWill(int good);

        //减少好感度
        public abstract void DelGoodWill(int good);
    }

我们的Account就是状态类,不同的方法就是由这里制定的。

接着我们直接看Account类的代码

public class Account
    {
        public Love love { get; set; }

        public Account(int good)
        {
            love = new Friend(0, this);
        }

        public void Eat()
        {
            love.Eat();
        }

        public void YueHui()
        {
            love.YueHui();
        }

        public void DelGoodWill(int good)
        {
            love.DelGoodWill(good);
        }
    }

我们让他们两个人,从朋友开始。所以构造的话,初始化朋友。并且定义不同的方法,调用女神反应的抽象方法。

这样继承的话,只需要改对应的抽象方法即可。

任务二:创建朋友的反应

我们先创建朋友的反应,直接上代码。

public class Friend : Love
    {
        public Friend(int good, Account love)
        {
            this.GoodWill = good;
            this.Account = love;
        }

        public override void AddGoodWill(int good)
        {
            this.GoodWill += good;
            Ask();
        }

        public override void DelGoodWill(int good)
        {
            this.GoodWill -= good;
            Ask();
        }

        public override void Eat()
        {
            AddGoodWill(1);
            Console.WriteLine("我们只是朋友,我不去");
            Ask();
        }

        public override void YueHui()
        {
            AddGoodWill(1);
            Console.WriteLine("我们只是朋友,我不去");
            Ask();
        }

        //询问是否有好感
        public void Ask()
        {
            if (this.GoodWill > 5)
            {
                Account.love = new Lovers();
            }
        }
    }

我们定义一个好感度机制,让他大于5才能变成恋人。小于等于5,那么每次叫出去,都不去。

任务三:创建恋人反应

我们创建一个恋人的反应。直接上代码。

public class Lovers : Love
    {
        public override void AddGoodWill(int good)
        {
            this.GoodWill += good;
            Ask();
        }

        public override void DelGoodWill(int good)
        {
            this.GoodWill -= good;
            Ask();
        }

        public override void Eat()
        {
            Console.WriteLine("我们是恋人,我去");
        }

        public override void YueHui()
        {
            Console.WriteLine("我们是恋人,我去");
        }

        //询问是否有好感
        public void Ask()
        {
            if (this.GoodWill < 5)
            {
                Account.love = new Friend(this.GoodWill, this.Account);
            }
        }
    }

这样,虽然外表没有改变,还是一个类。但是实际上,根据状态的不同,实现的东西也随之不同。

这就是状态模式。我们最后调用一下,看一下结果。

private static void Main(string[] args)
        {
            Console.WriteLine("两个人刚认识");
            Account account = new Account(0);
            Console.WriteLine("约吃饭");
            account.Eat();
            Console.WriteLine("慢慢交往,继续不停的约吃饭");
            for (int i = 0; i < 5; i++)
            {
                account.Eat();
            }
            account.Eat();
            account.YueHui();
            Console.ReadLine();
        }

总结

允许一个对象在其内部状态改变的时候,自行改变行为。让调用模块不进行修改,但是执行的确结果却是不同的。

常用场景:一个对象在多个状态下行为不同,且这些状态可相互转换。

选择关键点:这些状态是否经常在运行时需要在不同的状态下相互切换

时间: 2024-12-13 05:43:15

行为型模式(五)状态模式的相关文章

行为型模式之状态模式

概述 状态模式用于解决系统中复杂对象的状态转换以及不同状态下行为的封装问题.当系统中某个对象存在多个状态,这些状态之间可以进行转换,而且对象在不同状态下行为不相同时可以使用状态模式.状态模式将一个对象的状态从该对象中分离出来,封装到专门的状态类中,使得对象状态可以灵活变化,对于客户端而言,无须关心对象状态的转换以及对象所处的当前状态,无论对于何种状态的对象,客户端都可以一致处理. 定义 状态模式(State Pattern):允许一个对象在其内部状态改变时改变它的行为,对象看起来似乎修改了它的类

23行为型模式之状态模式

概念 State模式也叫状态模式,是行为设计模式的一种.State模式允许通过改变对象的内部状态而改变对象的行为,这个对象表现得就好像修改了它的类一样. 状态模式主要解决的是当控制一个对象状态转换的条件表达式过于复杂时的情况.把状态的判断逻辑转译到表现不同状态的一系列类当中,可以把复杂的判断逻辑简化. 角色和职责 Context:用户对象 拥有一个State类型的成员,以标识对象的当前状态: State:接口或基类 封装与Context的特定状态相关的行为: ConcreteState:接口实现

【设计模式】 模式PK:策略模式VS状态模式

1.概述 行为类设计模式中,状态模式和策略模式是亲兄弟,两者非常相似,我们先看看两者的通用类图,把两者放在一起比较一下. 策略模式(左)和状态模式(右)的通用类图. 两个类图非常相似,都是通过Context类封装一个具体的行为,都提供了一个封装的方法,是高扩展性的设计模式.但根据两者的定义,我们发现两者的区别还是很明显的:策略模式封装的是不同的算法,算法之间没有交互,以达到算法可以自由切换的目的:而状态模式封装的是不同的状态,以达到状态切换行为随之发生改变的目的.这两种模式虽然都有变换的行为,但

职责链模式vs状态模式区别

状态模式在具体状态里设置了下一状态. 而职责链模式是在客户端代码里设置了下一状态的处理对象. 如果状态模式里的任何一环缺失,将导致事情无法进行下去.职责链模式的链式在客户端连接的,也就是说,如果我们请假,请假制度一旦改变,比如说我们不需要班长,或者是先请求老师后直接请求主任或者中间多了一个环节,都是很容易实现的,所以,职责链模式要比状态模式灵活很多. 小时候写日记都是这么写的:上午七点起床,八点之前洗脸刷牙吃早饭,十二点之前好好上课,中午一点,吃午饭,下午两点到六点,上课,下课,找请假,明天妈妈

设计模式之策略模式和状态模式(strategy pattern &amp; state pattern)

本文来讲解一下两个结构比较相似的行为设计模式:策略模式和状态模式.两者单独的理解和学习都是比较直观简单的,但是实际使用的时候却并不好实践,算是易学难用的设计模式吧.这也是把两者放在一起介绍的原因,经过对比和实例介绍,相信应该会一些比较深刻的感知.最后在结合个人的体会简单聊一下对这两个模式的一些看法. 1. 模式概念 1.1 策略模式 运行时更改类的行为或算法,从而达到修改其功能的目的: 使用场景: 一个系统需要动态地在几种算法中选择一种,而这些算法之间仅仅是他们的行为不同. 此外决策过程中过多的

行为型模式之 状态模式

状态模式(State Pattern) :允许一个对象在其内部状态改变时改变它的行为,对象看起来似乎修改了它的类.其别名为状态对象(Objects for States),状态模式是一种对象行为型模式. 主要解决:对象的行为依赖于它的状态(属性),并且可以根据它的状态改变而改变它的相关行为. 何时使用:代码中包含大量与对象状态有关的条件语句. 如何解决:将各种具体的状态类抽象出来. 关键代码:通常命令模式的接口中只有一个方法.而状态模式的接口中有一个或者多个方法.而且,状态模式的实现类的方法,一

设计模式&lt;五&gt;——状态模式

类图 状态模式:当一个对象的内在状态改变时允许改变其行为,这个对象看起来像是改变了其类[DP].主要解决的就是当控制一个状态的条件表达式过于复杂的时候,把状态转移到表示不同状态的一系列类当中.目的是把复杂而冗长的条件判断简化.好处便是将与特性状态相关的行为局部化,并且将不同状态的行为分割开来.

行为型设计模式之状态模式(State)

结构 意图 允许一个对象在其内部状态改变时改变它的行为.对象看起来似乎修改了它的类. 适用性 一个对象的行为取决于它的状态, 并且它必须在运行时刻根据状态改变它的行为. 一个操作中含有庞大的多分支的条件语句,且这些分支依赖于该对象的状态.这个状态通常用一个或多个枚举常量表示.通常, 有多个操作包含这一相同的条件结构.S t a t e模式将每一个条件分支放入一个独立的类中.这使得你可以根据对象自身的情况将对象的状态作为一个对象,这一对象可以不依赖于其他对象而独立变化. 1 using Syste

【设计模式】策略模式 vs 状态模式

相同点:同为行为型策略模式,均通过context类封装一个具体行为,都提供一个封装的方法: 不同点: 1)从定义看:目的不同 策略模式:封装不同的算法,算法间没有交互,达到算法可以自由互换目的:  实际样例:人生不同阶段的主要工作:儿童->玩耍.成年->工作.比如加密算法的互换(AES->RSA) 状态模式:封装不同的状态,达到状态切换后行为随之发生改变的目的.      实际样例:从儿童 切换 成年,因为状态的变化(儿童到成年),主要工作内容发生了改变. 2)具体场景代码比对 场景:人

命令模式、状态模式、责任链模式区别(转)

命令模式:一次设定,统一执行.状态模式:    相当于If else if else:    设计路线:各个State类的内部实现(相当于If,else If内的条件)    执行时通过State调用Context方法来执行.职责链模式:    相当于Swich case    设计路线:客户设定,每个子类(case)的参数是下一个子类(case).    使用时,向链的第一个子类的执行方法传递参数就可以. ———————————————————————————————————— 命令模式:将多