状态模式

策略模式的孪生兄弟---状态模式

 ̄綄美尐妖づ 提交于 2019-12-22 09:14:10
人的机缘是神奇的,认识一个人就相当于打开了一个圈子,不管这个人是否在圈子中心,而这点,会在不经意间带给我们意想不到的作用。 如果我们在编写代码的时候,遇到大量的条件判断的时候,可能会采用策略模式来优化结构,因为这时涉及到策略的选择,但有时候仔细查看下,就会发现,这些所谓的策略其实是对象的不同状态,更加明显的是,对象的某种状态也成为判断的条件。 我们还是以一个例子入手。 假设现在我们有一个饮水机,它有以下两个状态: 满桶,空桶。初始状态是满桶,容量是20。饮水机只有一个动作:press,每次press后都会使容量减1,一旦为0,则将状态设置为空桶,这时press没有水流出。 要使用状态模式,我们必须明确两个东西:状态和每个状态下执行的动作。就像是饮水机,最基本的状态就是满桶和空桶,而这两个状态下,都可能要执行倒水这个动作,也就是press。如果饮水机的容量为0,则会进入空桶的状态。 在状态模式中,因为所有的状态都要执行相应的动作,所以我们可以考虑将状态抽象出来。 状态的抽象一般有两种形式:接口和抽象类。如果所有的状态都有共同的数据域,可以使用抽象类,但如果只是单纯的执行动作,就可以使用接口。 这里我们就用接口。 public interface DispenserState { void press(); } 然后我们再定义满桶和空桶两个状态: public class

设计模式----状态模式

夙愿已清 提交于 2019-12-18 12:43:33
允许一个对象在其内部状态改变时改变它的行为,对象看起来似乎修改了它所属的类 状态state模式是GOF23种模式中的一种,和命令模式一样,也是一种行为模式。状态模式和命令模式相当像,一样是“接口—实现类”这种模式的应用,是面向接口编程原则的体现。 状态模式属于对象创建型模式,其意图是允许一个对象在其内部状态改变时改变它的行为,对象看起来似乎修改了他的类。比较常见的例子是在一个表示网络连接的类TCPConnection,一个TCPConnection对象的状态处于若干不同的状态之一:连接已经建立(Established),正在监听,连接已经关闭(closed)。当一个TCPConnection对象收到其他对象的请求时,他根据自身的状态作出不同的反应。 例如:一个Open请求的结果依赖于该连接已关闭还是连接已建立状态。State模式描述了TCPConnection如何在每一种状态下表现出不同的行为。这一种模式的关键思想是引入了一个称为TCPState的抽象类表示网络的连接状态,TCPState类为各种表示不同的操作状态的字类声明了一个公共接口。TCPState的子类实现与特定的状态相关的行为。例如,TCPEstablished和TCPClosed类分别实现了特定于TCPConnection的连接已建立状态和连接已关闭状态的行为。 举例来说:一个人具有生气,高兴和抓狂等状态

Python笔记:状态设计模式

柔情痞子 提交于 2019-12-17 23:45:35
状态模式可以看做是在运行时改变对象行为的一种方式。状态模式允许对象在其内部状态变化时改变其行为,此时感觉就像对象本身已经改变了一样。 参与者: State接口: State基类,定义不同状态共同需要执行的接口。 ConcreteSate对象: State基类的子类,不同状态的可以在子类接口中实现不同的操作。 Context对象: 客户端需要关注的对象,此对象中维护自身的具体状态对象,当状态改变时,改变的是Context中的状态对象,而Context对象是不需要改变的。 优点: 对象的行为是根据运行时对象的状态而定,避免了使用大量的条件判断来改变代码逻辑。 状态模式中,更加容易添加新的行为,只需要定义一个额外的状态即可。 提高了编码的聚合性,使得属于同种状态的操作被归于一个类中。 缺点: 由于状态本身的功能过于单一,可能会创建过多的状态类,导致使用和维护都会变得非常麻烦。 对于Context对象,每个状态的引入,都可能需要进行更新,并且每次更新都可能会影响到原来的行为,导致Context对象的维护变得更加困难。 简单示例: """ 以电饭煲为例,它有三种状态或者说三种功能:煮饭、煮汤、煮粥 指定好电饭煲的状态后,它就开始以对应模式进行工作 """ from abc import ABCMeta, abstractmethod class CookState(metaclass

观察者模式

╄→尐↘猪︶ㄣ 提交于 2019-12-17 20:24:11
1 什么时候会用到此设计模式? 1) 当一个抽象模型有两个方面, 其中一个方面依赖于另一方面。将这二者封装在独立的对象中以使它们可以各自独立地改变和复用。 2) 当对一个对象的改变需要同时改变其它对象, 而不知道具体有多少对象有待改变。 3) 当一个对象必须通知其它对象,而它又不能假定其它对象是谁。换言之, 你不希望这些对象是紧密耦合的。 1. 概述   有时被称作发布/订阅模式,观察者模式定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象。这个主题对象在状态发生变化时,会通知所有观察者对象,使它们能够自动更新自己。 2. 解决的问题   将一个系统分割成一个一些类相互协作的类有一个不好的副作用,那就是需要维护相关对象间的一致性。我们不希望为了维持一致性而使各类紧密耦合,这样会给维护、扩展和重用都带来不便。观察者就是解决这类的耦合关系的。 3. 模式中的角色   3.1 抽象主题(Subject):它把所有观察者对象的引用保存到一个聚集里,每个主题都可以有任何数量的观察者。抽象主题提供一个接口,可以增加和删除观察者对象。   3.2 具体主题(ConcreteSubject):将有关状态存入具体观察者对象;在具体主题内部状态改变时,给所有登记过的观察者发出通知。   3.3 抽象观察者(Observer):为所有的具体观察者定义一个接口,在得到主题通知时更新自己。

