国产玉足榨精视频在线_亚洲日韩国产第一区_男人都懂的网站在线观看免费_久久91亞洲精品中文字幕奶水_按摩房技师激情国产精品_无人在线观看视频在线观看_年轻女教师2免费播放_欧洲熟妇色xxⅩx欧美老妇多毛_91爱视频成人在线第一页_欧美日韩中文字幕成人网

日志樣式

雙鴨山網(wǎng)站建設(shè)500元(十年上線檢測(cè))十年免上線從什么時(shí)候開(kāi)始,

本文借著版權(quán)管理系統(tǒng)-付款的改造,總結(jié)和抽象了一些老系統(tǒng)改造的方法希望能對(duì)遇到類似問(wèn)題的同學(xué)有所幫助作者 | 肖迪(墨詡)來(lái)源 | 阿里開(kāi)發(fā)者公眾號(hào)前言優(yōu)酷CRP系統(tǒng)-內(nèi)容采購(gòu)版權(quán)管理系統(tǒng),是個(gè)存在10年的老系統(tǒng),技術(shù)框架上比較老舊;再加上”人來(lái)人往“,必然存在很多”不合理但是能跑“和”不敢改,所以ifelse“等等經(jīng)典代碼,一共81w行java代碼,17w的jsp代碼。

我在今年全面接手CRP-財(cái)務(wù)部分,整體目標(biāo)就是全面推進(jìn)CRP財(cái)務(wù)的業(yè)財(cái)一體進(jìn)程而這些遺留的技術(shù)問(wèn)題都是推進(jìn)進(jìn)程的挑戰(zhàn),所以CRP財(cái)務(wù)本財(cái)年的技術(shù)主題就是“老系統(tǒng)重構(gòu)”根據(jù)以往的工作經(jīng)驗(yàn),面對(duì)這樣的系統(tǒng),大開(kāi)大合的重構(gòu)改版,帶來(lái)的往往是更加災(zāi)難性的”業(yè)務(wù)不可用“;所以我們的策略,還是要秉著業(yè)務(wù)優(yōu)先的原則,跟隨業(yè)務(wù)新需求來(lái)逐步重構(gòu)。

但無(wú)論產(chǎn)品還是研發(fā)心中都要有同一張大圖,我們最終要做成什么樣子然后根據(jù)大圖劃清各個(gè)業(yè)務(wù)模塊的邊界,在保證不會(huì)影響其他模塊的運(yùn)行的前提下,進(jìn)行重構(gòu)

81w行java代碼中,其實(shí)大部分都是廢代碼,比如:功能和服務(wù)還在但是沒(méi)有人使用;數(shù)據(jù)都已經(jīng)遷移到其他系統(tǒng),下游也不在實(shí)際使用,但依賴還在;有很多job還在運(yùn)行,但并沒(méi)有實(shí)際的數(shù)據(jù)產(chǎn)出使用方之前重構(gòu)的時(shí)候跟組里同學(xué)開(kāi)玩笑說(shuō)“如果隨機(jī)注釋掉一個(gè)service中是所有方法實(shí)現(xiàn),系統(tǒng)大概率還是work的”,雖然我們不會(huì)這樣做,但可能是真的。

對(duì)于這樣的系統(tǒng),重構(gòu)的策略如果是重新梳理所有服務(wù)的使用情況,無(wú)疑是成本特別高的,roi很低所以應(yīng)該按需重構(gòu)和遷移,并保證下游依賴方的不需要做任何改動(dòng)本篇文章會(huì)以其中一個(gè)模塊“付款”來(lái)作為示例,原因有二:

一、本財(cái)年付款的改版業(yè)務(wù)述求比較高,這個(gè)S的重構(gòu)進(jìn)程較其他模塊更快一些;二、想表達(dá)的主題更專注在代碼重構(gòu)方向付款作為整個(gè)優(yōu)酷運(yùn)營(yíng)中比較末端的商業(yè)行為,在系統(tǒng)上對(duì)于付款依賴的下游系統(tǒng)和模塊較少如果是寫(xiě)“合同遷移和改造”,會(huì)更偏架構(gòu)重構(gòu)和老系統(tǒng)、數(shù)據(jù)的遷移方案。

付款模塊一共涉及大概3w行左右的代碼,首先保證下游依賴的接口都不變,還在原有工程服務(wù),并且將老代碼遷移到新的工程下是否遷移工程取決于與遷移的ROI,我們的老工程的前端是用jsp實(shí)現(xiàn)的,現(xiàn)在要做前后端分離,所以老代碼遷移到新的工程下。

