在很多优秀的低代码平台中都支持了本地代码导出的设计,方便开发者二次集成,但能够导出的前提是已经通过低代码平台进行了初步的数据建模,界面绘制等基础性的操作。这些导出的代码虽然很大程度上减轻了开发者的代码量,但在项目的迭代过程中,遇到数据或需求变更。这些代码就又会成为开发者巨大的负担,重新由低代码平台建模会产生代码上的冲突无法解决,而重新用code编写这一步代码则又面临手工代码与“机器代码”的整合问题。而更为致命的问题是项目上线后,当直接用户希望通过低代码工具进行维护系统时更是“闪崩”。这也是低代码平台在直接用户叫好不叫座的根本原因。
本文将结合OneCode的底层编译原理来讲解 OneCode基于真实代码的建模解决方案。
一,OneCode编译设计原理
(1)OneCode宿主语言(JAVA)一体化设计
OneCode 本身基于JAVA语言体系,是在Java Spring 注解基础上的一套扩展子集,混合编译引擎器通过扩展注解构建完整的Domain模型,通过读取标准Spring 注解完成普通Web数据交付及调度过程,通过Domin域模型动态渲染JS文件输出为JSON交付给前端引擎构建页面。
(2)设计优势:
这种设计将数据结构和业务应用进行了合理的捆绑,但又通过语言体系的不同进行了有机的解耦,使得OneCode可以将设计“元数据文件”和到导出给开发者的“源代码”合二为一。开发者可以通过本地代码的方式进行二次开发,而OneCode 却仍然可以在开发者修改过的代码上读取最原始的建模信息。而二者在代码上的冲突则可以通过,合理的分层架构,通过IOC反转控制,将手工代码与元数据代码有机的分离。同时再利用不同的AOP切面达到各自的目的。
(3)OneCode代码示例:
在OneCode提供的开发示例中提供了一种简单的分层方式:
onecode/onecode-plugins
@FormAnnotation(customService = IPersonAPI.class, col = 2) public interface IPersonForm { @Uid public String getPersonId(); @Pid public String getRoleId(); @Pid public String getOrgId(); @CustomAnnotation(caption = "邮箱") public String getEmail(); @Required @CustomAnnotation(caption = "账户信息") public String getAccount(); @Required @InputAnnotation(inputType = InputType.password) @CustomAnnotation(caption = "密码") public String getPassword(); @Required @CustomAnnotation(caption = "用户名") public String getName(); @ComboNumberAnnotation @CustomAnnotation(caption = "手机") public String getMobile(); }
手工:
@EsbBeanAnnotation public class PersonForm implements IPersonForm { String personId; String orgId; String roleId; String name; String account; String email; String password; String mobile; String orgName; public PersonForm() { } public PersonForm(Person person) { this.personId = person.getID(); this.orgId = person.getOrgId(); this.name = person.getName(); this.account = person.getAccount(); this.password = person.getPassword(); this.mobile = person.getMobile(); this.email = person.getEmail(); } public String getPersonId() { return personId; } public void setPersonId(String personId) { this.personId = personId; } public String getOrgName() { return orgName; } public void setOrgName(String orgName) { this.orgName = orgName; } public String getRoleId() { return roleId; } public void setRoleId(String roleId) { this.roleId = roleId; } public String getEmail() { return email; } public void setEmail(String email) { this.email = email; } public String getAccount() { return account; } public void setAccount(String account) { this.account = account; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getMobile() { return mobile; } public void setMobile(String mobile) { this.mobile = mobile; } public String getOrgId() { return orgId; } public void setOrgId(String orgId) { this.orgId = orgId; } }
(3)运行结果三端读取展示
OneCode建模工具读取配置:
可视化编辑器读取结果:
开发者也可以同步使用idea等专业的开发工具编辑
二,手工代码 DDD建模 拖拽 三种模式的相互转换
(1),手工代码变化向设计层通知转换:
在实际开发的过程中,最常见的一种操作就是增加一些表单字段或者列表展现列,这些行为多数发生在导出代码后。程序员在传统的操作中通常修改bean实体代码和增加页面的代码输入域即可。但在低代码应用中则需要重新返回视图设计界面以及数据模型设计进行多出修改,然后重新生成代码才能完成。这些操作不但费时费力而且极易产生代码冲突。在OneCode的方案中允许用户直接在OneCode上添加一个接口描述,并声明基本的注解类型。然后在OneCode 领域工具中找到对应的代码地址点击重置应用。
然后再表单子域中就会发现新增加的字段属性
在领域工具中初步进行元数据配置后重新编译视图便可同步更新页面。
同理除了我们增加字段这样的需求外我们还可以通过OneCode代码直接声明一个,树形视图、列表视图、表单视图等等。声明完成后再利用OneCode建模工具进行相应的展示和交互设计即可。
(2),模型设计器向OneCode源代码的转换
对于程序员而言代码是最友好的,他们希望通过代码来打通应用创建简单易用的程序。但在整个项目实施过程中,必不可少的会有一些更关注产品以及应用需求本身的角色参与,如:产品经理、项目经理、以及项目实施人员。
(3),可视化设计器向OneCode源代码的转换
用户通过,拖拽完成页面建模序列化为按标准协议序列化JSON文件,后端OneCode服务支撑系统解析JSON文件并混合DSM建模信息以及后端服务逻辑后,通过混合编译,通过代码工厂指定出码模板,完成前后端一体的编译文件。
原型原理
三,混合编译与动态切面支持
三种编程方式混搭使用在设计器为团队提供了很好的协作支持,但一旦项目上线任然会面临一定的风险。特别是低代码编译部分重新上线修改会带来的风险更大。OneCode针对这以问题,在架构上提供了一层虚拟的运行支持层。在Studio中找到运行期配置
进入到运行期配置,我们可以看到所有可配置的OneCode属性,这些属性与代码中注解一一对应的可视化配置
四,可视化设计器页面调整维护
在项目上线后,大幅修改往往会集中在一些样式以及用户交互的细节上。OneCode 在设计之初,变将页面文件作为独立的后缀为.cls文件进行管理,在运行期动态转换为js 供前端按需加载。同时利用Stuido开发工具也可以方方便的直接连接到当前服务容器,进行在线修改调整,并利用版本工具控制测试数据。
OneCode 设计器提供了强大的编辑修改功能:
(1)OneCode样式
DOM树透视样式盒
动态样式盒
(2)OneCode动作事件
动作(逻辑)概览则是针对逻辑片段可视化的入口工具。打开任意页面便可以直观的将该页面的代码片段以直观的方式展现出来。并且可以直接插入,编辑事件,修改动作。同时也可以在调试期动态的中断、跳出终止等功能。