从混乱到混乱,业务逻辑搬家记

大数据领域 ETL 数据迁移的注意事项 在大数据时代,企业常常需要将数据从旧系统(如传统数据库、日志文件、Excel 表格)迁移到新系统(如 Hadoop、数据仓库、云平台),这个过程就像“给数据搬家”。而 ETL(Extract-Transform-Load,抽取-转换-加载)正是实现“数据搬家”的专业工具。总结大数据场景下 ETL 数据迁移的核心注意事项,帮助技术人员避开常见“坑点”,确保数据迁移过程“零丢失、零错误、高效率”。 阅读详情

1

 业务逻辑同学

这家伙不仅善变,而且特别喜欢和程序员作对,尤其喜欢制造混乱,让程序员惧怕他。

他最早栖息在像ASP 和 JSP这样的页面当中,整天和那些负责界面展示的HTML,CSS们厮混,在这里除了展示逻辑之外,你还能看访问数据库的代码, 他们坚定不移地以制造混乱为己任,齐心协力把页面搞得一团糟。

0?wx_fmt=png

当程序员想去修改的时候就发现, 这种代码简直就是“意大利面条”, 极难阅读,极难维护。 更不用提什么代码的复用了。

每当程序员抱怨的时候, 业务逻辑说: “怪我咯? 还不是你们自己惹的祸!”

0?wx_fmt=png

2

 第一次搬家

时间久了,大家都受不了, 只好想了新的办法, 分层!   强迫业务逻辑和展示逻辑分家 !

0?wx_fmt=png

业务逻辑被迫搬了家,再也无法和展示层的HTML,CSS一起喝酒吃肉, 每次想聊个天还必须得通过特定接口, 把数据发给展示层才行。 比如业务逻辑层会发个View Object 给展示层,把自己的孤独和思念捎带过去。 再后来展示层完全从服务器端移到了浏览器端,业务逻辑想打个招呼就得跨越网络的千山万水了。

业务逻辑退而求其次, 和Java bean 打得火热,不过很快就发现和Java bean 实在没什么好聊的,太单纯,没有一点深度,除了getter/setter方法之外,啥都没有。

有人把此时的业务逻辑称为Service , 有人称为Manager ,业务逻辑更喜欢这个名字,因为显得更加威严,更像系统的老大。

无论叫什么,其实做的事情都是一样的: 根据隔壁房间或千里之外的展示层传过来的指示, 从数据库读取数据,形成java bean(有时候连java bean 都不需要) , 进行业务逻辑运算,再给展示层发送结果。

0?wx_fmt=png

程序员把这种Java bean 形象地称为贫血模型, 因为它一点业务逻辑都没有, 业务逻辑在Service中放着呢。

这种简单的开发方式受到了广大程序员的欢迎,它概念简单,门槛极低,初学者很快就能掌握。

建个数据库表, 创建一个对应的java 类,使用Hibernate, MyBatis把它映射到数据库表和字段上, 接下来就可以在Service 中随心所欲地操作这些Java bean 实现业务逻辑了,完全不用什么“高深的”面向对象的分析和设计 。

一个项目划分成多个模块, 大家都按照这种模式开发, 再加上一些辅助的开发工具,能够自动化从数据库表生成各种类, 实在是直接而酸爽。

一大批使用贫血模型的应用程序如雨后春笋般地出现,慢慢地变成了趋势,好像用Java做面向对象的Web开发就是这个样子。 尤其是后来维护项目的程序员, 更是觉得天经地义。

(码农翻身老刘注: 按照Martin Flower在《企业应用架构模式》中的定义,这种方式叫做事务脚本,其本质是用面向对象的语言写面向过程的程序)

这种模式对于简单的增删改查一点问题都没有,甚至还有优势 !

业务逻辑这家伙经常在诱惑程序员,来啊来啊,再多给我的Service/Manager加点逻辑。

随着系统越来越复杂, 这家伙得逞了, 大量的业务规则被添加到Service 当中,Service越来越臃肿, 开始变成巨无霸的类, 各种状态、判断、if else 交织在一起, 喜欢混乱的业务逻辑同学又激动起来,  又回到了“面条代码”的“美好”时代。

3

 第二次搬家

程序员们决定再次让业务逻辑搬家, 搬到一个清静的地方去。

有一天,有个叫做Eric Evans的大神提出了一个新方案: 把Service 层和领域层分开。

0?wx_fmt=png

