当前位置: 首页 > news >正文

哪家做网站最便宜智博教育的网络营销是什么

哪家做网站最便宜,智博教育的网络营销是什么,手机网站前端开发布局技巧,深圳建设工程交易状态模式 状态模式状态驱动的状态机手工状态机Boost.MSM 中的状态机总结 状态模式 我必须承认:我的行为是由我的状态支配的。如果我没有足够的睡眠#xff0c;我会有点累。如果我喝了酒#xff0c;我就不会开车了。所有这些都是状态(states)#xff0c;它们支配着我的行为:… 状态模式 状态模式状态驱动的状态机手工状态机Boost.MSM 中的状态机总结 状态模式 我必须承认:我的行为是由我的状态支配的。如果我没有足够的睡眠我会有点累。如果我喝了酒我就不会开车了。所有这些都是状态(states)它们支配着我的行为:我的感受我能做什么我不能做什。 当然我可以从一种状态转换到另一种状态。我可以去喝杯咖啡它能让我从瞌睡中清醒过来(我希望如此!)所以我们可以把咖啡当作触发器让你真正从困倦过渡到清醒。这里让我笨拙地为你解释一下 coffee sleepy ---------- alert所以状态设计模式是一个非常简单的想法:状态控制行为;状态可以改变;唯一的问题是谁引发了状态的变更。 基本上有两种方式: 状态是带有行为的实际类这些行为将实际状态从一个转换到另一个状态和转换只是枚举。我们有一个称为状态机(state machine)的特殊组件它执行实际的转换。 这两种方法都是可行的但实际上第二种方法是最常见的。这两种我们都会过一遍但我必须承认我只会简单浏览第一个因为这不是人们通常做事情的方式。 状态驱动的状态机 我们将从最简单的例子开始:一个电灯开关。它只能处于开和关的状态。我们将构建一个任何状态都能够切换到其他状态的模型:虽然这反映了状态设计模式的经典实现(根据GoF的书)但我并不推荐这样做。 首先让我们为电灯开关建模:它只有一种状态和一些从一种状态切换到另一种状态的方法: class LightSwitch {State* state;public:LightSwitch(){state new OffState();}void set_state(State* state){this-state state;} };这一切看起来都很合理。我们现在可以定义状态在这个特定的情况下它将是一个实际的类: struct State {virtual void on(LightSwitch* ls){cout Light is already on\n;}virtual void off(LightSwitch* ls){cout Light is already off\n;} };这个实现很不直观所以我们需要慢慢地仔细地讨论它因为从一开始关于State类的任何东西都没有意义。 首先State不是抽象的!你会认为一个你没有办法(或理由)达到的状态是抽象的。但事实并非如此。 第二状态允许从一种状态切换到另一种状态。这对一个通情达理的人来说毫无意义。想象一下电灯开关:它是改变状态的开关。人们并不指望State本身会改变自己但它似乎就是这样做的。 第三也许是最令人困惑的State::on/off的默认行为声称我们已经处于这种状态!在我们实现示例的其余部分时这一点将在某种程度上结合在一起。 现在我们实现On和Off状态: struct OnState : State {OnState() { cout Light turned on\n; }void off(LightSwitch* ls) override; };struct OffState : State {OffState() { cout Light turned off\n; }void on(LightSwitch* ls) override; };实现OnState::off和OffState::on允许状态本身切换到另一个状态!它看起来是这样的: void OnState::off(LightSwitch* ls) {cout Switching light off...\n;ls-set_state(new OffState());delete this; } // same for OffState::on这就是转换发生的地方。这个实现包含了对delete This的奇怪调用这在真实的c中是不常见的。这对初始分配状态的位置做出了非常危险的假设。例如可以使用智能指针重写这个示例但是使用指针和堆分配清楚地表明状态在这里被积极地销毁。如果状态有析构函数它将触发你将在这里执行额外的清理。 当然我们确实希望开关本身也能切换状态就像这样 class LightSwitch {...void on() { state-on(this); }void off() { state-off(this); } };因此把所有这些放在一起我们可以运行以下场景: 1 LightSwitch ls; // Light turned off 2 ls.on(); // Switching light on... 3 // Light turned on 4 ls.off(); // Switching light off... 5 // Light turned off 6 ls.off(); // Light is already off我必须承认:我不喜欢这种方法因为它不是直观的。当然状态可以被告知(观察者模式)我们正在进入它。但是状态转换到另一种状态的想法——根据GoF的书这是状态模式的经典实现——似乎不是特别令人满意。 如果我们笨拙地说明从OffState到OnState的转换则需要将其说明为 LightSwitch::on() - OffState::on() OffState ------------------------------------- OnState另一方面从OnState到OnState的转换使用基状态类这个类告诉你你已经处于那个状态 LightSwitch::on() - State::on() OnState ---------------------------------- OnState这里给出的示例可能看起来特别人为所以我们现在将看看另一个手工创建的设置其中的状态和转换被简化为枚举成员。 手工状态机 让我们尝试为一个典型的电话会话定义一个状态机。首先我们将描述电话的状态: enum class State {off_hook,connecting,connected,on_hold,on_hook };我们现在还可以定义状态之间的转换也可以定义为enum class: enum class Trigger {call_dialed,hung_up,call_connected,placed_on_hold,taken_off_hold,left_message,stop_using_phone };现在这个状态机的确切规则即可能的转换需要存储在某个地方。 mapState, vectorpairTrigger, State rules;这有点笨拙但本质上map的键是我们移动的状态值是一组表示Trigger-State的对在此状态下可能的触发器以及使用触发器时所进入的状态。 让我们来初始化这个数据结构 rules[State::off_hook] {{Trigger::call_dialed, State::connecting},{Trigger::stop_using_phone, State::on_hook} };rules[State::connecting] {{Trigger::hung_up, State::off_hook},{Trigger::call_connected, State::connected} }; // more rules here我们还需要一个启动状态如果我们希望状态机在达到该状态后停止执行我们还可以添加一个退出(终止)状态 State currentState { State::off_hook }, exitState { State::on_hook };完成这些之后我们就不必为实际运行(我们使用orchestrating这个术语)状态机而构建单独的组件了。例如如果我们想要构建电话的交互式模型我们可以这样做: while(true) {cout The phone is currently currentState endl;select_trigger:cout Select a trigger: \n;int i 0;for(auto item : rules[currentState]){cout i . item.first \n;}int input;cin input;for(input 0 || (input1) rules[currentState].size()){goto select_trigger;}currentState rules[currentState][input].second;if(currentState exitState) break; }首先:是的我确实使用goto这是一个很好的例子说明在什么地方使用goto是合适的译者注一般不建议在程序里面使用goto,这样会使得程序的控制流比较混乱。对于算法本身这是相当明显的:我们让用户在当前状态上选择一个可用的触发器(operator状态和触发器都在幕后实现了)并且如果触发器是有效的我们通过使用前面创建的规则映射转换到它。 如果我们到达的状态是退出状态我们就跳出循环。下面是一个与程序交互的示例。 1 The phone is currently off the hook 2 Select a trigger: 3 0. call dialed 4 1. putting phone on hook 5 0 6 The phone is currently connecting 7 Select a trigger: 8 0. hung up 9 1. call connected 10 1 11 The phone is currently connected 12 Select a trigger: 13 0. left message 14 1. hung up 15 2. placed on hold 16 2 17 The phone is currently on hold 18 Select a trigger: 19 0. taken off hold 20 1. hung up 21 1 22 The phone is currently off the hook 23 Select a trigger: 24 0. call dialed 25 1. putting phone on hook 26 1 27 We are done using the phone这种手工状态机的主要优点是非常容易理解:状态和转换是普通的枚举类转换集是在一个简单的std::map中定义的开始和结束状态是简单的变量 Boost.MSM 中的状态机 在现实世界中状态机要复杂得多。有时你希望在达到某个状态时发生某些操作。在其他时候你希望转换是有条件的也就是说你希望转换只在某些条件存在时发生。 当Boost.MSM (Meta State Machine)一个状态机库是Boost的一部分你的状态机是一个通过CRTP继承自state_ machine_def的类 struct PhoneStateMachine : state_machine_defPhoneStateMachine {bool angry{ false }; }我添加了一个bool变量来指示调用者是否angry(例如在被搁置时); 我们稍后会用到它。现在每个状态也可以驻留在状态机中并且可以从state类继承: struct OffHook : state {}; struct Connecting : state {templateclass Event, class FSMvoid on_entry(Event const evt, FSM){cout We are connecting... endl;}// also on_exit }; // other states omitted如你所见状态还可以定义在进入或退出特定状态时发生的行为。你也可以定义在转换时执行的行为(而不是当你到达一个状态时):这些也是类但它们不需要从任何东西继承;相反它们需要提供具有特定签名的operator(): struct PhoneBeingDestoryed {templateclass EVT, class FSM, class SourceState, class TargetStatevoid operator()(EVT const, FSM SourceState, TargetState){cout Phone breaks into a million pieces endl;} };正如你可能已经猜到的那样这些参数提供了对状态机的引用以及你将要进入和进入的状态。 最后我们有守卫条件(guard condition):这些条件决定我们是否可以在第一时间使用一个转换。现在我们的布尔变量angry不是MSM可用的形式所以我们需要包装它: struct CanDestoryPhone {templateclass EVT, class FSM, class SourceState, class TargetStatebool operator()(EVT const, FSM fsm, SourceState, TargetState){return fsm.angry;} };前面的例子创建了一个名为CanDestroyPhone的守卫条件稍后我们可以在定义状态机时使用它。 为了定义状态机规则Boost.MSM使用MPL(元编程库)。具体来说转换表被定义为mpl::vector每一行依次包含: 源状态状态转换目标状态一个要执行的可选操作一个可选守卫条件 因此有了所有这些我们可以像下面这样定义一些电话呼叫规则 struct transition_table : mpl::vectorRowOffHook, CallDialed, Connecting,RowConnecting, CallConnected, Connected,RowConnected, PlacedOnHold, OnHold,RowOnHold, PhoneThrownIntoWall, PhoneDestoryed, PhoneBeingDestoryed, CanDestoryPhone{};在前面的方法中与状态不同CallDialed之类的转换是可以在状态机类之外定义的类。它们不必继承自任何基类而且很容易为空但它们必须是类型。 transition_table的最后一行是最有趣的:它指定我们只能尝试在CanDestroyPhone保护条件下销毁电话并且当电话实际上被销毁时应该执行PhoneBeingDestroyed操作。 现在我们可以添加更多的东西。首先我们添加起始条件:因为我们正在使用Boost.MSM起始条件是一个类型定义而不是一个变量: typedef OffHook initial_state;最后如果没有可能的转换我们可以定义要发生的操作。它可能发生!比如你把手机摔坏了就不能再用了对吧? template class FSM, class Event void no_transition(Event const e, FSM, int state) {cout No transition from state state_names[state] on event typeid(e).name() endl; }Boost MSM将状态机分为前端(我们刚刚写的)和后端(运行它的部分)。使用后端API我们可以根据前面的状态机定义构造状态机: msm::back::state_machinePhoneStateMachine phone;现在假设存在info()函数它只打印我们所处的状态我们可以尝试orchestrating以下场景 1 info(); // The phone is currently off hook 2 phone.process_event(CallDialed{}); // We are connecting... 3 info(); // The phone is currently connecting 4 phone.process_event(CallConnected{}); 5 info(); // The phone is currently connected 6 phone.process_event(PlacedOnHold{}); 7 info(); // The phone is currently on hold 8 9 phone.process_event(PhoneThrownIntoWall{}); 10 // Phone breaks into a million pieces 11 12 info(); // The phone is currently destroyed 13 14 phone.process_event(CallDialed{}); 15 // No transition from state destroyed on event struct CallDialed因此这就是定义更复杂、具有工业强度的状态机的方式。 总结 首先这是值得强调的Boost.MSM是Boost中两种状态机实现之一另一种是Boost.statechart。我很确定还有很多其他的状态机实现。 其次状态机的功能远不止这些。例如许多库支持分层状态机的思想:例如一个生病(Sick)的状态可以包含许多不同的子状态如流感(Flu)或水痘(Chickenpox)。如果你在处于感染流感的状态你也同时处于生病的状态。 最后有必要再次强调现代状态机与状态设计模式的原始形式之间的差异。重复api的存在(例如LightSwitch::on/off vs. State::on/off)以及自删除的存在在我的书中是明确的代码气味。不要误会我的方法是有效的但它是不直观的和繁琐的。
http://www.hkea.cn/news/14570070/

