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

长沙网站建设维护江西网络推广seo

长沙网站建设维护,江西网络推广seo,网站开发销售提成,软件开发培训机构去哪个学校原创#xff1a; 张卫滨 译 Jean-Jacques Dubray是一名资深工程师#xff0c;他最近引入了一个新的模式#xff1a;状态-行为-模(State-Action-Model#xff0c;SAM)。SAM是一个函数式反应型的编程模式#xff0c;它致力于简化数据Model和View之间的交互。它究竟有何优点值…原创 张卫滨 译 Jean-Jacques Dubray是一名资深工程师他最近引入了一个新的模式状态-行为-模(State-Action-ModelSAM)。SAM是一个函数式反应型的编程模式它致力于简化数据Model和View之间的交互。它究竟有何优点值得作者弃用MVC呢话题起因在我最近的工作中最让人抓狂的就是为前端开发人员设计API。我们之间的对话大致就是这样的开发人员这个页面上有数据元素x,y,z…你能不能为我创建一个API响应格式为{x: , y:, z: }我好吧我甚至没有进行进一步的争论。项目结束时会积累大量的API这些API与经常发生变化的页面是关联在一起的按照“设计”只要页面改变相应的API也要随之变化而在此之前我们甚至对此毫不知情最终由于形成因素众多且各平台之间存在些许差异必须创建非常多的API来满足这些需求。Sam Newman甚至将这种制度化的过程称之为BFF模式这种模式建议为每种设备、平台当然还包含APP版本开发特定的API。 Daniel Jacobson在接受InfoQ的采访时曾指出Netflix颇为勉强地将“体验式API”与“临时API(Ephemeral API)”划上了等号。 唉……几个月前我开始思考是什么造成了如今的这种现象该做些什么来应对它这个过程使我开始质疑应用架构中最强大的理念也就是MVC我感受到了函数式反应型编程(reactive)的强大威力这个过程致力于流程的简化并试图消除我们这个行业在生产率方面的膨胀情绪。我相信你会对我的发现感兴趣的。MVC的辉煌过去与现存问题在每个用户界面背后我们都在使用MVC模式也就是模型-视图-控制器(Model-View-Controller)。MVC发明的时候Web尚不存在当时的软件架构充其量是胖客户端在原始网络中直接与单一数据库会话。但是几十年之后MVC依然在使用持续地用于OmniChannel应用的构建。Angular 2正式版即将发布在这个时间节点重估MVC模式及各种MVC框架为应用架构带来的贡献意义重大。我第一次接触到MVC是在1990年当时NeXT刚刚发布Interface Builder(让人惊讶的是如今这款软件依然发挥着重大的作用)。当时我们感觉Interface Builder和MVC是一个很大的进步。在90年代末期MVC模式用到了HTTP上的任务中(还记得Struts吗)如今就各个方面来讲MVC是所有应用架构的基本原则。MVC的影响十分深远以致于React.js在介绍他们的框架时都委婉地与其划清界限“React实现的只是MVC中视图(View)的部分”。当我去年开始使用React的时候我感觉它在某些地方有着明显的不同你在某个地方修改一部分数据不需要显式地与View和Model进行交互整个UI就能瞬间发生变化(不仅仅是域和表格中的值)。这也就是说我很快就对React的编程模型感到了失望在这方面我显然并不孤独。我分享一下Andre Medeiros的观点React在很多方面都让我感到失望它主要是通过设计不佳的API来引导程序员[…]将多项关注点混合到一个组件之中。 作为服务端的API设计者我的结论是没有特别好的方式将API调用组织到React前端中这恰恰是因为React只关注View在它的编程模型中根本不存在控制器。到目前为止Facebook一直致力于在框架层面弥合这一空白。React团队起初引入了Flux模式不过它依然令人失望最近Dan Abramov又提倡另外一种模式名为Redux在一定程度上来讲它的方向是正确的但是在将API关联到前端方面依然比不上我下面所介绍的方案。Google发布过GWT、Android SDK还有Angular你可能认为他们的工程师熟知何为最好的前端架构但是当你阅读Angular 2设计考量的文章时便会不以为然即便在Google大家也达成这样的共识他们是这样评价之前的工作成果的Angular 1并不是基于组件的理念构建的。相反我们需要将控制器与页面上各种[元素]进行关联(attach)其中包含了我们的自定义逻辑。根据我们自定义的指令如何对其进行封装(是否包含isolate scope)scope会进行关联或继续往下传递。基于组件的Angular 2看起来能简单一点吗其实并没有好多少。Angular 2的核心包本身就包含了180个语义(semantics)整个框架的语义已经接近500个这是基于HTML5和CSS3的。谁有那么多时间学习和掌握这样的框架来构建Web应用呢当Angular 3出现的时候情况又该是什么样子呢在使用过React并了解了Angular 2将会是什么样子之后我感到有些沮丧这些框架都系统性地强制我使用BFF“页面可替换模式(Screen Scraping)”模式按照这种模式每个服务端的API要匹配页面上的数据集不管是输入的还是输出的。弃用MVC之后怎么走此时我决定“让这一切见鬼去吧”。我构建了一个Web应用没有使用React、没有使用Angular也没有使用任何其他的MVC框架通过这种方式我看一下是否能够找到一种在View和底层API之间进行更好协作的方式。就React来讲我最喜欢的一点在于Model和View之间的关联关系。React不是基于模板的View本身没有办法请求数据(我们只能将数据传递给View)看起来针对这一点进行探索是一个很好的方向。如果看得足够长远的话你会发现React唯一的目的就是将View分解为一系列(纯粹的)函数和JSX语法它实际上与下面的格式并没有什么差别 V f( M )例如我当前正在从事项目的Web站点 Gliiph就是使用这种函数构建的图1用于生成站点Slider组件HTML的函数这个函数需要使用Model来填充数据图2支撑slider的Model如果用简单的JavaScript函数就能完成任务我们为什么还要用React呢虚拟DOM(virtual-dom)如果你觉得需要这样一种方案的话(我并不确定有很多的人需要这样)其实有这样的可选方案我也期望开发出更多的方案。GraphQL并不完全如此。不要因为Facebook大量使用它就对其产生误解认为它一定是对你有好处的。GraphQL仅仅是以声明的方式来创建视图模型。强制要求Model匹配View会给你带来麻烦而不是解决方案。React团队可能会觉得使用“客户端指定查询(Client-specified queries)”是没有问题的(就像反应型团队中那样)GraphQL完全是由View以及编写它们的前端工程师的需求所驱动的。[…]另一方面GraphQL查询会精确返回客户端请求的内容除此之外也就没什么了。GraphQL团队没有关注到JSX语法背后的核心思想用函数将Model与View分离。与模板和“前端工程师所编写的查询”不同函数不需要Model来适配View。当View是由函数创建的时候(而不是由模板或查询所创建)我们就可以按需转换Model使其按照最合适的形式来展现View不必在Model的形式上添加人为的限制。例如如果View要展现一个值v有一个图形化的指示器会标明这个值是优秀、良好还是很差我们没有理由将指示器的值放到Model中函数应该根据Model所提供的v值来进行简单的计算从而确定指示器的值。现在把这些计算直接嵌入到View中并不是什么好主意使View-Model成为一个纯函数也并非难事因此当我们需要明确的View-Model时就没有特殊的理由再使用GraphQL了 V f( vm(M) )作为深谙MDE之道的人我相信你更善于编写代码而不是元数据不管它是模板还是像GraphQL这样的复杂查询语言。这个函数式的方式能够带来多项好处。首先与React类似它允许我们将View分解为组件。它们创建的较为自然的界面允许我们为Web应用或Web站点设置“主题”或者使用不同的技术来渲染View(如原生的方式)。函数实现还有可能增强我们实现反应型设计的方式。在接下来的几个月中可能会出现开发者交付用JavaScript函数包装的基于组件的HTML5主题的情况。这也是最近这段时间在我的Web站点项目中我所采用的方式我会得到一个模板然后迅速地将其封装为JavaScript函数。我不再使用WordPress。基本上花同等的工夫(甚至更少)我就能实现HTML5和CSS的最佳效果。这种方式也需要在设计师和开发人员之间建立一种新型的关系。任何人都可以编写这些JavaScript函数尤其是模板的设计人员。人们不需要学习绑定方法、JSX和Angular模板的语法只掌握简单的JavaScript核心函数就足以让这一切运转起来。有意思的是从反应型流程的角度来说这些函数可以部署在最合适的地方在服务端或在客户端均可。但最为重要的是这种方式允许在View与Model之间建立最小的契约关系让Model来决定如何以最好的方式将其数据传递给View。让Model去处理诸如缓存、懒加载、编配以及一致性的问题。与模板和GraphQL不同这种方式不需要从View的角度来直接发送请求。既然我们有了一种方式将Model与View进行解耦那么下一个问题就是在这里该如何创建完整的应用模型呢“控制器”该是什么样子的为了回答这个问题让我们重新回到MVC上来。苹果公司了解MVC的基本情况因为他们在上世纪80年代初从Xerox PARC“偷来了”这一模式从那时起他们就坚定地实现这一模式图3MVC模式Andre Medeiros曾经清晰地指出这里核心的缺点在于 MVC模式是“交互式的(interactive)”(这与反应型截然不同)。在传统的MVC之中Action(Controller)将会调用Model上的更新方法在成功(或出错)之时会确定如何更新View。他指出其实并非必须如此这里还有另外一种有效的、反应型的处理方式我们只需这样考虑Action只应该将值传递给Model不管输出是什么也不必确定Model该如何进行更新。那核心问题就变成了该如何将Action集成到反应型流程中呢如果你想理解Action的基础知识的话那么你应该看一下TLA。TLA代表的是“Action中的逻辑时序(Temporal Logic of Actions)”这是由Dr. Lamport所提出的学说他也因此获得了图灵奖。在TLA中Action是纯函数 data’ A (data)我真的非常喜欢TLA这个很棒的理念因为它强制函数只转换给定的数据集。按照这种形式反应型MVC看起来可能就会如下所示 V f( M.present( A(data) ) ) 这个表达式规定当Action触发的时候它会根据一组输入(例如用户输入)计算一个数据集这个数据是提交到Model中的然后会确定是否需要以及如何对其自身进行更新。当更新完成后View会根据新的Model状态进行更新。反应型的环就闭合了。Model持久化和获取其数据的方式是与反应型流程无关的所以它理所应当地“不应该由前端工程师来编写”。不必因此而感到歉意。再次强调Action是纯函数没有状态和其他的副作用(例如对于Model不会包含计数的日志)。反应型MVC模式很有意思因为除了Model以外所有的事情都是纯函数。公平来讲Redux实现了这种特殊的模式但是带有React不必要的形式并且在reducer中Model和Action之间存在一点不必要的耦合。Action和接口之间是纯粹的消息传递。这也就是说反应型MVC并不完整按照Dan喜欢的说法它并没有扩展到现实的应用之中。让我们通过一个简单的样例来阐述这是为什么。假设我们需要实现一个应用来控制火箭的发射一旦我们开始倒计时系统将会递减计数器(counter)当它到达零的时候会将Model中所有未定的状态设置为规定值火箭的发射将会进行初始化。这个应用有一个简单的状态机图4火箭发射的状态机其中decrement和launch都是“自动”的Action这意味着我们每次进入(或重新进入)counting状态时将会保证进行转换的评估如果计数器的值大于零的话decrement Action将会继续调用如果值为零的话将会调用launchAction。在任何的时间点都可以触发abort Action这样的话控制系统将会转换到aborted状态。在MVC中这种类型的逻辑将会在控制器中实现并且可能会由View中的一个计时器来触发。这一段至关重要所以请仔细阅读。我们已经看到在TLA中Action没有副作用只是计算结果的状态Model处理Action的输出并对其自身进行更新。这是与传统状态机语义的基本区别在传统的状态机中Action会指定结果状态也就是说结果状态是独立于Model的。在TLA中所启用的Action能够在状态表述(也就是View)中进行触发这些Action不会直接与触发状态转换的行为进行关联。换句话说状态机不应该由连接两个状态的元组(S1, A, S2)来进行指定传统的状态机是这样做的它们元组的形式应该是(Sk, Ak1, Ak2,…)这指定了所有启用的Action并给定了一个状态SkAction应用于系统之后将会计算出结果状态Model将会处理更新。当我们引入“state”对象时TLA提供了一种更优秀的方式来对系统进行概念化它将Action和view(仅仅是一种状态的表述)进行了分离。我们样例中的Model如下所示model { counter: , started: , aborted: , launched: }系统中四个(控制)状态分别对应于Model中如下的值 ready {counter: 10, started: false, aborted: false, launched: false } counting {counter: [0..10], started: true, aborted: false, launched: false } launched {counter: 0, started: true, aborted: false, launched: true} aborted {counter: [0..10], started: true, aborted: true, launched: false}这个Model是由系统的所有属性及其可能的值所指定的状态则指定了所启用的Action它会给定一组值。这种类型的业务逻辑必须要在某个地方进行实现。我们不能指望用户能够知道哪个Action是否可行。在这方面没有其他的方式。不过这种类型的业务逻辑很难编写、调试和维护在没有语义对其进行描述时更是如此比如在MVC中就是这样。让我们为火箭发射的样例编写一些代码。从TLA角度来讲next-action断言在逻辑上会跟在状态渲染之后。当前状态呈现之后下一步就是执行next-action断言如果存在的话将会计算并执行下一个Action这个Action会将其数据交给ModelModel将会初始化新状态的表述以此类推。图5火箭发射器的实现需要注意的是在客户端/服务器架构下当自动Action触发之后我们可能需要使用像WebSocket这样的协议(或者在WebSocket不可用的时候使用轮询机制)来正确地渲染状态表述。我曾经使用Java和JavaScript编写过一个很轻量级的开源库它使用TLA特有的语义来构造状态对象并提供了样例这些样例使用WebSocket、轮询和队列实现浏览器/服务器交互。在火箭发射器的样例中可以看到我们并非必须要使用那个库。一旦理解了如何编写状态实现的编码相对来讲是很容易的。新模式——SAM模式对于要引入的新模式来说我相信我们已经具备了所有的元素这个新模式作为MVC的替代者名为SAM模式(状态-行为-模型State-Action-Model)它具有反应型和函数式的特性灵感来源于React.js和TLA。SAM模式可以通过如下的表达式来进行描述 V S( vm( M.present( A(data) ) ), nap(M))它表明在应用一个Action A之后View V可以计算得出Action会作为Model的纯函数。在SAM中A(Action)、vm(视图-模型view-model)、nap(next-action断言)以及S(状态表述)必须都是纯函数。在SAM中我们通常所说的“状态”(系统中属性的值)要完全局限于Model之中改变这些值的逻辑在Model本身之外是不可见的。随便提一下next-action断言即nap()是一个回调它会在状态表述创建完成并渲染给用户时调用。图6状态-行为-模型(SAM)模式模式本身是独立于任何协议的(可以不费什么力气就能在HTTP上实现)和客户端/服务器拓扑结构的。SAM并不意味着我们必须要使用状态机的语义来获取View的内容。如果Action是由View触发的那next-action断言就是一个空函数。不过这可能是一个很好的实践它清晰暴露了底层状态机的控制状态因为根据(控制)状态的不同View看起来可能也是不同的。另一方面如果你的状态机涉及到自动化的Action那么Action和Model都不可能做到纯粹的不包含next-action断言有些Action将会变得有状态或者Model必须要触发Action而这本来并不是它的角色。顺便提一下也许并不那么直观状态对象并没有持有任何的“状态”它同样也是纯函数它会渲染View并计算next-action断言这两者都来源于Model的属性值。这种新模式的好处在于它清晰地将CRUD操作从Action中分离了出来。Model负责它的持久化将会通过CRUD操作来实现通过View是无法进行访问的。尤其是View永远不会处于“获取”数据的位置View所能做的唯一的事情就是请求系统中当前的状态表述并通过触发Action初始化一个反应型流程。Action仅仅代表了一种具有权限的通道以此来建议Model该怎样进行变更。它们本身(在Model方面)并没有什么副作用。如果必要的话Action会调用第三方的API(同样对Model没有副作用)比如说修改地址的Action可能会希望调用地址校验服务并将服务返回的地址提交到Model中。如下就是“修改地址”Action该如何进行实现它会调用地址校验的API图7“修改地址”的实现模式中的元素包括Action和Model可以进行自由地组合函数组合data’ A(B(data))端组合(Peer)(相同的数据集可以提交给两个Model)M1.present(data’)M2.present(data’)父子组合(父Model控制的数据集提交给子Model)M1.present(data’,M2)function present(data, child) { // 执行更新 … // 同步Model child.present(c(data))}发布/订阅组合M1.on(“topic”, present )M2.on(“topic”, present )或M1.on(“data”, present )M2.on(“data”, present )有些架构师可能会考虑到System of Record和Systems of Engagement这种模式有助于明确这两层的接口(图8)Model会负责与systems of record的交互。图8SAM组合模型整个模式本身也是可以进行组合的我们可以实现运行在浏览器中的SAM实例使其支持类似于向导(wizard)的行为(如ToDo应用)它会与服务器端的SAM进行交互图9SAM实例组合请注意里层的SAM实例是作为状态表述的一部分进行传送的这个状态表述是由外层的实例所生成的。会话检查应该在Action触发之前进行(图10)。SAM能够启用一项很有意思的组合在将数据提交给Model之前View可以调用一个第三方的Action并且要为其提供一个token和指向系统Action的回调这个第三方Action会进行授权并校验该调用的合法性。图10借助SAM实现会话管理从CQRS的角度来讲这个模式没有对查询(Query)和命令(Command)做特殊的区分但是底层的实现需要进行这种区分。搜索或查询“Action”只是简单地传递一组参数到Model中。我们可以采用某种约定(如下划线前缀)来区分查询和命令或者我们可以在Model上使用两个不同的present方法{ _name : ‘/^[a]$/i’ } // 名字以A或a开头{ _customerId: ‘123’ } // id123的customerModel将会执行必要的操作以匹配查询更新其内容并触发View的渲染。类似的约定可以用于创建、更新或删除Model中的元素。在将Action的输出传递给Model方面我们可以实现多种方式(数据集、事件、Action……)。每种方式都会有其优势和不足最终这取决于个人偏好。我更喜欢数据集的方式。在异常方面与React类似我们预期Model会以属性值的形式保存异常信息(这些属性值可能是由Action提交的也可能是CRUD操作返回的)。在渲染状态表述的时候会用到属性值以展现异常信息。在缓存方面SAM在状态表述层提供了缓存的选项。直观上来看缓存这些状态表述函数的结果能够实现更高的命中率因为我们现在是在组件/状态层触发缓存而不是在Action/响应层。该模式的反应型和函数式结构使得功能重放(replay)和单元测试变得非常容易。SAM模式完全改变了前端架构的范式因为根据TLA的基础理念业务逻辑可以清晰地描述为Action是纯函数CRUD操作放在Model中状态控制自动化的Action作为API的设计者从我的角度来讲这种模式将API设计的责任推到了服务器端在View和Model之间保持了最小的契约。Action作为纯函数能够跨Model重用只要某个Model能够接受Action所对应的输出即可。我们可以期望Action库、主题(状态表述)甚至Model能够繁荣发展起来因为它们现在能够独立地进行组合。借助SAM模式微服务能够非常自然地支撑Model。像Hivepod.io这样的框架能够插入进来就像它本来就在这层似得。最为重要的是这种模式像React一样不需要任何的数据绑定或模板。随着时间的推移我希望能够推动浏览器永久添加虚拟DOM的特性新的状态表述能够通过专有API直接进行处理。我发现这个旅程将会带来一定的革新性在过去的几十年中面向对象似乎无处不在但它已经一去不返了。我现在只能按照反应型和函数式来进行思考。我借助SAM所构建的东西及其构建速度都是前所未有的。另外我能够关注于API和服务的设计它们不再遵循由前端决定的模式。最后我自己是一名从事了多年开发的Java老程序员辞职目前在做自己的Java私人定制课程今年年初我花了一个月整理了一份最适合2019年学习的Java学习干货可以送给每一位喜欢Java的小伙伴想要获取的可以关注我的头条号并在后台私信我01即可免费获取。
http://www.sadfv.cn/news/267211/