(码农翻身老刘注: 在Eric Evans的领域驱动开发中,最下面是基础设施层,而不仅仅是数据访问, 我这里为了和之前的图保持一致,只把数据访问列了出来)

业务逻辑同学很不爽地发现,自己不但和展示层彻底说byebye ,还被拆分到一个个的领域对象当中去了,这些对象不仅仅是具有getter/setter的java bean , 而且拥有相关的业务逻辑、业务状态、业务规则。  现在各个领域对象要想聊天吹牛,也非得调用相应的业务接口才可以。

原来的Service 层也成功减肥,变得非常轻薄,不再包含业务规则和知识,只是为下层的领域对象协调任务,分配工作,指挥着他们完成业务任务,解决问题。

程序员们被美好的前景激励着, 努力地帮着业务逻辑再次搬家。 喜欢混乱的业务逻辑同学这次要绝望了, 以后的系统都这么搞,自己还有什么活路。

可是没想到这一次搬家难度很高, 尤其是从需求中分析合适的领域对象,实在不是一件轻松的事情,习惯了之前那种用数据库表驱动的开发方式,想转到领域模型驱动的开发方式, 让大家很不适应。

于是业务逻辑同学趁势鼓噪,算了吧,这种方法太难了,你有丰富的开发经验吗?、你有优秀的面向对象设计能力吗?你能把业务领域专家拉进来一起讨论设计吗? 不行吧? 还是退回去吧,贫血模型多好,又简单又熟悉。

这厮还真得逞了,鉴于大部分遗留系统都是贫血模型,大家没有勇气更没有时间去重构,只好将就着继续往混乱的Service舔砖加瓦,希望能熬到系统重写的那一天。

业务逻辑再次搬回到熟悉的地方,再次开始幸福的生活。

你看到的只是冰山一角, 更多精彩文章,请移步《码农翻身2016文章精华》或者《码农翻身2017上半年文章精华》

有心得想和大家分享? 欢迎投稿 ! 我的联系方式:微信:liuxinlehan  QQ: 3340792577


码农翻身

用故事讲述技术

0.jpeg

Java智能合约升级像“换心脏”?三招代理合约+状态分离,版本控制不“翻车”! 《智能合约升级魔法手册:用Java实现可进化合约》 🔥 核心痛点 传统合约升级易导致数据丢失、版本混乱、逻辑僵化 ✨ 三步破解方案 1️⃣ 代理合约——遥控器式版本切换 通过ProxyContract动态路由请求 支持热升级/回滚(含事件日志) 2️⃣ 状态分离——数据与逻辑解耦 StateStorage独立管理状态 StateMigrator实现平滑数据迁移 3️⃣ 版本控制——全生命周期追踪 自增版本号管理 区块链事件记录每次变更 🛠️ 实战验证 完整Java代码示例覆盖代理模式、状态迁移 自动化测 阅读详情

相关推荐

NMOS管和PMOS管做开关控制电路

NMOS管和PMOS管做开关控制电路

while(1) 3万+

应对复杂的业务逻辑

1.确定逻辑单元2.对逻辑单元做单元测试确定逻辑单元的方法有很多,说简单其道理就像我们平时整理自己的屋子,只要将各种东西分门别类的放整齐就可以了;说复杂的,大家可以看看现在市面上的各种设计模式,它们又像一把梳子,帮助我们将杂乱无章的业务逻辑理顺。事实上,不管你怎么写,你的代码是由逻辑单元组成的,因为你的代码的确是在描述业务逻辑,就算是只有一个逻辑单元存在。然而事情并没有那么简单,逻辑单

欢迎来到我的博客!我是一名拥有20年以上经验的系统架构师。作为一名技术爱好者,我相信技术的力量可以改变世界。 2765

tcmalloc(高并发内存池)简化版讲解-项目

高清发不上去,私我发高清,项目完整代码@我。

2201_75352618的博客 910

码农吐槽项目代码:一个函数一眼望不到边,逻辑混乱,不敢直视!

作为一名程序员,相信好多人都见过形形色色的项目代码,说实话,很少能见到一些特别完美,特别规范的代码,特别是在一些小公司,我想有好多程序员朋友有这种感觉,对吧,其实,最初的设计都是好的,只不过最后由于业务的扩展,需求的变更等复杂的因素造成目前看到的局面,虽然不想看到这样的结果,但是也不得不硬着头皮去继续维护现在这团代码,近期,一名程序员网友就吐糟了他们的项目代码。 据这名程序员朋友说,他不确定大公...