相关文章:

  • 厦门模板网站苏州建设交通高等职业技术学校
  • 建服务网站需要多少钱17网站一起做网店的流程
  • 怎么做网站流量统计惠州市两学一做网站
  • 本地拖拽网站建设上海新增感染呈下降趋势
  • 网站建设链接毕业设计 网站建设选题
  • 佛山企业网站设计惠州企业网站seo
  • wordpress双站 中英文在中国建设工程造价管理协会网站
  • 官方制作网站长沙网站seo报价
  • 网站首页被k 做跳转怎么做系部网站首页
  • 高清免费观看电视网站如何把自己做的网站
  • 做公众号必了解的网站域名收录提交入口
  • 蓝色 宽屏 网站 模板下载餐饮网站方案
  • 做打鱼网站需要多少钱企业邮箱如何申请
  • 做类似简书的网站俄罗斯ip地址
  • 网站布局的好坏的几个要素雨花区最新情况
  • 自助建站基础工作主要包括()深圳网站建设推选上榜网络
  • 手机端网站加盟网站开发重点难点
  • 金融行业网站开发易企秀h5制作官网
  • php做的网站安全吗怎么投诉网站制作公司
  • 网站怎么做才被收录快正邦设计招聘
  • 医院网站开发违法吗做PS的赚钱的网站
  • 做的好的微信商城网站能上外国网站dns
  • 网站模板怎么改移动网站有哪些
  • 网站建设设计平台做外贸怎么登陆国外网站
  • 淄博 网站建设个人网站设计图片
  • 坂田做网站的公司给自己广告公司宣传
  • 用群晖nas做网站创业项目排行榜前十名
  • 网站建设企业排行榜wordpress快速部署
  • 手机网站用模版苏州互联网公司集中在哪里
  • 东莞网站开发前三强网站建设需要什么条件