设计模式再学习(下)

前提是你 提交于 2019-12-17 13:05:47
理解设计模式前的前堤: 1、模式的应用目标是把可维护性作为很重要指标的程序,像一次性的Demo程序就不需要多高的可维护性; 2、意识到并认可面向接口编程的好处,不认可请回看1; 3、设计模式的本质是解耦,解耦的根本手段是分层,分的层越多,关系越不直观; 4、不用设计模式完全不影响实现需求,只是写的代码多了,重构多了,写着写着,也就进入了设计模式的“窠臼”。 行为型模式 模板方法模式 模板方法也是用得很多的一种模式,尤其是在重构系统时。当你在两个以上相同的类,代码几乎一模一样,只有少许区别时,就要考虑是否用模板方法模式进行重构。父类定好算法步骤,通常将变化的部分封装成abstract方法,由子类实现该abstract方法。从另一个角度来看模板方法,其实它是对面向对象多态的补充,试想一下,多态是父类(接口)定好接口,子类分别实现之,可现实情况并不会总是如此简单,有些是可复用的部分,让每个子类各自重复实现这些可复用的代码明显是有问题的,重构方法就是把这部分可复用的代码前置到父类去写一份即可,那重构后不就是模板方法的应用了么?缺点就是父类调用子类方法,会增加调试的复杂性。 策略模式 既然是策略,那就是对调用方暴露的,即调用方需要了解有哪些策略。面向接口编程使得策略之间可以互相替换,变化部分通过策略类封装起来,也就意味着一个事情可以有多种实现方案,在使用if..

Head First设计模式之目录

不想你离开。 提交于 2019-12-16 21:57:46
一、定义 观察者设计模式定义了对象间的一种一对多的依赖关系,以便一个对象的状态发生变化时,所有依赖于它的对象都得到通知并自动刷新。 有时被称作发布/订阅模式,观察者模式定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象。这个主题对象在状态发生变化时,会通知所有观察者对象,使它们能够自动更新自己。 观察者模式是写松耦合代码的必备模式。 二、结构 三、实现 //被观察者 public interface IObject { IList<IMonitor> ListMonitor { get; set; } //定义观察者集合,因为多个观察者观察一个对象,所以这里用集合 string SubjectState { get; set; } //被观察者的状态 void AddMonitor(IMonitor monitor); //添加一个观察者 void RemoveMonitor(IMonitor monitor); //移除一个观察者 void SendMessage(); //向所有观察者发送消息 } public class Subject : IObject { private IList<IMonitor> listMonitor = new List<IMonitor>(); public string SubjectState //被观察者的状态 {

设计模式-状态模式

