【程序员日记】---从业务编排到低代码

之前总聊微服务,今天换一个话题---低代码。

低代码这个词也是最近这几年很火的概念,尤其是遇到大环境下行,很多大厂和互联网那个公司也在慢慢在低代码方向发力,当然,对于传统项目交付型的软件公司,低代码也具有相当大的吸引力。

如何理解低代码

用一个通俗易懂的说法,就是少写代码,并且降低开发门槛的方式,可以让平民开发者(可以理解为并不一定具有软件技术素质的人员)也能高效快速的构建应用程序。

如果基于这个思路,是不是大家觉得有一些类比?

当计算机刚起步的时候,大家还用打孔卡片来跑程序的时候,这时候一个牛逼的汇编语言可以说就是那个时代的低代码;再到后来C语言的普及,那对于汇编语言来说,C语言简直就是低代码…..以此类比,在我们这个时代,当面向对象的开发语言成为主流的时候,大家不可避免的在思考,是不是可以通过简单的可视化配置或者逻辑图就能实现编程呢?比如产品经理把产品设计好,时序图画好,自动就可以编程可以跑得程序。

命令式 vs 描述式

对于传统的软件开发,我们需要定义数据结构,定义变量,通过一行行命令式的代码,来精准的控制计算机执行每一步操作。这个过程中,对于开发者要求是比较高的,要有计算机运行的基本知识,要有算法的基本能力,而且时常要从计算机角度触发逻辑思考,包括线程池管理,内存管理等问题。这些,无疑都增加了开发者的门槛,同时也会增加工作量。

那低代码的目标就是减少工作量和对底层逻辑的关系,从此目标出发,我们可以构建一种描述式的编程方式。

所谓描述式的编程,就是把业务需求标准化,配置化,最优方案是可视化的配置的方式实现快速开发,这个过程中,开发人员不用关心计算机底层逻辑,只需要描述好数据模型,业务流程即可。

现在已经有很多成熟的低代码平台,比如Mendix这种,对于业务不复杂的情况,能够实现程序的快速构建。但对于很多程序员来说,还是很不适应这种编码方式。对于大多数程序员来说,一个好的低代码框架,反而是更香的那个面包,对于解决眼前的饥饿能够起到立竿见影的效果。

说一下我们熟悉的一些业务场景,包括 工作流引擎,前端页面装修等,这些业务场景已经有了很成熟的低代码框架帮我们解决。比如工作流引擎,当你处理流程审批的业务场景的时候,如果没有工作流引擎,你可能还需要自己用状态机来硬编码你的程序,有了工作流引擎,我们可以实现业务配置化。

而业务编排思想,其实就是从命令式走向描述式的一次探索,所有低代码框架的核心思想就是业务编排能力,通过打造不同的原子,和原子之间的排列组合,从而实现业务能力。

低代码实现路径---业务编排

业务编排思想核心还是业务单元模块化,这个在某种程度跟微服务思想有点不谋而合。通过模块化去解耦复杂业务系统,化繁为简。下面贴一个简单的业务编排架构图:

1. 核心组件说明

a. 流程引擎,规则引擎和决策表。

这些概念在activiti这种框架中也是耳熟能详的,所以可以看出,业务编排也是依靠流程驱动实现的。只不过activiti关心的是橘色任务流转,比如OA审批流这种,而业务编排关心的事一个复杂业务本身中的业务粒度拆分和装配,例如下单流程,价格规则等等。

b. 上下文管理。

这个也是很重要的,在一个复杂的业务编排过程中,每个独立组件之间不可避免会有数据交互,而这些都交给了上下文处理。对于上下文管理,也有两种方式,一种是流程串联中的上下文传输,类似水流中的小纸船,他会在流程中通过业务控制实现上下文的传递,当然这种在实现和理解上都会更复杂一些。

