2022-09-08 13:39

架構解釋

以前在專案開發時對分層架構所定下的原則,去避免不必要的地雷,以及每一層的要處裡的職權。

我會考慮分層架構,是希望提高系統的嚴謹度,以及 Method 的共用性,所以 Dao 層級就要避免功能導向,不然就是把單頁的程式拆分到多個層去而已。

 

DomainModel / ViewModel

  • 這三類都屬於 POCO 類型的物件,單純的資料載體,不允許有動作的 method,不可以外部取資料
  • 相同資料的欄位命名必須一致,反例: ProjectId, Pid, pid, PID, p_id
  • 有欄位就要有資料,明明有欄位定義卻不從 DB 取資料,這會造成不必要的雷

 

DomainModel

  • 欄位定義可與 DB 一致
  • 將 DB 的資料進行彙整,成為完整的資料體

 

ViewModel

欄位定義與 View 的表單(Form)一致,與 DomainModel 可能很相似,但有些欄位只會用在表單上,所以 DomainModel 不適合用在表單 Binding 上

例如:

  • 同意上述條款
  • 舊密碼, 新密碼, 確認密碼

 

Dao

  • 回傳 DomainModel
  • 定義單純的 BD 操作 List, GetById, Save, Insert, Update
  • 與 ORM 不同,是進一步將資料操作簡化
  • 保證 Method 的通用性,避免功能導向,例如: 有一個 Method 是專門為了A畫面功能而存在的

 

Service

  • 回傳 DomainModel
  • 驗證商業邏輯,如必要資料欄位,數值範圍等...
  • 調用一個或多個 Dao 來完成商業邏輯
  • 處理 DB 交易,來協調多個 Dao 的調用

 

Controller

  • 處理 DomainModel 到 ViewModel 的轉換
  • 調用 Service 進行 DomainModel 的資料處理
  • 調配 Responses 的結果 Html, Json, PDF ...
  • 驗證資料類型的正確,數值﹑日期
  • 負責 Access 的權限阻擋

 

View

  • View 是被動的,不能存取任何 Controller / Service / Dao
  • 負責資料呈現及格式化,如 日期﹑金額 ...
  • Ajax 只能對 Controller 調用

 

附註

  1. 同一層之間不可以互相參考,這容易發生循環參考,例如:
    • Controller 呼叫 Controller
    • Service 呼叫 Service
    • Dao 呼叫 Dao
  2. 同一層之間有相同邏輯可以抽離到 Support 類
     
  3. 建議定義命名規範,讓每一個人寫出來的程式像是同一個人寫的,好處是降低支援或接手的人的困難度
     
  4. 任何第三方的 API 都需要包裝,隔離直接相依的問題,而且可以單獨測試
     

 

架構關係全貌

 

Model 傳遞的關係

 

用 Interface 隔離實作

 

Web Api 的呼叫關係

 

2022-09-05 11:29

[轉載] opencv js getPerspectiveTransform,perspectiveTransform 方法使用

轉載自: opencvjs getPerspectiveTransform,perspectiveTransform方法使用

OpenCV JavaScript版本,使用getPerspectiveTransform,PerspectiveTransform方法。

JavaScript和python版本不同的是Mat的创建方法不同,python会在内部自动把数据转换成Mat类,也JavaScript不会,所以刚开始没有找到JavaScript创建Mat方法,走了很多弯路。

这只是测试代码,没有使用项目中真实的数据,所有有一定的偏差。

如果有什么错误,欢迎纠正。

下面上代码:

  1. <!DOCTYPE html> 
  2. <html> 
  3.  
  4. <head> 
  5.  <meta charset="utf-8"> 
  6.  <title>Hello OpenCV.js</title> 
  7. </head> 
  8.  
  9. <body> 
  10.  <h2>Hello OpenCV.js</h2> 
  11.  <h2>getPerspectiveTransform,PerspectiveTransform方法使用</h2> 
  12.  <p id="status">OpenCV.js is loading...</p> 
  13.  <div> 
  14.    <button onClick="myclick()">输出结果</button> 
  15.  </div> 
  16.  <script type="text/javascript"> 
  17.    function myclick() { 
  18.      //代码 getPerspectiveTransform 
  19.      //创建数据 
  20.      let srcTri = cv.matFromArray(4, 1, cv.CV_32FC2, [56, 65, 368, 52, 28, 387, 389, 390]); 
  21.      let dstTri = cv.matFromArray(4, 1, cv.CV_32FC2, [0, 0, 300, 0, 0, 300, 300, 300]); 
  22.      //转换的数据 
  23.      let M = cv.getPerspectiveTransform(srcTri, dstTri); 
  24.      console.log("getPerspectiveTransform M", M); 
  25.  
  26.      //==== PerspectiveTransform ====== 
  27.      //point点的数据一定要是一维的,opencv会自己去处理 
  28.      let points = [ 
  29.        1, 2, 
  30.        3, 4, 
  31.        5, 6, 
  32.        7, 8 
  33.      ]; 
  34.      //原数据 
  35.      points = cv.matFromArray(4,1,cv.CV_32FC2,points); 
  36.      //转换后的数据 
  37.      let points_trans = new cv.Mat(); 
  38.      cv.perspectiveTransform(points, points_trans,M); 
  39.      console.log("points", points); 
  40.      console.log("points_trans", points_trans); 
  41.  
  42.    } 
  43.    function onOpenCvReady() { 
  44.      document.getElementById('status').innerHTML = 'OpenCV.js is ready.'; 
  45.  
  46.    } 
  47.  </script> 
  48.  <script async src="https://docs.opencv.org/4.x/opencv.js" onload="onOpenCvReady();" type="text/javascript"></script> 
  49.  <script src="https://docs.opencv.org/4.x/utils.js" type="text/javascript"></script> 
  50. </body> 
  51.  
  52. </html> 

getPerspectiveTransform结果

perspectiveTransform结果