付款重構(gòu)的第一原則是以業(yè)務(wù)為中心,不要為了重構(gòu)而重構(gòu)。先來(lái)了解一下付款的業(yè)務(wù)和業(yè)務(wù)的痛點(diǎn)。

付款要解決的業(yè)務(wù)問(wèn)題付款主要解決倆個(gè)問(wèn)題:1、0資損;2、流程效率我通過(guò)MECE的從下而上的歸納整理后,審慎判斷想法建議的“最小公倍數(shù)”的方法,對(duì)付款進(jìn)行梳理,先了解一下付款在做一件什么事,以及如何完成目標(biāo)?

給誰(shuí)付:收款人是誰(shuí)?是否有財(cái)務(wù)或者法務(wù)上的風(fēng)險(xiǎn)?以及需要驗(yàn)證對(duì)方提供的發(fā)票為誰(shuí)付:決定了付款的成本歸屬,歸屬到節(jié)目、部門或者財(cái)務(wù)口徑的入賬科目上付多少錢:是否存在應(yīng)收款和應(yīng)付款可以互抵的情況?付款依據(jù)是什么?稅費(fèi)如何計(jì)算?

怎么付:通過(guò)什么方式支付,先票后款還是先款后票,是否支持預(yù)約付款?能不能付:根據(jù)不同業(yè)務(wù)場(chǎng)景以及金額,流轉(zhuǎn)到不同的審批人進(jìn)行審批將這些要解決的業(yè)務(wù)問(wèn)題向上抽象總結(jié),付款要想做到0資損:信息校驗(yàn):很多基礎(chǔ)信息的校驗(yàn),最基本的不能付錯(cuò)人。

風(fēng)險(xiǎn)攔截:包括風(fēng)險(xiǎn)供應(yīng)商攔截和風(fēng)險(xiǎn)金額的攔截金額精準(zhǔn):依據(jù)合同、賬單、項(xiàng)目等計(jì)算出應(yīng)付金額,然后進(jìn)行對(duì)抵和稅費(fèi)計(jì)算(如有)金額依據(jù)狀態(tài)一致:既然金額的精準(zhǔn)決定了最多付多少錢,就要保證金額依據(jù)與付款單的狀態(tài)一致性

提高流程效率:自動(dòng)憑證入賬多種付款方式的支持快捷的流程審批到這里應(yīng)該可以看出來(lái),付款不是一個(gè)復(fù)雜業(yè)務(wù)流程的模塊,它的核心述求是“穩(wěn)定”與“可擴(kuò)展”從這個(gè)季度的需求也可以驗(yàn)證這點(diǎn)付款的技術(shù)痛點(diǎn)代碼臃腫,擴(kuò)展性低。

付款有個(gè)特點(diǎn),沒(méi)有很復(fù)雜的業(yè)務(wù)流程,但是涉及到資金,在付款之前需要做很多的金額計(jì)算和風(fēng)險(xiǎn)校驗(yàn)而且另外一個(gè)特點(diǎn),付款作為一個(gè)工具性質(zhì)的模塊,會(huì)接入很多業(yè)務(wù)方不同的業(yè)務(wù),在金額計(jì)算、風(fēng)險(xiǎn)校驗(yàn)等流程上基本一致,但實(shí)際接入實(shí)現(xiàn)的時(shí)候,會(huì)有或多或少的差別(比如,付款金額的依據(jù)上,主客和OTT會(huì)有不同類型的賬單)。

