欢迎访问 生活随笔!

ag凯发k8国际

当前位置: ag凯发k8国际 > 前端技术 > javascript >内容正文

javascript

javascript设计模式-ag凯发k8国际

发布时间:2024/10/14 javascript 39 豆豆
ag凯发k8国际 收集整理的这篇文章主要介绍了 javascript设计模式_javascript 前端设计模式 小编觉得挺不错的,现在分享给大家,帮大家做个参考.

工具匆匆过,模式永流传

虽然在我们的项目中使用新的框架/库可能很酷,但我们经常忽略了为什么使用它们,而是“为了使用它而使用它”。

在人们制作桌面/企业应用程序的日子里,出现了许多设计模式/软件架构设计。它们由明智的工程师设计,以解决其应用程序中信息流的复杂性。今天,当我们忙于制作web应用程序时,这种复杂性并不会消失,只有这一次阶段才会从桌面/企业私有服务器变为浏览器。因此,我们应该能够从这些看似不那么性感的架构模式中学习,以管理我们的前端应用程序。

由于有丰富的代码示例和资源来学习前端社区中工具“使用方法”,因此本文不应该是另一个。相反,我们的重点将放在“前端应用程序的体系结构”上,或更明确地说,“在应用程序中管理大量不断变化的部分的方法”,这在当今丰富的ui交互中。如果这篇文章可以促进这一主题的思考和讨论,那么它的目的就大大提高了。

这是作者开始web开发之旅的地方(甚至在学习vanilla javascript之前)。jquery提供了一种选择和操作dom的便捷方法。假设我们正在构建像netflix这样的网络应用。我们将向用户显示电影列表。我们以下列格式保存这些数据:

[{id:123,title:'ironman',savedforlater:true},{id:456,title:'x-men',savedforlater:false},{id:789,title:'aquaman',savedforlater:false} ,... ]

我们可以遍历数组并使用“appendchild”到document 来记录包含的相关信息。然后,对于每部电影,我们提供一个按钮供用户点击,以便切换savedforlater布尔字段。我们可以绑定onclick事件并更新列表。要更新ui,我们可以删除所有子节点并重新渲染它们,或者我们可以通过id选择dom子节点,创建容器div,使用新节点添加appendchild,删除旧节点和容器。

接下来,我们要添加一个显示savedforlater计数的功能,导航栏中出现的书签图标按钮上的数字徽章。(像购物车一样!?)为了使这个计数保持最新,我们可以将它绑定到每个savedforlater按钮的onclick事件 - 更新列表变量,更新卡片ui,更新计数显示。

(可能有另一种不创建数组变量的方法。它是在每个影片dom元素的数据属性中保存每个影片的所有信息。为了得到计数,我们可以遍历元素并总结值像data-savedforlater这样的属性)

但是,我们可以看到,当有越来越多的功能/ ui交互时,我们必须自己处理越来越多的dom操作,如有必要,我们要同时管理任何全局变量(movie array,isloading,isloggedin,themecolor。。。)。

ui状态交互的示意图

这就是angular,react,vue等前端框架的用武之地。一旦我们更新了应用程序的状态(model),所有这些框架/库都将为我们处理dom操作(view)。更新模型,更改视图,听起来很熟悉?是的,让我们说下架构模式。

mvvm模式,双向绑定

在构造应用程序时,我们都听说过mvc(模型视图控制器)模式。在spa的上下文中,我们可以说model = app state,v = html模板。对于angular和vue.js,它们的模式更接近于mvc的变体 - mvvm(模型视图 - 模型)。在这种情况下,每个dom元素(或一组元素)仅对模型的某个部分感兴趣(即仅是app状态的一部分)。通过将每个元素绑定到模型的负责部分(view-model层),它可以直接监听(读取)/更新(写入)模型的一部分。这也称为双向绑定。

具有mvvm模式的angular和vue.js的代码片段

使用这种模式,我们实现了关注点的分离 - 将业务逻辑(模型)与表示层(view)分离。此模式允许快速和直接操作数据模型,这是基于crud(创建 - 读取 - 更新 - 删除)的应用程序的理想选择。

crud应用和基于任务的应用

crud应用程序例如是todo list,employee list等。为您显示数据项的行,对于每个数据项,您可以单击“编辑”以更新该项目的某些属性,然后“保存”它。您还可以使用“添加”按钮插入新行,使用“删除”按钮删除某行。这就像拥有一个用于数据库操作的图形用户界面。