sssdhua的博客 1286

手把手调试Altera FPGA远程升级:从ASMI扇区擦除到Remote Update IP配置的避坑实录

本文详细解析了Altera FPGA远程升级的全流程,重点介绍了Cyclone IV系列FPGA的ASMI扇区擦除和Remote Update IP配置的实战技巧。通过双镜像架构设计、ASMI IP核优化配置及Remote Update IP的隐藏参数设置,帮助开发者避免常见陷阱,提升远程升级的可靠性和效率。

weixin_30872499的博客 447

手把手教你用U盘给海信IP501H刷机:GK6323V100C芯片的4.4.2和9.0固件实战

本文详细介绍了海信IP501H电视盒子基于GK6323V100C芯片的刷机实战指南,涵盖Android 4.4.2强刷和Android 9.0免拆刷机两种方案。从工具准备、短接操作到ADB调试,提供全流程解析和常见问题解决方案,帮助用户安全高效地完成刷机操作。

lemon的博客 1458

javaweb 各层理解

许多设计良好的web应用,可以被按职责分为四层。这些层次是表现层、持久层、业务层、和域模型层。每一个层次都有其独特的职责,不能把各自的功能与其它层次相混合。每一个应用层都应该和其它层隔离开来,但允许使用接口在层间进行通信。我们开始来看看每个层,并讨论一下它们各自都应该提供什么和不应该提供什么: 1. 持久层(Persistence layer–DAO–hibernate) 所谓持久,就是把数据...

aoocean的博客 7002

GD32单片机引脚复用指南:如何让JTAG接口的PA15/PB3发挥第二功能?

本文详细介绍了GD32F103Cx系列单片机如何通过AFIO模块进行引脚复用,特别是将默认用于JTAG调试接口的PA15、PB3等引脚释放为普通IO或复用功能引脚。文章从原理出发,结合代码实践,讲解了如何配置调试端口重映射,将JTAG引脚安全地转换为GPIO或定时器通道,并提供了常见问题排查与最佳实践,帮助开发者高效利用有限的引脚资源。

nept的博客 810

模块化开发入门指南:前端新人如何告别代码混乱(附主流规范详解)

AMD 是前端模块化的“诺基亚”,质量过硬,但时代眼泪。

一个做过前端开发的产品经理,经历过睿智产品的折磨导致脱发之后,励志要翻身"农奴"把歌唱,一边打入敌人内部一边持续提升自己,为我们广大开发同胞谋福祉,坚决抵制睿智产品折磨我们码农兄弟! 799

利用gprMax与Matlab实现SFCW雷达信号的高效仿真与优化

本文详细介绍了如何结合gprMax与Matlab实现SFCW雷达信号的高效仿真与优化。通过利用gprMax获取地下场景的冲激响应,并在Matlab中运用卷积与信号处理技术,可大幅提升SFCW雷达系统仿真的效率与灵活性,为探地雷达研究与设计提供强大工具。

book8的博客 706

STM32CubeMX平台F4系列固件下载核心要点

详解STM32CubeMX平台下F4系列单片机的固件包下载方法与常见问题,重点讲解stm32cubemx固件包下载流程及配置技巧,帮助开发者快速完成开发环境搭建。

weixin_42575505的博客 896

Debian 8下Apache DocumentRoot迁移实战:rsync安全搬家指南

DocumentRoot 是 Apache Web 服务器的核心配置项,定义了网站文件的根目录位置;其修改涉及配置解析、文件系统权限与安全模块(如 AppArmor)协同。在 Debian 8 等老旧但仍在服役的生产环境中,因磁盘空间、性能优化或项目隔离需求而迁移 DocumentRoot 属于高频运维操作。技术关键在于避免 403/500 错误——这往往源于权限继承失效、AppArmor 白名单缺失或 rsync 元数据丢失。推荐采用 rsync -av --delete-after 方案,兼顾原子性、可

weixin_34099526的博客 427

[游戏排查] Baldur‘s Gate 3 加载完成即崩溃?五步排查帮你快速定位问题

《博德之门3》加载崩溃问题解决方案:针对游戏进度条走完后闪退的情况,提供五步排查法。首先清除LevelCache缓存(成功率最高),其次检查Mod兼容性,然后切换Vulkan/DX11渲染API,再排查存档损坏问题,最后可删除配置目录(需备份存档)。重点提示Steam验证无法解决此类问题,建议按步骤顺序排查,多数情况下前两步即可解决问题。