故事扮演 提交于 2019-12-16 07:19:52
状态模式 定义 状态模式允许一个对象在其内部状态改变时改变它的行为,对象看起来似乎修改了它所属的类,属于行为型模式 状态模式类图 环境(Context)角色 ,也成上下文:定义客户端所感兴趣的接口,并且保留一个具体状态类的实例。这个具体状态类的实例给出此环境对象的现有状态。 抽象状态(State)角色 :定义一个接口,用以封装环境(Context)对象的一个特定的状态所对应的行为。 具体状态(ConcreteState)角色 :每一个具体状态类都实现了环境(Context)的一个状态所对应的行为。 状态模式例子 我们通常购物的时候,我们会先下订单,这个时候订单的状态就是待付款状态,这个时候我们可以去付款,付完款了,订单的状态就是待发货状态,这个时候订单可以去发货,商家发货了,这个时候订单的状态就是运送中,这个时候我们可以去收货,当我们确认收货了,订单的状态变成待评价状态,这个时候我们可以去评价订单,现在我们来用状态模式完成这个流程 先定义状态接口,里面有几个方法 public interface OrderState { // 付款 public void pay ( ) ; // 发货 public void deliver ( ) ; // 收货 public void takeDeliver ( ) ; // 评价 public void appraise ( ) ; } /

状态模式

断了今生、忘了曾经 提交于 2019-12-13 20:25:42
在软件开发过程中,应用程序中的有些对象可能会根据不同的情况做出不同的行为,我们把这种对象称为有状态的对象,而把影响对象行为的一个或多个动态变化的属性称为状态。当有状态的对象与外部事件产生互动时,其内部状态会发生改变,从而使得其行为也随之发生改变。如人的情绪有高兴的时候和伤心的时候,不同的情绪有不同的行为,当然外界也会影响其情绪变化。 对这种有状态的对象编程,传统的解决方案是:将这些所有可能发生的情况全都考虑到,然后使用 if-else 语句来做状态判断,再进行不同情况的处理。但当对象的状态很多时,程序会变得很复杂。而且增加新的状态要添加新的 if-else 语句,这违背了“开闭原则”,不利于程序的扩展。 以上问题如果采用“状态模式”就能很好地得到解决。状态模式的解决思想是:当控制一个对象状态转换的条件表达式过于复杂时,把相关“判断逻辑”提取出来,放到一系列的状态类当中,这样可以把原来复杂的逻辑判断简单化。 状态模式的定义与特点 状态(State)模式的定义:对有状态的对象,把复杂的“判断逻辑”提取到不同的状态对象中,允许状态对象在其内部状态发生改变时改变其行为。 状态模式是一种对象行为型模式,其主要优点如下。 状态模式将与特定状态相关的行为局部化到一个状态中,并且将不同状态的行为分割开来,满足“单一职责原则”。 减少对象间的相互依赖

JavaScript设计模式之状态模式

孤街醉人 提交于 2019-12-10 16:50:48
什么是状态模式? 状态模式是一种非同寻常的优秀模式,它也许是解决某些需求场景的最好方法。虽然状态模式并不是一种简单到一目了然的模式(它往往还会带来代码量的增加),但你一旦明白了状态模式的精髓,以后一定会感谢它带给你的无与伦比的好处。 状态模式的关键是区分事物内部的状态,事物内部状态的改变往往会带来事物的行为改变。 初识状态模式 我们来想象这样一个场景:有一个电灯,电灯上面只有一个开关。当电灯开着的时候,此时按下开关,电灯会切换到关闭状态;再按一次开关,电灯又将被打开。同一个开关按钮,在不同的状态下,表现出来的行为是不一样的。 现在用代码来描述这个场景,首先定义一个Light类,可以预见,电灯对象light将从Light类创建而出, light对象将拥有两个属性,我们用state来记录电灯当前的状态,用button表示具体的开关按钮。下面 来编写这个电灯程序的例子。 第一个例子:电灯程序 首先给出不用状态模式的电灯程序实现: var Light = function(){ this.state = 'off'; // 给电灯设置初始状态off this.button = null; // 电灯开关按钮 }; 接下来定义Light.prototype.init方法,该方法负责在页面中创建一个真实的button节点,假设这个button就是电灯的开关按钮,

状态(State)模式--设计模式

懵懂的女人 提交于 2019-12-09 20:15:23
定义与特点 1.1 定义 状态模式允许一个对象在其内部状态改变的时候改变其行为.这个对象看上去就像是改变了它的类一样. 1.2 特点 状态模式优点: 封装了转换规则,并枚举可能的状态,它将所有与某个状态有关的行为放到一个类中,并且可以方便地增加新的状态,只需要改变对象状态即可改变对象的行为. 多个环境对象共享一个状态对象,从而减少系统中对象的个数. 状态模式缺点: 使用状态模式会增加系统类和对象的个数,且状态模式的结构与实现都较为复杂,如果使用不当将导致程序结构和代码的混乱,对于可以切换状态的状态模式不满足“开闭原则”的要求. 角色与结构 2.1 角色 环境(Context)角色,也成上下文:定义客户端所感兴趣的接口,并且保留一个具体状态类的实例.这个具体状态类的实例给出此环境对象的现有状态. 抽象状态(State)角色:定义一个接口,用以封装环境(Context)对象的一个特定的状态所对应的行为. 具体状态(ConcreteState)角色:每一个具体状态类都实现了环境(Context)的一个状态所对应的行为. 2.2 结构 示例Demo 3.1 环境Context角色 class Context { var state:State? func request(day:Int) { if day <= 1 { self.state = BuyState() } else if