相关文章:

  • 单页面网站做排名做淘宝客网站的流程
  • 黄页88网是什么性质的网站哈尔滨市建设工程网
  • 定制网站制作公司有哪些建设银行企业网站打不开
  • 家装效果图设计网站昆明市网站建设
  • 域名出售网站wordpress 电脑微信登陆不了
  • 门户网站的基本特征信息与服务网站色调搭配
  • 免费炫酷企业网站源码记事本怎么做网站
  • 德阳建设局官方网站天津放心站内优化seo
  • 宁波门户网站建设广州做网站信科建设
  • 怎么制作网站视频播放器外包优化是什么意思
  • 品牌网站建设哪好哈尔滨互联网广告公司
  • 怎样设置网站主域名怎么建立网站的步骤
  • 厂字型布局网站有必要 在线 网页 代理
  • 企业网站建设 详细方案网站建设及空间
  • 网站与网页的区别.网站建设服务方案ppt
  • 东莞倣网站游戏开发软件工具
  • WordPress手机站插件WordPress上图片加载不出来
  • 手机网站优势网站建设法律法规
  • 怎么查找网站的根目录局域网如何做视频网站建设
  • 响应式电商网站制作广告推广平台代理
  • 网站建设技能考试试题三服务器调用wordpress
  • 江苏建筑工程信息网站app 软件开发
  • 网站内容建设出现的问题数据查询插件 wordpress
  • 酷站海洛牡丹江网络推广公司
  • 做盗版电影网站后果泰安招聘网
  • 网站在线推广计算机培训班价格
  • 网站做电商销售需要注册吗wordpress修改头像
  • 网站维护内容及费用毕业设计选择做网站的意义
  • 网站开发的历史创意广告图片及文字解析
  • 自建网站 好处网络营销与直播电商专业学什么就业方向是什么