还有一种方式类似工作台,这里可以做一个类比:n个工人按照一定顺序围绕一张工作台进行零件生产,每个工人都可以从工作台上拿去资源生产自己的零件,而每个工人会将自己生产的零件放在工作台上,同时也可以从工作台上领取别的工人做好的零件。而这个工作台就是上下文, 所有的资源和零件在这个工作台之上是共享的。这种共享上下文的设计思想会让业务实现和理解变得简单,但它的问题在于组件的安全性和约束性,因为资源共享,所以每个组件都可以对资源进行修改,在软件开发中,有时候失去约束性,会在系统迭代的过程中出现变质,这就类似于面向对象编程中的封装性。

2. 案例讲解

这里举个业务编排的例子,我们以商品详情查看为例:

通过上图可以看出,在商品详情查看这个接口中,包含了商品基本信息查询,库存查询,售后查询,可售性查询等流程,然后最终才得到返回值。

你可以将瀑布流式的代码,转变成以组件为核心概念的代码结构,这种结构的好处是可以任意编排,组件与组件之间是解耦的,组件可以用脚本来定义,组件之间的流转全靠规则来驱动。

可能有的同学会说,这个业务用瀑布是写也问题不大嘛。那我再换一个更复杂一些的业务流程,大家是不是就可以看出业务编排的优势,下面给大家一个商城搜索接口的业务逻辑图:

上面的案例是笔者在采灵通系统开发中真实的一个案例,笔者最开始是采用瀑布方式实现的该搜索关键字处理逻辑。但之后进行了重构,通过引入开源框架liteFlow的业务编排框架,极大的简化的业务复杂度。基本可以实现流程图即代码的程度。具体代码就不贴在此处了,如果大家该兴趣,可以去研究一下liteflow这个业务编排开源框架。

从业务编排晋升为低代码框架

从业务编排晋升为低代码框架,需要改进几个地方,第一个就是流程节点的Node, 在业务编排中,Node节点是一个可以自定义的业务模块,可以由程序员自行写业务逻辑。业务编排做到的是把复杂的业务变成简单的业务,但简单的业务也是需要开发的。如果我们把简单的业务也原子化和配置化,那么就可以成为一个入门级的低代码框架了,那么,我们的架构该如何调整呢?

首先我们需要将Node节点晋升为微流程节点,同时需要元数据模型支持。在微流程节点内,我们可以自定义CRUD模块,也可以自定义动作和发布时间,所有的缓存,查询都会定义为一个个的微流程节点,当微流程节点丰富度可以覆盖我们的业务代码需求时,我们就可以是先业务开发的配置化。然后在配合部署管理模块,实现代码的一键发布,这样就实现了一个简单的低代码框架。而这也是所有主流的商用低代码框架的思路。

总结

业务编排是实现低代码的路径之一,但不是唯一路径。尤其是当我看到ChartGPT4.0出来之后,人工智能,可以通过一个网页草图自动生成html代码时,我觉得,这可能才是低代码的最终归宿吧。

作者:京东物流 赵勇萍

内容来源:京东云开发者社区

本文转载于网络 如有侵权请联系删除