技术小甜甜:传播可落地技术,帮助个人和企业降低解决真实场景问题的成本 3264

别再写Service一把梭了!用COLA 4.0给你的SpringBoot项目做个‘收纳整理’

本文介绍了如何使用COLA 4.0架构重构SpringBoot项目,解决Service层代码混乱的问题。通过分层设计和领域驱动开发(DDD)原则,提升代码的可维护性和可测试性,实现高效的应用架构。文章详细展示了从传统Service到COLA架构的迁移步骤,并提供了最佳实践和避坑指南。

weixin_33714884的博客 275

IMSL CNL 7.0.0 (x86-64)Crack

IMSL CNL 7.0.0 (x86-64)Crack intel的算法库破解文件,这是C++版本的破解文件

Outlook Express 6 (OE6) for Win7/Win8/Win10

英文版 Outlook Express6.0, 兼容Win7/Win10/WinXP,解压就可用。

阿明出海记——从阿明的“东京分店“,看国际化与多区域部署的工程实践

摘要: 阿明餐厅在东京开设首家海外分店,遭遇国际化挑战:登录方式不适配日本用户习惯(LINE vs 微信)、货币单位未本地化(人民币未换算为日元)、网络延迟导致加载缓慢(请求需跨海传输),以及数据合规问题(日本APPI法规要求数据本地存储)。 国际化(i18n)与本地化(l10n)需区分:前者是架构支持多语言(如字符串外置至语言包),后者是内容适配地区文化(如日语菜单用"名物 牛肉ラーメン"而非直译)。时区问题导致东京夜宵订单被误算至次日,解决方案包括存储统一用UTC、前端展示本地时间、业务逻辑按门店时区处

wb04307201的博客 238

LinePhone3.2.7(android端最新版本) sip客户端

SIP客户端For android:LinePhone3.2.7(最新版本),官网地址:http://www.linphone.org/

用飞算JavaAI,让SpringBoot重构轻松“一键开挂”

智能识别技术栈差异,自动生成适配层代码,支持旧数据库、旧接口、旧数据格式的平滑过渡,调试阶段的问题修复效率提升。通过智能扫描与上下文推理,自动补全缺失需求,生成包含功能点、接口定义、数据流向的完整设计文档,准确率超。最佳实践,自动生成分层架构代码,包含依赖管理、异常处理、日志记录等标准化模块,代码规范度直接达到阿里。翻开尘封十年的代码库,模块耦合如乱麻,注释形同虚设,架构混乱堪比迷宫。它不仅懂技术,更懂业务,连我们都没注意到的隐藏需求都被挖掘出来了。分钟即可完成,且生成的代码自带标准化注释,彻底告别。

CalEx_Tech的博客 378

大中型超市收银系统(可直接运行)

光步前台收银系统系统功能:商品销售、商品退货、挂单、收银员权限、会员销售、单品取消、整单取消、商品查询、脱机销售、脱机数据上传,基本资料下载,开钱箱、小票打印、收款结算,支持多币种付款方式(现金、储值卡、礼券、微信等),支持多种促销。运行环境:.net 4.0登陆信息用户名:1001 密码:123456内置商品信息,商品编码可输入00001000 - 00010000,测试效果相关功能键F5 结算 F9挂单 F11商品查询 F8退货 Insert单品取消 Del整单取消 F12开钱箱F2 会员 Ctrl+Z退出系统 Home 锁屏 相关源码待公开

【AI】别忙着招 Agent 了,你的企业还没还清“语义债”

大模型降低了通用智能的门槛,却把“理解业务”的昂贵成本甩给了企业。本文结合《本体驱动的 AI 数据管理》核心洞见指出:多数 AI 项目翻车,根因不在模型不行,而是企业背着几十年的“语义债”和“规则债”——概念口径不一、业务规则散落于老员工脑中与祖传代码里,就被包装成 Prompt 塞给了 Agent。结果,缺乏边界的 Agent 成了错误规则的“双向放大器”,轻则算错报表,重则造成实质性业务损失。当基座模型日益平权,企业竞争的焦点正从算法转向“事理”:谁能把隐性经验显性化、把业务语义与规则编码为可计算的模型

求-是 230

FastAPI 请求体:Web 表单背后的“数据包裹”