我们也想构建的另一种应用是基于任务的应用。示例应用程序是酒店/航班预订应用程序,电子商务应用程序或macbook上的“系统偏好设置”应用程序。您需要完成一系列步骤才能完成工作。就数据模型/应用程序状态而言,crud应用程序和基于任务的应用程序之间的根本区别在于后面的应用程序的状态将不仅仅具有“书籍列表”的数据,例如“currentstep”,“currentuser”, “isdarkmode”。

如果我们要使用双向绑定模式,我们将为每个ui组件创建与模型相关部分的绑定。在这些绑定中的每一个中,读取和写入操作都是强耦合的。虽然这在crud应用程序案例中可能是一个好主意,其中每个ui组件负责数据模型的某个部分的读取和写入操作,但在基于任务的应用程序中,读取并不常见only /只写ui组件。虽然可以为这些组件中的每一个创建双向绑定,但是用于改变数据模型的相同部分的多余“路径”是状态管理的混乱源自何处。

这里我们将要实现另一种设计模式cqrs(command query responsibility segregation),或者在简单的英文中,查询(read)和命令(write)应该分开完成。

这并不意味着像angular和vue.js这样的框架变得毫无用处。angular服务是应用cqrs模式的一个很好的例子:你有私有变量存储有问题的项目,公共getter(查询)和setter(命令)作为单独的方法.angular的官方文档中的“ 管理数据 ”部分有一个很好的说明。是否有利用cqrs的架构模式?当然有。

当事件发生时,组件可以向事件总线发送消息(例如,用户单击按钮)。组件还可以订阅事件总线以获取他们关注的事件。事件总线会在收到消息时将消息发送给订阅者。这种类似中间人的模式也称为单向绑定,因为该组件不是直接读写绑定到模型的。相反,组件订阅要读取的模型的一部分; 并将事件发送到“状态处理程序”来编写而不是自己编写。react是一个实现单向绑定的库。换句话说,我们需要自己连接读写周期。

实现单向绑定的react组件的示例

在上面的示例中,我们可以说按钮是发送消息到事件总线的发布者,而h1是一个订阅者,用于监听数据模型/应用程序状态的计数部分的更改。

这种分离读写问题的方法在这个简单的基于任务的应用程序的可维护性方面似乎非常令人满意(好吧,所以你的任务是将显示数量抽到100 ......无论如何),仅使用这种方法来处理大规模的e-商务应用可能会成为一场噩梦。你可以想象在着陆页上有许多“状态处理函数”改变了同一个状态(例如,单击按钮a将切换状态值.a,在输入b中键入文本将同时更新状态值.b和state.a,从api获取数据将在完成时更新state.b和state.c的值,依此类推)。我们需要一种方法来管理一个数据模型的变异方式和时间。

flux模式通过提供状态突变的明确性来解决这个问题。我们来看一下通量模式下的典型数据流。

flux模式中的数据流示例

状态改变的明确性通过以下方式实现:

  • state只能通过调度程序进行改变,而不是任意的“状态处理程序”
  • 要使调度程序改变状态,唯一的方法是发出一个动作
  • 如此确切地说,对于一个视图来改变一个状态,唯一的方法是发出一个动作(或者说redux-ly,发出一个动作)

因此,通过监视操作及其包含的信息,整个应用程序的数据变异在我们的控制之下(何时以及如何更改)。

我们经历了从古老的jquery到今天强大的web开发工具之旅,如angular,react,vue。我们将web应用程序剖析为view层和model层,并探索管理它们之间信息流的方法。双向绑定采用mvvm模式,其中view通过viewmodel与模型紧密绑定,从而允许每个view直接读取和更新模型的相应部分。单向绑定借用了cqrs的设计原则,将写操作与读操作分开,我们自己有意识地实现了2个操作。flux模式进一步推动了这一概念,将数据模型的变异限制为仅通过调度操作,从而通过密切监视这些操作来控制整个app状态。

因此,下次我们可以停一下,并在编码之前考虑下构建应用程序的方法。

总结

以上是ag凯发k8国际为你收集整理的javascript设计模式_javascript 前端设计模式的全部内容,希望文章能够帮你解决所遇到的问题。

如果觉得ag凯发k8国际网站内容还不错,欢迎将ag凯发k8国际推荐给好友。

网站地图