相关文章

  • 定制SAX解析器的执行自定义实体解析

    XML文档可能包含对外部DTD或其他实体的引用。默认情况下,InterSystemsIRIS尝试查找这些实体的源文档并解析它们。要控制InterSystemsIRIS解析外部实体的方式,请使用以下步骤:定义实体解析程序类。此类必须在扩展%XML.SAX.EntityResolver,并且必须实现resolveEntity()方法,该方法具有以下签名:methodresolveEntity(publicIDAs%Library.String,systemIDAs%Library.String)as%Library.Integer复制每当XML处理器找到对外部实体(如DTD)的引用时,就会调用该方法;这里的publicID和systemID是该实体的Public和系统标识符字符串。该方法应获取实体或文档,将其作为流返回,然后在将流包装在%XML.SAX.StreamAdapter的实例中。此类提供了用于确定流特征的必要方法。如果无法解析该实体,则该方法应返回$$$NULLOREF,以向SAX解析器指示该实体无法解析)。尽管方法签名指示返回值为%Library.Integer,但该方法应返回

  • 安装部署Kubernetes集群

    其实本节的文章我在很久之前就已经发过了一次,但不够详细,层次不清。我今天部署的时候看的够呛(虽然也是部署成功了),也算是对以前的坑,做个忏悔吧。本文可能会比较boring,但请相信这并不是我的本意。这一定是最精简的笔记之一,相信我这绝对不是混水。本文主要分三大部分,他们分别是系统初始化、安装docker、安装Kubernetes,测试验证与删库跑路系统初始化请注意后面的单词all,代表所有(master、node) Master:仅在master上 node:仅在node上关闭防火墙(`all`)##临时关闭 systemctlstopfirewalld ##永久关闭 systemctldisablefirewalld ##验证防火墙是否关闭 systemctlstatusfirewalld 复制效果如下关闭selinux(`all`)#临时关闭 setenforce0 #永久 sed-i's/enforcing/disabled/'/etc/selinux/config 复制关闭swap(`all`)#临时 swapoff-a #永久 sed-ri's/

  • 【笔记】《Laplacian Surface Editing》的思路

    近来在做三维网格编辑相关的工作,于是看了04年的这篇高引用的经典论文,这篇文章在三维中使用拉普拉斯坐标配合多个限制方法实现了效果不错的网格编辑。因为最近太忙了所以现在才抽空写好总结发出来 这篇文章对于数学的要求可能比较高尤其是构造和求解线性方程组那里,需要好好阅读,里面也许还有很多理解不透彻或理解错误的地方,请谅解这篇文章我发现网络上几乎没有开源的实现,于是我花了一段时间对这篇文章进行实现,目前已经实现了前两个部分,第三个部分可能不会继续实现了,代码等整理好后会开源到Github上到时会通知大家PartA总览 交互式的自由曲面变形在以前是一个难以解决的问题,因为传统的网格自由变形方法会导致表面细节的严重失真.这篇04年的文章使用拉普拉斯坐标来对网格进行编辑(Meshediting),从而能在保留表面细节和结构的情况下对表面进行变形.除此之外还利用拉普拉斯坐标对涂层迁移(Coatingtransfer)和曲面块移植(Transplantingsurfacepatches)问题进行了应用.思路:将网格坐标编码为拉普拉斯坐标在拉普拉斯坐标中对网格进行处理将拉普拉斯坐标解码回网格PartB拉普

  • 以后要是再写for循环,我就捶自己!

    以下文章来源于CodeSheep,作者hansonwong99请听题给定一个字符串元素列表,如下所示:["1","2","bilibili","of","codesheep","5","at","BILIBILI","codesheep","23","CHEERS","6"]复制里面有数字型字符串,有字母型字符串;字符串里有大写,也有小写;字符串长度也有长有短现在要写代码完成一个小功能:我想找出所有长度>=5的字符串,并且忽略大小写、去除重复字符串,然后按字母排序,最后用“爱心❤”连接成一个字符串输出!哟,就这点需求能难倒我?三分钟之类必搞定!首先我写一个函数,判断输入字符串到底是字母还是数字publicstaticBooleanisNum(Stringstr){ for(inti=0;i<str.length();i++){ if(!C

  • 0677-在CDSW1.6中使用你喜爱的编辑器

    自2017年ClouderaDataScienceWorkbench(CDSW)推出以来,我们一直致力于加速企业数据科学从研究到生产。我们正在帮助IQVIA和DeutscheTelekom等数百家客户建立自己的AI工厂,使大型数据科学团队能够安全,自助地访问业务数据,计算资源以及开源工具和库,这样他们能够更快的创新和影响业务。通过不错的用户体验提高数据科学团队的工作效率仍然是我们赋予客户工业化机器学习和AI使命的关键,我们很高兴宣布今天发布的CDSW1.6支持第三方编辑器包括JupyterNotebook,RStudio,PyCharm等。CDSW让团队在端到端数据科学工作流上进行协同合作,从数据探索和数据工程到生产中的模型开发和部署。这可能涉及数据工程师,数据科学家和ML工程师之间的协作,通常这些人对编辑器和IDE的喜好是不一样的。现在不同的团队可以利用CDSW提供的自助服务数据科学的优势,同时在最熟悉或最喜欢的IDE中工作。基于浏览器的IDE在IDE偏好方面,有时每个人都有自己喜爱的工具,而每个人最爱的又不一样,其实每个人都没有错。事实上,Cloudera很多客户都是Jupyter

  • 在.Net Core 2.0中使用MySQL

    在之前,我简单的介绍过在.netcore中使用Mongodb(见文章《.NetCore系列教程(三)——使用Mongodb》),也使用过PostgreSQL(但是没有写文章介绍怎么使用,只是在文章《.NetCore系列教程(一)——环境搭建》中简单介绍过如何安装)。当然,我的文章质量都不高,只是把自己平时遇到的问题记录下来,很多问题是自己经历过之后在网上苦苦的寻找答案但都不适用或者不明了的情况下,自己摸索出来的解决方案,这也算是防止自己再次误入坑,也给遇到同样问题的朋友一点帮助吧。 下面说下怎样在.netcore中使用MySQL,这个问题网上随便一搜有很多,我的当然也是从网上搜索来的,只是用自己的语言再次整理下而已。 在使用MySQL时,需要使用到MySQL的驱动,之前MySQL官方没有出驱动的时候,需要使用第三方的,不过现在有官方的驱动,还是尽量使用官方的吧,我这里也以官方的为准。另外还用到了Dapper这个小型ORM,这两个都可以通过Nuget来安装。需要注意的是,MySQL.Data需要安装最新版的(现在是6.10.3-rc版),旧版本不支持.netcore2.0 先在appse

  • 起底谷歌疯狂黑科技,百度和谷歌不止隔着一个太平洋

    谷歌在创新的路上越走越远,而百度在致富的步子上越走越急。看到下面这些谷歌黑科技,我才明白谷歌和百度不止隔着一个太平洋!智能隐形眼镜据谷歌称,它正在开发一款智能隐形眼镜。该产品旨在通过泪液测量血糖水平,它带有一个微型的无线芯片,两层软性隐形眼镜材料之间则嵌入微型化血糖传感器。除体臭设备今年,谷歌向美国专利局注册了一款可检测及消除体臭的设备。机器人军队谷歌已将致力于“改变你对机器人功能的想法”的公司BostonDynamics。BostonDynamics旗下的机器人产品包括Petman,该款机器人能够像人一样移动,用于测试化学状况。“终结者”机器人谷歌正在研发的另一款机器人名为Atlas,它看起来就像是“终结者”。各种酷似动物的机器人除了上述的两款机器人之外,我们也别忘了谷歌的各款酷似动物的机器人,其中包括:号称全世界跑得最快的机器人的Cheetah,可像小虫一样攀爬建筑物的RiSE,以及可翻山越岭的高级机器人BigDog。长生不老之术?谷歌旗下的CalicoLabs公司在研究些什么呢?他们在研究如何抗衰老。文化艺术谷歌文化学院收集了来自多家博物馆的国际藏品和展品以及来自世界各地的档案(

  • Binary Tree Preorder Traversal

    二叉树的前序遍历 递归实现/** *Definitionforbinarytree *structTreeNode{ *intval; *TreeNode*left; *TreeNode*right; *TreeNode(intx):val(x),left(NULL),right(NULL){} *}; */ classSolution { public: voidPreOrder(TreeNode*root,vector<int>&vec) { if(root!=NULL) { vec.push_back(root->val); PreOrder(root->left,vec); PreOrder(root->right,vec); } } vector<int>preorderTraversal(TreeNode*root) { vector<int>vec; PreOrder(root,vec); returnvec; } };复制

  • lightoj 1179(线段树)

      传送门:JosephusProblem 题意:经典约瑟夫问题,有n个人,每次数到第k个人出列,求剩下的最后一人。 分析:用线段树模拟约瑟夫问题,记录区间的减少情况,然后根据每次数到的人在区间排第几位,线段树log(n)找到并更新,总复杂度为O(nlog(n))。 #include<cstdio> #include<cstring> #include<cmath> #include<algorithm> #defineN100010 #definemod1000000007 #defineLLlonglong #definelsonl,m,rt<<1 #definersonm+1,r,rt<<1|1 usingnamespacestd; intn,k; intsum[N<<2],vis[N]; voidPushup(intrt) { intls=rt<<1,rs=ls|1; sum[rt]=sum[ls]+sum[rs]; } voidbuild(intl,intr,intr

  • tcp的粘包和拆包示例以及使用LengthFieldFrameDecoder来解决的方法

    粘包和拆包是什么? TCP协议是一种字节流协议,没有记录边界,我们在接收消息的时候,不能人为接收到的数据包就是一个整包消息 当客户端向服务器端发送多个消息数据的时候,TCP协议可能将多个消息数据合并成一个数据包进行发送,这就是粘包 当客户端向服务器端发送的消息过大的时候,tcp协议可能将一个数据包拆成多个数据包来进行发送,这就是拆包 以下一netty为例,展示一下tcp粘包和拆包的例子: ServerBusinessHanler: importio.netty.buffer.ByteBuf; importio.netty.buffer.Unpooled; importio.netty.channel.ChannelHandlerContext; importio.netty.channel.SimpleChannelInboundHandler; importjava.nio.charset.Charset; importjava.util.UUID; publicclassServerBusinessHanlerextendsSimpleChannelInboundHandler

  • 工程代码维护的思考:完美的工程代码存在么?

       昨天下班回家坐在车上,突然想到了一个事实——完美的工程代码是不存在。当然我这里单独指工程代码,即正常运行在服务器上,作为生产的一环运行的代码。那些个人或很小团队维护的实验性质,学术性质的代码不在此列。    为什么这么说呢?我觉得主要是工程代码需要团队协作,而只要是人就一定会犯错误。而且经验越少,技术越差,犯错误的概率就越高。如果是一个人,甚至两到三个人,只要定好了代码风格,做好代码复查,基本都能保证代码质量,但是一个团队往往不止2,3个人,而是5,6个,甚至十几个人。这些人中间有的人参加工作十几年了,有的人今年才刚毕业,有人技术好,有人技术差,人员素质怎次不齐。一定会有人源源不断的贡献坏的代码。   有人说:坏代码来了不让他提交不就行了?代码复查这个环节哪里去了?其实代码复查是一个成本很高的工作,我相信很多团队根本没有,就算有,大部分团队也是抽查。因为从需求端过来的任务非常多,不可能每一个任务都安排给有经验的、技术好员工,一定会有任务被安排到新人那边。新人提交的代码也不一定每一段都能被复查到,因为项

  • 《高校学生学科竞赛管理平台的系统设计与实现》文献阅读随笔

    一、基本信息 标题:高校学生学科竞赛管理平台的系统设计与实现 时间:2018年 来源:韶关学院数学与统计学院 关键词:学科竞赛;管理平台;信息化;线上; 二、研究内容 1.研究背景 传统学科竞赛采用纯线下的运作模式,竞赛的宣传、报名和安排等均通过人工完成,竞赛的数据也是人工管理,这种运作模式不仅效率低下,同时繁琐也容易出错.通过需求分析及数据库系统,设计一个线上运行的多学科的学科竞赛管理系统.竞赛报名采用线上方便快捷的一键式报名,管理系统采取信息化设计,开发信息系统平台多种功能,后台处理简单,极大地提高了竞赛组织方的工作效率. 2.需求分析 学科竞赛管理系统设计的目的是服务于广大的高校师生,它能够帮助竞赛组织方高效地完成竞赛组织等相关工作.对学生而言,学科竞赛可以让他们更快地获得本校内或者高校间的学科竞赛信息,同时还可以在系统上进行竞赛的报名和成绩查询.对于竞赛的组织方而言,他们可以方便地申请举办一个新的竞赛,发布竞赛相关信息,在平台上查看竞赛的报名情况以及报名学生的基本信息,同时还可以进行试题的批改和成绩上传. 3.模块设计 1)用户报名模块2)信息发布模块3)成绩查询模块4)资料管

  • Scala学习十六——XML处理

    一.本章要点 XML字面量<like>this</like>的类型为NodeSeq 可以在XML字面量中内嵌Scala代码 Node的child属性产出后代节点 Node的attributes属性产出包含节点属性的MetaData对象 \和\\操作符执行类Xpath匹配 可以在case语句中使用XML字面量匹配节点模式 使用带有RewriteRule示例的RuleTransformer来变换某个节点的后代 XML对象利用Java的XML相关方法实现XML文件的加载和保存 ConstructingParser是另一个可以使用的解析器,它会保留注释和CDATA节 二.XML字面量   Scala对XML有内建支持。例: //类型为scala.xml.Elem valdoc=<html><head><title>Test</title></head></html> //类型为scala.xml.NodeSeq valitem=<li>Test1</li><li&

  • 第十章:RDB持久化

    RDB 保存命令 save命令,阻塞Redis服务器进程,直到保存动作完成; bgsave命令,派生出一个子进程来完成保存动作; 载入命令 Redis没有载入RDB文件的命令,载入动作在Redis启动时自动完成。即若相应文件夹下有RDB文件,则Redis自动载入,且载入期间Redis服务器处于阻塞状态,不会处理客户端请求。 注意:因为AOF文件的更新频率比RDB文件的更新频率高,所以如果Redis服务器开启了AOF持久化功能的话,那么启动时优先载入AOF文件。 相关命令的并发执行 SAVE命令和BGSAVE命令禁止同时执行,防止产生竞态条件; BGSAVE命令和BGSAVE命令禁止同时执行,防止产生竞态条件; BGSAVE命令和BGREWRITEAOF命令可以同时执行,但是两个命令底层也是序列化执行的,防止两个子进程同时进行大量磁盘写入操作。

  • 杂篇

    word2vec工具包:Gensim 链接:https://www.cnblogs.com/pinard/p/7278324.html

  • Matlab图像处理—边界填充,均值滤波,中值滤波,统计排序滤波

    空间滤波的工作原理 滤波器的邻域中心访问输入图像中的每一个像素,并产生一个对应的信像素,新像素的坐标等于当前访问的像素的坐标,新像素的值是预定义操作的运算结果。 以此类推。 一,图像边界处理方法 1忽略边界数据 2.拓展图像(四周补上数据) 使用P值填充(如:P=0) 复制图像边界像素的值 镜像图像边界像素的值 周期扩展 1.忽略边界数据 优点:滤波后的图像中所有像素点都能由整个模版处理 缺点:处理后的图像比原始图像小,输出的图像尺寸=n-w+1 2.拓展图像(四周补上数据) (1)使用P=0来填充 (2)复制图像边界 (3)镜像扩展 (4)周期扩展 优点:与原图的尺寸相等 缺点:若扩展方法不当,补在靠近图像边缘的部分会给处理后的图像带来不良影响,而且会随着滤波器尺寸的增加而增大 matlab代码示例 %%%%%%%%%% %边界填充示例% %%%%%%%%%% %用matlab创建图像 A=ones(512,512)*255; A(1:256,1:256)=0; A(257:512,257:512)=0; figure; imshow(uin

  • 【笔记】「pj复习」深搜——简单剪枝

    深搜——简单剪枝 说在最前面: 因为马上要NOIP2020了,所以菜鸡开始了复习qwq。 pj组T1,T2肯定要拿到满分的,然后T3,T4拿部分分,T3拿部分分最常见的做法就是暴搜,但是暴搜容易T,为了拿到更多的分数,应该合理剪枝。 各种剪枝方法 优化搜索顺序 (随缘)随缘剪枝。 可行性剪枝 对当前状态进行检查,发现分支无法到达递归边界,回溯。 最优化剪枝☆☆☆←最重要的一种剪枝方法 在最优化问题的搜索过程中,若当前花费的代价已超过前面搜到的最优解,回溯。 上下界剪枝 按题意,找子节点的上下界。 例题 例一:洛谷P1135奇怪的电梯 \(\rm\LargeLink\) 这道题当然bfs效率是最快的,但是为了练习剪枝,就可以拿dfs做。 思路很简单,从起点开始,只要没越界就向上下搜,全部搜完得到答案。 很容易就得到了代码: #include<iostream> #include<cstdio> #include<algorithm> #include<cstring> #include<cmath> #inclu

  • A题笔记(14)

    ReverseWordsinaString: http://oj.leetcode.com/problems/reverse-words-in-a-string/ 代码: https://code.csdn.net/snippets/252509 EvaluateReversePolishNotation : http://oj.leetcode.com/problems/evaluate-reverse-polish-notation/ 代码: https://code.csdn.net/snippets/252512   区分:“x”和‘x’    string中find类的函数都有两个版本 string::size_typeiFind,iFind2; iFind=s.find_first_not_of(""); iFind=s.find_first_not_of("",iFindend);复制 一个是从头开始查找,另一个从给定下标出开始查找,而且返回的都是下标而并非迭代器   find和

  • 算法笔记错误-链表篇

    算法笔记错误-链表篇 for(inti=first;i!=-1;i=link[i].next){ link[i].flag=true; } 复制 上述代码中,i只有在for循环内有效,出了for循环,就无效了

  • Typescript使用字符串联合类型代替枚举类型

    TypeScript宗旨 我觉得Typescript的宗旨是任何一个TypeScript程序,在手动删去类型部分,将后缀改成.js后,都应能够正常运行。Typescript是javascript的超集,是编译期行为,不引入额外开销,不改变运行时行为,始终与ESMAScript语言标准一致。 但是enum类型了引入了JavaScript没有的数据结构(编译成一个双向map),入侵了运行时,与TypeScript宗旨不符。用字符串联合类型('enum1'|'enum2'|'enum3')可以做到相同的事,且在调试时可读性更好。 以下代码展示了enum违背了宗旨的证据: Enum实现 //TypeScript enumTest{ enum1=2, enum2, enum3 } consttest:Test=Test.enum2;//3 //编译为javscript varTest; (function(Test){ Test[Test["enum1"]=2]="enum1"; Test[Test["enum2"]=3]="enum2"; Test[Test["enum3"]=4]

  • SSM + SpringBoot 常用注解

    Spring常用注解 @Controller 对应表现层的Bean @Service 对应的是业务层Bean @Repository 对应数据访问层Bean(即DAO组件) @Component 把普通pojo实例化到Spring容器中,相当于配置文件中的<beanid=""class=""/> 当我们的类不属于各种归类的时候(不属于@Controller、@Services等的时候),我们就可以使用@Component来标注这个类。 @Repository(value="userDao") 注解是告诉Spring,让Spring创建一个名字叫“userDao”的UserDaoImpl实例。 @Autowired 自动装配,默认按类型装配 @Resource 作用相当于@Autowired,均可标注在字段或属性的setter方法上。 不同点: @Autowired是Spring的注解,@Resource是javax.annotation注解 @Autowired默认按类型装配,@Resource默认按Name自动注入 @Resource注解的使用性更为灵活,可指定名称,也

相关推荐

推荐阅读