<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      Go后端架構探索: MVC 與 DDD 分層架構有何不同?

      Go語言 MVC 與 DDD 分層架構詳細對比

      MVCDDD是后臺開發兩種流行的分層架構思想,MVC(Model-View-Controller)是一種設計模式,主要用于分離用戶界面、業務邏輯和數據模型,便于分層解耦,而DDD(領域驅動設計)則是一種架構方法論,旨在通過構建業務領域模型來解決復雜系統中的設計和維護難題。

      在Java領域,很多系統逐漸由MVC逐漸轉為DDD,但在Go、Python、NodeJS等語言,秉持簡單高效的理念,MVC依然是主流架構。下面基于Go語言來具體探討下MVCDDD兩種目錄結構的區別。

      MVC 圖形結構

      +------------------+
      |      View        | 用戶界面層:負責數據展示和用戶交互(如HTML頁面、API響應)
      +------------------+
      |   Controller     | 控制層:處理用戶請求,調用Service邏輯,協調Model與View
      +------------------+
      |      Model       | 模型層:包含數據對象(如數據庫表結構)和部分業務邏輯(常分散在Service層)
      +------------------+
      

      DDD 圖形結構

      +--------------------+
      |   用戶界面層(UI)    | 負責用戶交互和展示(如REST API、Web界面)
      +--------------------+
      | 應用層(Application)| 編排業務流程(如調用領域服務、事務管理),不包含核心業務規則
      +--------------------+
      |  領域層(Domain)    | 核心業務邏輯層:包含聚合根、實體、值對象、領域服務等,內聚業務規則
      +--------------------+
      |      基礎設施層      | 提供技術實現(如數據庫訪問、消息隊列、外部API)
      |  (Infrastructure) | 
      +--------------------+
      

      MVCDDD 的主要區別:

      1. 代碼組織邏輯
      MVC 按技術功能分層(Controller/Service/DAO),關注技術實現;DDD 按業務領域劃分模塊(如訂單域、支付域),以限界上下文隔離核心業務邏輯。

      2. 業務邏輯載體
      MVC 通常采用貧血模型,數據(Model)與行為(Service)分離,邏輯分散導致維護成本高;DDD 通過聚合根、領域服務實現充血模型,業務邏輯內聚于領域層,增強可擴展性。

      3. 適用性與成本
      MVC 開發成本低,適合需求穩定的中小型系統;DDD 需前期領域建模和統一語言,適用于業務復雜、需長期演進的大型系統,但團隊需具備領域抽象能力。例如,電商促銷規則用 DDD 可避免邏輯散落在多個 Service 中。


      Go語言 MVC 目錄結構

      MVC主要分為三層:視圖、控制器、模型。

      gin-order/
      ├── cmd
      │   └── main.go                  # 應用入口,啟動 Gin 引擎
      ├── internal
      │   ├── controllers              # 控制器層(處理 HTTP 請求),也可以叫handlers
      │   │   └── order
      │   │       └── order_controller.go  # Order 模塊的控制器
      │   ├── services                 # 服務層(業務邏輯處理)
      │   │   └── order
      │   │       └── order_service.go       # Order 模塊的服務實現
      │   ├── repository               # 數據訪問層(與數據庫交互)
      │   │   └── order
      │   │       └── order_repository.go    # Order 模塊的數據訪問接口及實現
      │   ├── models                   # 模型層(數據結構定義)
      │   │   └── order
      │   │       └── order.go               # Order 模塊的數據模型
      │   ├── middleware               # 中間件(如鑒權、日志、請求攔截)
      │   │   ├── logging.go             # 日志中間件
      │   │   └── auth.go                # 鑒權中間件
      │   └── config                   # 配置模塊(數據庫、服務器等配置)
      │       └── config.go                # 應用與環境配置
      ├── pkg                          # 公共工具包(如響應包裝工具)
      │   └── response.go              # 響應處理工具方法
      ├── web                          # 前端資源(模板與靜態資源)
      │   ├── static                   # 靜態資源(CSS、JS、圖片)
      │   └── templates                # 模板文件(HTML模板)
      │       └── order.tmpl           # Order 模塊的視圖模板(如果需要渲染HTML)
      ├── go.mod                       # Go 模塊管理文件
      └── go.sum                       # Go 模塊依賴版本鎖定
      

      Go語言 DDD 目錄結構

      DD主要分為四層:界面、應用、領域、基礎。

      go-web/
      │── cmd/
      │   └── main.go               # 應用入口
      │── internal/
      │   ├── application/          # 應用層(協調領域邏輯,處理業務用例)
      │   │   ├── services/         # 服務層,業務邏輯目錄
      │   │   │   └── order_service.go # 訂單應用服務,調用領域層業務邏輯
      │   ├── domain/               # 領域層(核心業務邏輯和接口定義)
      │   │   ├── order/            # 訂單聚合
      │   │   │   ├── order.go      # 訂單實體(聚合根),包含核心業務邏輯
      │   │   ├── repository/       # 通用倉庫接口
      │   │   │   ├── repository.go # 通用倉庫接口(通用 CRUD 操作)
      │   │   │   └── order_repository.go # 訂單倉儲接口,定義對訂單數據的操作
      │   ├── infrastructure/       # 基礎設施層(實現領域層定義的接口)
      │   │   ├── repository/       # 倉儲實現
      │   │   │   └── order_repository_impl.go  # 訂單倉儲實現,具體的訂單數據存儲
      │   └── interfaces/           # 接口層(處理外部請求,如HTTP接口)
      │   │   ├── handlers/         # HTTP 處理器
      │   │   │  └── order_handler.go # 訂單相關的HTTP處理器
      │   │   └── routes/
      │   │   │   ├── router.go     # 基礎路由工具設置
      │   │   │   └── order-routes.go # 訂單路由地址配置
      │   │   │   └── order-routes-test.go # 訂單路由測試
      │   └── middleware/           # 中間件(例如:鑒權、攔截、認證等)
      │   │   └── logging.go        # 日志中間件
      │   ├── config/               # 服務相關配置
      │   │   └── server_config.go  # 服務器配置(如端口、超時設置等)
      │── pkg/                      # 可復用的公共庫
      │   └── utils/                # 工具類(例如:日志、日期處理等)
      

      Go語言 MVC 代碼實現

      源碼:https://github.com/microwind/design-patterns/tree/main/mvx/mvc/gin-mvc

      Controller(接口層) → Service(業務邏輯層) → Repository(數據訪問層) → Model(數據模型)
      

      分層代碼

      • 控制器層(Controller)
      // internal/controller/order/order.go
      package order
      
      import (
          "net/http"
          "strconv"
          "github.com/gin-gonic/gin"
          "github.com/gin-order/internal/model"
          "github.com/gin-order/internal/service/order"
          "github.com/gin-order/internal/pkg/response"
      )
      
      type OrderController struct {
          service *order.OrderService
      }
      
      func NewOrderController(service *order.OrderService) *OrderController {
          return &OrderController{service: service}
      }
      
      func (c *OrderController) GetOrder(ctx *gin.Context) {
          idStr := ctx.Param("id")
          id, _ := strconv.ParseUint(idStr, 10, 64)
          
          order, err := c.service.GetOrderByID(uint(id))
          if err != nil {
              response.Error(ctx, http.StatusNotFound, "Order not found")
              return
          }
          
          response.Success(ctx, order)
      }
      
      func (c *OrderController) CreateOrder(ctx *gin.Context) {
          var req model.Order
          if err := ctx.ShouldBindJSON(&req); err != nil {
              response.Error(ctx, http.StatusBadRequest, "Invalid request")
              return
          }
          
          if err := c.service.CreateOrder(&req); err != nil {
              response.Error(ctx, http.StatusInternalServerError, "Create failed")
              return
          }
          
          response.Success(ctx, req)
      }
      
      • 路由配置
      // cmd/server/main.go
      package main
      
      import (
          "github.com/gin-gonic/gin"
          "github.com/gin-order/internal/controller/order"
          "github.com/gin-order/internal/pkg/database"
          "github.com/gin-order/internal/repository/order"
          "github.com/gin-order/internal/service/order"
      )
      
      func main() {
          // 初始化數據庫
          db := database.NewGORM()
          
          // 依賴注入
          orderRepo := order_repo.NewMySQLOrderRepository(db)
          orderService := order_service.NewOrderService(orderRepo)
          orderController := order_controller.NewOrderController(orderService)
          
          // 創建路由
          r := gin.Default()
          
          // 注冊中間件
          r.Use(middleware.Logger())
          
          // 路由分組
          apiGroup := r.Group("/api")
          {
              orderGroup := apiGroup.Group("/orders")
              {
                  orderGroup.GET("/:id", orderController.GetOrder)
                  orderGroup.POST("", orderController.CreateOrder)
              }
          }
          
          // 啟動服務
          r.Run(":8080")
      }
      
      • 服務層(Service)
      // internal/service/order/service.go
      package order
      
      import (
          "github.com/gin-order/internal/model"
          "github.com/gin-order/internal/repository/order"
      )
      
      type OrderService struct {
          repo order.OrderRepository
      }
      
      func NewOrderService(repo order.OrderRepository) *OrderService {
          return &OrderService{repo: repo}
      }
      
      func (s *OrderService) GetOrderByID(id uint) (*model.Order, error) {
          return s.repo.FindByID(id)
      }
      
      func (s *OrderService) CreateOrder(order *model.Order) error {
          return s.repo.Create(order)
      }
      
      • 數據訪問層(Repository)
      // internal/repository/order/interface.go
      package order
      
      import "github.com/gin-order/internal/model"
      
      type OrderRepository interface {
          FindByID(id uint) (*model.Order, error)
          Create(order *model.Order) error
          FindByStatus(status string) ([]model.Order, error)
      }
      
      // internal/repository/order/mysql.go
      package order
      
      import (
          "gorm.io/gorm"
          "github.com/gin-order/internal/model"
      )
      
      type MySQLOrderRepository struct {
          db *gorm.DB
      }
      
      func NewMySQLOrderRepository(db *gorm.DB) OrderRepository {
          return &MySQLOrderRepository{db: db}
      }
      
      func (r *MySQLOrderRepository) FindByID(id uint) (*model.Order, error) {
          var order model.Order
          if err := r.db.First(&order, id).Error; err != nil {
              return nil, err
          }
          return &order, nil
      }
      
      func (r *MySQLOrderRepository) Create(order *model.Order) error {
          return r.db.Create(order).Error
      }
      
      func (r *MySQLOrderRepository) FindByStatus(status string) ([]model.Order, error) {
          var orders []model.Order
          if err := r.db.Where("status = ?", status).Find(&orders).Error; err != nil {
              return nil, err
          }
          return orders, nil
      }
      
      • 模型層(Model)
      // internal/model/order.go
      package model
      
      import "time"
      
      type Order struct {
          OrderID     uint      `gorm:"primaryKey;column:order_id"`
          OrderNo     string    `gorm:"uniqueIndex;column:order_no"`
          UserID      uint      `gorm:"index;column:user_id"`
          OrderName   string    `gorm:"column:order_name"`
          Amount      float64   `gorm:"type:decimal(10,2);column:amount"`
          Status      string    `gorm:"column:status"`
          CreatedAt   time.Time `gorm:"column:created_at"`
          UpdatedAt   time.Time `gorm:"column:updated_at"`
      }
      
      func (Order) TableName() string {
          return "orders"
      }
      

      Go語言 MVC 最佳實踐

      接口隔離原則

      Repository 層通過接口定義,支持多種數據庫實現

      // 可輕松切換為 Mock 實現
      type MockOrderRepository struct {}
      func (m *MockOrderRepository) FindByID(id uint) (*model.Order, error) {
          return &model.Order{OrderNo: "mock-123"}, nil
      }
      

      統一響應格式

      // pkg/response/response.go
      func Success(c *gin.Context, data interface{}) {
          c.JSON(http.StatusOK, gin.H{
              "code":    0,
              "message": "success",
              "data":    data,
          })
      }
      

      中間件鏈

      // 全局中間件
      r.Use(gin.Logger(), gin.Recovery())
      
      // 路由組中間件
      adminGroup := r.Group("/admin", middleware.AuthJWT())
      

      數據庫遷移

      使用 GORM AutoMigrate:

      db.AutoMigrate(&model.Order{})
      

      Go語言 DDD 代碼實現與最佳實踐

      源碼:https://github.com/microwind/design-patterns/tree/main/domain-driven-design/go-web

      1. 關注領域模型

      DDD 強調領域模型的構建,使用 聚合(Aggregate)實體(Entity)值對象(Value Object) 組織業務邏輯。

      在 Go 語言中,通常使用 struct 定義實體和值對象:

      // 實體(Entity)
      type User struct {
          ID   int
          Name string
      }
      

      2. 分層架構

      DDD 通常采用 分層架構,Go 語言項目可以遵循如下結構:

      • 領域層(Domain Layer):核心業務邏輯,如 domain 目錄下的實體和聚合。
      • 應用層(Application Layer):用例(Use Cases)和業務流程編排。
      • 基礎設施層(Infrastructure Layer):數據庫、緩存、外部 API 適配等。
      • 接口層(Interface Layer):提供 HTTP、gRPC 或 CLI 接口。

      3. 依賴倒置(Dependency Inversion)

      領域層不應直接依賴基礎設施,而是通過 接口(Interface) 進行依賴倒置。

      注:DDD架構核心就是依賴倒置(DIP),Domain是最核心的內層,僅定義業務規則和接口抽象,其他層級依賴Domain實現,Domain不依賴任何外部實現。在六邊形架構(Hexagonal Architecture)中,領域層位于核心,其他層級(如應用層、基礎設施層)通過實現領域層定義的接口來提供具體技術細節(如數據庫操作、API 調用),從而達成領域與技術實現的解耦。

      // 領域層:定義接口
      type UserRepository interface {
          GetByID(id int) (*User, error)
      }
      
      // 基礎設施層:數據庫實現
      type userRepositoryImpl struct {
          db *sql.DB
      }
      
      func (r *userRepositoryImpl) GetByID(id int) (*User, error) {
          // 數據庫查詢邏輯
      }
      

      4. 聚合(Aggregate)管理

      聚合根(Aggregate Root)管理整個聚合的生命周期:

      type Order struct {
          ID      int
          Items   []OrderItem
          Status  string
      }
      
      func (o *Order) AddItem(item OrderItem) {
          o.Items = append(o.Items, item)
      }
      

      5. 應用服務(Application Service)

      應用服務封裝領域邏輯,避免外部直接操作領域對象:

      type OrderService struct {
          repo OrderRepository
      }
      
      func (s *OrderService) CreateOrder(userID int, items []OrderItem) (*Order, error) {
          order := Order{UserID: userID, Items: items, Status: "Pending"}
          return s.repo.Save(order)
      }
      

      6. 事件驅動(Event-Driven)

      使用 領域事件(Domain Events) 進行解耦,在 Go 語言中可通過 ChannelPub/Sub 實現:

      type OrderCreatedEvent struct {
          OrderID int
      }
      
      def publishEvent(event OrderCreatedEvent) {
          go func() {
              eventChannel <- event
          }()
      }
      

      7. 結合 CQRS(命令查詢職責分離)

      DDD 可結合 CQRS(Command Query Responsibility Segregation),在 Go 語言中可用 命令(Command) 處理變更操作,用 查詢(Query) 處理數據讀取:

      type CreateOrderCommand struct {
          UserID int
          Items  []OrderItem
      }
      
      func (h *OrderHandler) Handle(cmd CreateOrderCommand) (*Order, error) {
          return h.service.CreateOrder(cmd.UserID, cmd.Items)
      }
      

      MVC與DDD架構總結

      1. 架構核心區別

      維度 MVC 架構 DDD 架構
      層級 三層:Controller/Service/DAO 四層:接口層/應用層/領域層/基礎設施層
      職責 - Controller 處理請求,Service 承載邏輯
      - DAO 直接操作數據庫
      - 應用層編排流程(如調用領域服務)
      - 領域層內聚業務原子操作(如訂單創建規則)
      - 基礎設施層實現技術細節(如數據庫訪問)
      痛點 Service 層臃腫,業務邏輯與數據操作耦合 領域層獨立于技術實現,邏輯與層級強對應

      2. 模塊化與擴展性

      MVC

      • 高耦合:缺乏明確的業務邊界,跨模塊調用(如訂單服務直接依賴賬戶表)導致代碼難以維護。
      • 擴展性差:新增功能需全局修改(如添加風控規則需侵入訂單服務),易引發連鎖問題。

      DDD

      • 限界上下文:按業務能力劃分模塊(如支付域、風控域),通過事件驅動(如訂單支付完成事件)解耦協作。
      • 獨立演進:各領域模塊可獨立升級(如支付邏輯優化不影響訂單服務),降低系統級風險。

      3. 適用場景區別

      • 中小系統優先 MVC:業務簡單(如博客、CMS、管理后臺),需快速開發且業務規則清晰,無后續反復變更。
      • 復雜業務轉向 DDD:規則密集(如金融交易、供應鏈)、多領域協作(如電商訂單與庫存聯動),后續變更頻繁。

      更多架構設計源碼

      posted @ 2025-03-30 20:58  刀法如飛  閱讀(820)  評論(1)    收藏  舉報
      主站蜘蛛池模板: 日韩一区二区三区水蜜桃| 亚洲人成网站77777在线观看 | 欧美人与zoxxxx另类| 久久精品免费自拍视频| 最近中文字幕国产精品| 国产成人欧美一区二区三区 | 中文字字幕在线中文乱码| 国产乱妇无乱码大黄aa片| 中国女人熟毛茸茸A毛片| 亚洲色最新高清AV网站| 樱花草视频www日本韩国| 枞阳县| 亚洲国产精品男人的天堂| 欧美疯狂三p群体交乱视频| 久久精品熟妇丰满人妻久久| 欧美丰满熟妇乱XXXXX网站| av天堂久久天堂av| 长泰县| 日韩精品区一区二区三vr| 国产精品久久久久久亚洲色| 亚洲av网一区天堂福利| 国产mv在线天堂mv免费观看| 欧美高清精品一区二区 | 女人被爽到高潮视频免费国产| 玩弄放荡人妻少妇系列| 爽爽精品dvd蜜桃成熟时电影院| 日本久久一区二区三区高清| 红桥区| 2021亚洲国产精品无码 | 亚洲一区av在线观看| 思思久99久女女精品| 日韩午夜午码高清福利片| 国产精品免费看久久久| 国产成人精品无码播放| 老色鬼永久精品网站| 国产va免费精品观看精品| 久久精品女人天堂av免费观看 | 中文无码乱人伦中文视频在线| 国产a在视频线精品视频下载| AV免费网址在线观看| 毛片亚洲AV无码精品国产午夜|