场景:电商下单时,订单包含 { "user": { "id": 1, "address": {...} }, "items": [{ "sku": "A1", "qty": 2 }] }。最关键的区别:路径参数和查询参数都在 URL 里(有长度限制,通常 2048 字符,且会留在浏览器历史中),而请求体在 HTTP 请求的“肚子”里(无大小硬上限,且 HTTPS 下是加密的)。你在任何 App 点“注册”,填写的用户名、密码、手机号通过 POST 请求的 Body 发送给后端,绝不暴露在 URL 里。

2301_76841966的博客 190

ERP定制开发为什么历史数据迁移经常被低估

真实情况要复杂得多:旧数据的字段可能不完整,格式可能不统一,部门口径可能不一致,重复数据、脏数据、无效数据和历史状态都需要处理。客户、供应商、商品、库存、订单、合同、财务往来、员工组织、审批记录和历史单据,都是ERP迁移里的高风险数据。库存批次不清,会影响发货和盘点。比较稳妥的做法是,在需求阶段就列出数据清单:哪些系统有数据,数据量大概多少,字段是否完整,是否有附件,是否有历史审批记录,是否需要保留操作日志。开发团队导入一次,业务部门发现问题,再修改,再导入,再核对,循环多次后,项目周期自然被拉长。

qq_30888909的博客 139

SQL Server 迁移注意事项:一次的真实复盘与经验沉淀

很多人把数据库迁移类比成搬家——把东西打包、运过去、再 unpack。但真正做过生产环境 SQL Server 迁移的人都知道,这个比喻害死人。搬家可以接受短暂的秩序混乱,可以忍受几天找不到东西。数据库迁移不一样,生产库一旦出问题,业务就是停摆,损失按分钟计。我参与过大大小小十几次 SQL Server 迁移,从 2008 升级到 2016、跨版本的数据迁移、主从架构调整、甚至是实例层面的 OS 级别迁移。每一次都踩过不同的坑,也因此对「迁移到底要注意什么」有了比文档更实在的理解。

libaike111的博客 415

构建跨平台嵌入式框架:从分层设计到高效移植

本文详细介绍了构建跨平台嵌入式框架的关键技术,重点解析了分层设计(如硬件抽象层HAL)在实现高效移植中的核心作用。通过实战案例展示了如何通过软件分层设计解耦硬件依赖,提升开发效率,并分享了从STM32到GD32的移植技巧与自动化工具链开发经验。

weixin_29166013的博客 369

IDEA多模块项目拆解实战:用Gradle管理依赖的5个关键设置

本文分享了在IDEA中将单体应用重构为多模块Gradle项目的实战经验,重点解析了五个关键依赖管理设置,以构建清晰、稳定的项目架构。针对多模块环境下常见的“No cached version available for offline mode”等构建错误,提供了从根项目配置、模块间API暴露到构建缓存与离线模式根治策略的完整解决方案,帮助开发者提升构建效率与项目可维护性。

julia4scientist的博客 760

基于Springboot+Vue的小型家政服务管理系统毕设源码+文档+讲解视频

本课题针对小型家政服务公司管理中服务流程不规范、订单管理混乱、人员调度低效、客户信息分散等问题,设计并实现基于 SpringBoot+Vue 的小型家政服务管理系统,构建 “订单管理 - 人员调度 - 服务跟踪 - 客户管理” 一体化的家政服务管理体系。系统以 “规范流程、高效调度、优质服务” 为核心,功能涵盖客户在线预约与订单管理、家政服务项目展示(保洁、保姆、维修、搬家等)、服务人员信息与技能管理、智能派单与人员调度、服务过程跟踪与质量监督、客户评价与反馈管理、收费标准设置与财务管理、数据统计分析及管理

全网粉丝10W+、全栈领域优质创作者、掘金、阿里云等社区博客专家、专注于全栈领域和毕业项目实战 788

【新手python程序员必须明白的真相】66.新手python程序员必须明白的函数写太长?拆分函数提高可读性的4个原则

编程就像搭乐高,好的函数就是那些棱角分明、接口清晰的积木块。记住:读你代码最多的不是编译器,而是未来的自己和其他开发者。保持函数的简洁纯粹,就是在为整个团队节省生命。当你下次写出超过30行的函数时,不妨停下来问问自己:“这个函数是否在试图拯救世界?编程之路没有捷径,但正确的拆解方法能让你少走十年弯路。

942
上一篇: CSS的诞生
下一篇: 写给初学者:编程的本质
码农翻身
码农翻身 《码农翻身》作者 《码农翻身》作者
博客等级 码龄8年 3万+粉丝 1084原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值