可以看出付款這部分對(duì)于復(fù)用性、擴(kuò)展性要求是比較高的現(xiàn)在要接入OTT的付款,我們先來(lái)看一下如果繼續(xù)在老代碼上升級(jí),會(huì)有哪些問(wèn)題@Override @Transactional(rollbackFor = Exception.class,transactionManager = "transactionManager2") public Payment submitPayment(PaymentDto paymentDto, User user) { **只保留能說(shuō)明問(wèn)題的關(guān)鍵代碼或者注釋,省去前整個(gè)方法600行左右** ***payment對(duì)象初始化代碼*** ...省去60行代碼... Integer r = paymentDao.insertPayment(paymentDto); ***payment付款依賴對(duì)象初始化代碼*** //保存關(guān)聯(lián)節(jié)目 playComponent.dealPaymentPlay(paymentDto.getId(), ListUtils.emptyIfNull(paymentDto.getPaymentPlayDtoList()), user); //保存文件 appendixComponent.dealFile(paymentDto.getId(), ListUtils.emptyifNull(paymentDto.getFileDtoList()), user); //保存賬單 paymentAssociatedBillComponent.dealBill(paymentDto.getId(), ListUtils.emptyIfNull(paymentDto.getBillDtoList()).stream().map(AssociatedBillDto::getBillId).collect(Collectors.toList())); //保存責(zé)任人和其他操作人 comPermissionComponent.saveComPermission(paymentDto, "ALL"); **第一步做金額和風(fēng)險(xiǎn)校驗(yàn),為簡(jiǎn)單只保留注釋,省去實(shí)現(xiàn)代碼** //1.校驗(yàn)重復(fù)提交 ...省去5行代碼... //2.提交前校驗(yàn) ...省去20行代碼... //3.校驗(yàn)賬單金額&&所屬公司 ...省去5行代碼... //4.校驗(yàn)娛樂(lè)寶賬號(hào) ...省去1行代碼... //5.校驗(yàn)付款條件 checkPayCondition(payment); //6.校驗(yàn)節(jié)目金額 if (paymentComponent.needPaymentToPlay(payment.getType())) { checkPaymentSubject(payment); } **校驗(yàn)過(guò)程中混入payment對(duì)象初始化代碼** CrpContract contract = crpContractDao.getContractById(payment.getContractId()); Integer operationFlow = contract.getOperationFlow(); payment.setContractOperationFlow(operationFlow); //7.校驗(yàn)本次申請(qǐng)金額是否超過(guò)預(yù)期 ....省去40行代碼... //8.僅版權(quán)采購(gòu)合同支持預(yù)約付款 if (){ throw new RuntimeException("僅版權(quán)采購(gòu)合同支持預(yù)約付款!"); } //8.校驗(yàn)預(yù)約付款不能選擇先款后票 if (){ throw new RuntimeException("預(yù)約付款僅支持先收票后付款!"); } //9.版權(quán)采購(gòu)&&收款賬戶國(guó)家為CN&&簽約幣種為RMB 才可以使用預(yù)約付款 ...省去10行代碼... **payment對(duì)象初始化代碼** payment.setApplyDate(new Date()); ...省去40行代碼... **多了一次沒(méi)有必要的數(shù)據(jù)庫(kù)update** paymentDao.updatePayment(payment); **payment對(duì)象初始化代碼** String actualApplyWorkNo = payment.getActualApplyWorkNo(); ...省去10行代碼... paymentDao.updatePayment(payment); //異步提交審批流 BpmsDto bpmsDto = new BpmsDto(); ...省去10行代碼... return payment; } private xxx(){}

比較典型的“流水賬”代碼,最直觀會(huì)導(dǎo)致的問(wèn)題就是維護(hù)困難,比如想查一個(gè)字段不正確的bug,最差情況要通讀600+代碼(還有部分private方法)在升級(jí)的時(shí)候,最容易想到的辦法就是繼續(xù)蓋樓(比如代碼中調(diào)用了倆次 paymentDao.updatePayment(payment),應(yīng)該就是蓋樓的時(shí)候,代碼復(fù)制多了),從而使“泥丸”越滾越大。

剩余60%,完整內(nèi)容請(qǐng)點(diǎn)擊下方鏈接查看:上線十年,81萬(wàn)行Java代碼的老系統(tǒng)如何重構(gòu)版權(quán)聲明:本文內(nèi)容由阿里云實(shí)名注冊(cè)用戶自發(fā)貢獻(xiàn),版權(quán)歸原作者所有,阿里云開(kāi)發(fā)者社區(qū)不擁有其著作權(quán),亦不承擔(dān)相應(yīng)法律責(zé)任。

具體規(guī)則請(qǐng)查看《阿里云開(kāi)發(fā)者社區(qū)用戶服務(wù)協(xié)議》和《阿里云開(kāi)發(fā)者社區(qū)知識(shí)產(chǎn)權(quán)保護(hù)指引》如果您發(fā)現(xiàn)本社區(qū)中有涉嫌抄襲的內(nèi)容,填寫(xiě)侵權(quán)投訴表單進(jìn)行舉報(bào),一經(jīng)查實(shí),本社區(qū)將立刻刪除涉嫌侵權(quán)內(nèi)容