自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

煩死了,業(yè)務代碼老寫不好...

開發(fā) 前端 開發(fā)工具
本文舉一個非常簡單的例子,以案例的業(yè)務實現(xiàn)來分析如何寫好業(yè)務代碼。

 [[401825]]

圖片來自 Pexels

本案例只是簡單的模擬,可能與真實的情況有出入,這里只是為了舉例使用。

案例:用戶挑選商品放入購物車,然后下單結算。

流程如下:挑選商品→下單→結算→生成訂單→通知。

提交下單的業(yè)務邏輯如下:驗證賬號是否合法→調用第三方接口查看商品的打折價格→錢包金額扣除→生成訂單信息→通知用戶下單成功,等待收貨。

代碼實現(xiàn):

  1. @Service 
  2. public class OrderServiceImpl implements OrderService { 
  3.     @Autowired 
  4.     private UserMapper userMapper; 
  5.     @Autowired 
  6.     private ProductMapper productMapper; 
  7.     @Autowired 
  8.     private OrderMapper orderMapper; 
  9.     @Autowired 
  10.     private KafkaTemplate kafkaTemplate; 
  11.  
  12.     /** 
  13.      *  購買商品,提交訂單 
  14.      * @param userId      用戶ID 
  15.      * @param productId   商品ID 
  16.      * @return 
  17.      */ 
  18.     public Result submit(Long userId, Long productId) throws BizException { 
  19.         // 驗證賬號 
  20.         UserDO userDO = userMapper.findById(userId); 
  21.         if (userDO == null) { 
  22.             throw BizException(USER_NOT_EXISTS); 
  23.         } 
  24.         // 查看商品信息及打折信息 
  25.         ProductDO productDO = productMapper.findById(productId); 
  26.         Double delta = HttpUtils.getDiscount(productId); 
  27.         double actualPayment = productDO.getPrice() - delta; 
  28.         Money money = userDO.getMoney(); 
  29.         if (actualPayment > money.getRemain()) { 
  30.             // 如果商品價格 - 優(yōu)惠價格 > 用戶錢包,則說明不夠付 
  31.             return Result.fail("余額不足"); 
  32.         } 
  33.         // 錢包夠付,扣除金額 
  34.         double remain = money.getRemain() - actualPayment; 
  35.         money.setRemain(remain); 
  36.         // 更新賬號錢包余額 
  37.         userMapper.update(userDO); 
  38.         // 生成訂單信息 
  39.         OrderDO orderDO = new OrderDO(); 
  40.         orderDO.setUserId(userId); 
  41.         orderDO.setProductId(productId); 
  42.         orderMapper.save(orderDO); 
  43.         // 通知用戶訂單已生成,等待收貨 
  44.         kafkaTemplate.send("orderTopic", orderDO); 
  45.         return Result.ok(); 
  46.     } 

上面代碼寫好了,而且可以實現(xiàn)相關功能,但是隨著業(yè)務的迭代,可能會出現(xiàn)很多問題。

①可維護性差

XxMapper 是基于 Mybatis 實現(xiàn)數(shù)據操作層,也就把技術細節(jié)帶入業(yè)務邏輯中了,如果技術實現(xiàn)變了(改為使用 Hibernate,或 Mybatis 版本升級造成用法改變等),業(yè)務代碼就得改變。

XxDO 是和數(shù)據表綁定的,數(shù)據表結構變更等也會影響業(yè)務代碼。

調用第三方 API,直接在業(yè)務代碼中調用 HttpUtils 完成,未來第三方 API 修改了方法簽名或返回值,或改為了 RPC 接口,那么業(yè)務代碼也會隨著改變。

發(fā)送消息直接使用 KafkaTemplate,如果技術選型變了要改為使用 RocketMQ,那么業(yè)務代碼還得變。

②可擴展性差

如果商品因為做活動又加了其他的優(yōu)惠,或商品某一段時間不打折了,那么原有的代碼就會重新改來改去。

業(yè)務邏輯和數(shù)據存儲結構是強依賴的,數(shù)據存儲結構的變化對業(yè)務的影響可想而知。

③可測試性差

因為直接依賴了數(shù)據庫,第三方接口,中間件,所以需要所有技術實現(xiàn)后才能進行測試,測試成本和時間都比較大。

代碼優(yōu)化一

我們上面說了,數(shù)據庫操作不應該直接暴露在業(yè)務邏輯中,因此把數(shù)據庫操作“隔離”開。

  1. public interface UserRepository { 
  2.     User findById(Long userId); 

新增 XxRepository 接口,業(yè)務邏輯直接依賴接口/抽象,而不應該直接依賴實現(xiàn)。

Repository 是數(shù)據倉庫,不一定非得是 DB,也可以是其他的數(shù)據操作。

Repository 返回的對象也不是 DO,與數(shù)據庫結構無關。

代碼優(yōu)化二

DO 對象是只有 set、get 操作,沒有其他行為,我們說這有時是一種貧血現(xiàn)象,會導致本該在業(yè)務領域實體中完成的事情散落到各個 Service 中,低內聚而且也不好維護。

增加領域實體,相關行為直接在實體內完成(高內聚):

  1. public class Money { 
  2.     private double remain; 
  3.     public double getRemain() { 
  4.         return remain; 
  5.     } 
  6.     public void setRemain(double remain) { 
  7.         this.remain = remain; 
  8.     } 
  9.     /** 
  10.      * 扣費 
  11.      * @param delta 
  12.      * @return 
  13.      */ 
  14.     public boolean charge(double delta) { 
  15.         if (remain < delta) { 
  16.             return false
  17.         } 
  18.         this.remain -= delta; 
  19.         return true
  20.     } 

代碼優(yōu)化三

第三方接口是不可靠的,方法簽名或返回值或調用方式都有可能會變的,如果直接在業(yè)務中依賴,會對業(yè)務造成“腐蝕”,所以應該加一層適配層(也叫防腐層 ACL)。

  1. /** 
  2.  * 防腐層/適配層 
  3.  */ 
  4. @Service 
  5. public class PayServiceImpl implements PayService { 
  6.  
  7.     @Autowired 
  8.     private DiscountFacade discountFacade; 
  9.  
  10.     /** 
  11.      *  支付 
  12.      * @param money 
  13.      * @param product 
  14.      * @return 
  15.      */ 
  16.     public boolean pay(Money money, Product product) { 
  17.         // 獲取優(yōu)惠 
  18.         Double delta = discountFacade.getDiscount(product.getId()); 
  19.         // 扣除費用 
  20.         return money.charge(product.getPrice() - delta); 
  21.     } 

代碼優(yōu)化四

抽象中間件,不直接依賴具體的 MQ 實現(xiàn):

  1. public interface MessageProducer<T, R> { 
  2.     Result<R> send(T message); 

總結

優(yōu)化后的代碼如下:

  1. @Autowired 
  2. private UserRepository userRepository; 
  3. @Autowired 
  4. private ProductRepository productRepository; 
  5. @Autowired 
  6. private OrderRepository orderRepository; 
  7. @Autowired 
  8. private MessageProducer<Order,Result> messageProducer; 
  9. @Autowired 
  10. private PayService payService; 
  11.  
  12. /** 
  13.  * 購買商品,提交訂單 
  14.  * @param userId      用戶ID 
  15.  * @param productId   商品ID 
  16.  * @return 
  17.  */ 
  18. public Result submit(Long userId, Long productId) throws BizException { 
  19.     // 驗證 
  20.     User user = userRepository.findByUserId(userId); 
  21.     if (user == null) { 
  22.         throw BizException(USER_NOT_EXISTS); 
  23.     } 
  24.     // 支付 
  25.     Product product = productRepository.findById(productId); 
  26.     boolean f = payService.pay(user.getMoney(), product); 
  27.     if (!f) { 
  28.         return Result.fail("費用扣除失敗"); 
  29.     } 
  30.     // 更新賬戶 
  31.     userRepository.update(user); 
  32.     // 生成訂單信息 
  33.     Order order = OrderFactory.create(user, product); 
  34.     orderRepository.add(order); 
  35.     // 通知用戶訂單已生成,等待收貨 
  36.     messageProducer.send(order); 
  37.     return Result.ok(); 

代碼不一定非常嚴謹,只是通過這一個簡單的例子告訴大家實際工作中代碼該怎么寫,該遵循哪些目標。

①獨立于框架:架構不應該依賴某個外部的庫或框架,不應該被框架的結構所束縛。

②獨立于 UI:前臺展示的樣式可能會隨時發(fā)生變化(今天可能是網頁、明天可能變成 console、后天是獨立 app),但是底層架構不應該隨之而變化。

③獨立于底層數(shù)據源:無論今天你用 MySQL、Oracle 還是 MongoDB、CouchDB,甚至使用文件系統(tǒng),軟件架構不應該因為不同的底層數(shù)據儲存方式而產生巨大改變。

④獨立于外部依賴:無論外部依賴如何變更、升級,業(yè)務的核心邏輯不應該隨之而大幅變化。

⑤可測試:無論外部依賴了什么數(shù)據庫、硬件、UI 或者服務,業(yè)務的邏輯應該都能夠快速被驗證正確性。

作者:構即人生

編輯:陶家龍

出處:toutiao.com/i6903053083555807752/

 

責任編輯:武曉燕 來源: 今日頭條
相關推薦

2021-01-29 08:52:10

App微信移動應用

2020-11-08 14:34:31

小視頻瀏覽器

2020-11-09 14:15:23

代碼菜鳥老司機

2019-12-27 14:00:43

傳統(tǒng)IT商業(yè)模式

2021-08-18 15:23:42

SDNSD-WAN軟件定義網絡

2009-08-25 09:32:31

2021-11-12 08:07:40

競品分析數(shù)據分析 大數(shù)據

2025-02-24 10:10:20

ChatGPTC#代碼

2023-10-25 16:36:06

數(shù)字化轉型IT系統(tǒng)

2009-11-20 12:54:42

2022-12-26 09:00:07

2024-02-26 00:00:00

RAGGeminiLLM

2019-01-22 08:58:41

代碼耦合業(yè)務

2020-11-26 06:29:20

代碼非業(yè)務程序員

2019-08-14 08:52:40

業(yè)務代碼運營

2020-09-21 05:57:11

代碼編程語言開發(fā)

2016-04-20 11:08:57

代碼歷史新功能

2021-10-18 17:54:13

論文博士數(shù)據

2012-07-03 09:59:03

程序員

2010-11-01 16:00:00

點贊
收藏

51CTO技術棧公眾號