go: Fail-Fast Pattern

项目结构:

image

 

/*
# 版权所有  2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:Fail-Fast Pattern 快速失败模式
# Author    : geovindu,Geovin Du 涂聚文.
# IDE       : goLang 2024.3.6 go 26.2
# os        : windows 10
# database  : mysql 9.0 sql server 2019, postgreSQL 17.0  Oracle 21c Neo4j
# Datetime  : 2026/6/30 21:25
# User      :  geovindu
# Product   : GoLand
# Project   : godesginpattern
# File      : fail_fast.go
*/
package exceptions

type ResourceCheckFailedError struct {
	Msg string
}

func (e *ResourceCheckFailedError) Error() string {
	return e.Msg
}

func NewFailFastErr(msg string) error {
	return &ResourceCheckFailedError{Msg: msg}
}



/*
# 版权所有  2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:Fail-Fast Pattern 快速失败模式
# Author    : geovindu,Geovin Du 涂聚文.
# IDE       : goLang 2024.3.6 go 26.2
# os        : windows 10
# database  : mysql 9.0 sql server 2019, postgreSQL 17.0  Oracle 21c Neo4j
# Datetime  : 2026/6/30 21:26
# User      :  geovindu
# Product   : GoLand
# Project   : godesginpattern
# File      : inventory_repo.go
*/
package repository

type InventoryRepository struct {
	stockMap map[string]int
}

func NewInventoryRepository() *InventoryRepository {
	repo := &InventoryRepository{
		stockMap: make(map[string]int),
	}
	// 初始化测试库存
	repo.stockMap["DIA001"] = 2
	repo.stockMap["DIA002"] = 0
	return repo
}

func (r *InventoryRepository) GetStock(productId string) int {
	val, ok := r.stockMap[productId]
	if !ok {
		return -1
	}
	return val
}

func (r *InventoryRepository) DeductStock(productId string, qty int) {
	r.stockMap[productId] -= qty
}



/*
# 版权所有  2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:Fail-Fast Pattern 快速失败模式
# Author    : geovindu,Geovin Du 涂聚文.
# IDE       : goLang 2024.3.6 go 26.2
# os        : windows 10
# database  : mysql 9.0 sql server 2019, postgreSQL 17.0  Oracle 21c Neo4j
# Datetime  : 2026/6/30 21:27
# User      :  geovindu
# Product   : GoLand
# Project   : godesginpattern
# File      : external_services_repo.go
*/
package repository

type ExternalServices struct {
	InventoryService  bool
	PaymentGateway    bool
	QualityInspection bool
	InvoiceService    bool
}

func NewExternalServices() *ExternalServices {
	return &ExternalServices{
		InventoryService:  true,
		PaymentGateway:    true,
		QualityInspection: true,
		InvoiceService:    true,
	}
}



/*
# 版权所有  2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:Fail-Fast Pattern 快速失败模式
# Author    : geovindu,Geovin Du 涂聚文.
# IDE       : goLang 2024.3.6 go 26.2
# os        : windows 10
# database  : mysql 9.0 sql server 2019, postgreSQL 17.0  Oracle 21c Neo4j
# Datetime  : 2026/6/30 21:27
# User      :  geovindu
# Product   : GoLand
# Project   : godesginpattern
# File      : validation_service.go
*/
package service

import (
	"godesginpattern/failfast/exceptions"
	"godesginpattern/failfast/repository"
)

type ValidationService struct {
	invRepo *repository.InventoryRepository
	extSvc  *repository.ExternalServices
}

func NewValidationService(inv *repository.InventoryRepository, ext *repository.ExternalServices) *ValidationService {
	return &ValidationService{
		invRepo: inv,
		extSvc:  ext,
	}
}

func (v *ValidationService) FailFastCheck(customerId, productId string, quantity int) error {
	// 1. 顾客校验
	if len(customerId) < 3 {
		return exceptions.NewFailFastErr("顾客信息无效,立即失败")
	}
	// 2. 商品是否存在
	stock := v.invRepo.GetStock(productId)
	if stock == -1 {
		return exceptions.NewFailFastErr("商品不存在,立即失败")
	}
	// 3. 库存校验
	if stock < quantity {
		return exceptions.NewFailFastErr("库存不足,立即失败")
	}
	// 4. 外部服务校验
	if !v.extSvc.InventoryService {
		return exceptions.NewFailFastErr("库存服务不可用,立即失败")
	}
	if !v.extSvc.PaymentGateway {
		return exceptions.NewFailFastErr("支付网关不可用,立即失败")
	}
	if !v.extSvc.QualityInspection {
		return exceptions.NewFailFastErr("质检服务不可用,立即失败")
	}
	if !v.extSvc.InvoiceService {
		return exceptions.NewFailFastErr("发票服务不可用,立即失败")
	}
	return nil
}




/*
# 版权所有  2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:Fail-Fast Pattern 快速失败模式
# Author    : geovindu,Geovin Du 涂聚文.
# IDE       : goLang 2024.3.6 go 26.2
# os        : windows 10
# database  : mysql 9.0 sql server 2019, postgreSQL 17.0  Oracle 21c Neo4j
# Datetime  : 2026/6/30 21:28
# User      :  geovindu
# Product   : GoLand
# Project   : godesginpattern
# File      : order_service.go
*/
package service

import (
	"godesginpattern/failfast/repository"
	//"godesginpattern/failfast/exceptions"
	"strconv"
	"time"
)

type OrderService struct {
	valSvc  *ValidationService
	invRepo *repository.InventoryRepository
	extSvc  *repository.ExternalServices
}

func NewOrderService(val *ValidationService, inv *repository.InventoryRepository, ext *repository.ExternalServices) *OrderService {
	return &OrderService{
		valSvc:  val,
		invRepo: inv,
		extSvc:  ext,
	}
}

func (o *OrderService) CreateOrder(customerId, productId string, quantity int) (map[string]interface{}, error) {
	err := o.valSvc.FailFastCheck(customerId, productId, quantity)
	if err != nil {
		return nil, err
	}
	// 校验通过执行业务
	o.invRepo.DeductStock(productId, quantity)
	orderId := "ORD" + strconv.FormatInt(time.Now().Unix(), 10)
	res := map[string]interface{}{
		"order_id":        orderId,
		"product_id":      productId,
		"quantity":        quantity,
		"remaining_stock": o.invRepo.GetStock(productId),
		"status":          "success",
	}
	return res, nil
}



/*
# 版权所有  2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:Fail-Fast Pattern 快速失败模式
# Author    : geovindu,Geovin Du 涂聚文.
# IDE       : goLang 2024.3.6 go 26.2
# os        : windows 10
# database  : mysql 9.0 sql server 2019, postgreSQL 17.0  Oracle 21c Neo4j
# Datetime  : 2026/6/30 21:31
# User      :  geovindu
# Product   : GoLand
# Project   : godesginpattern
# File      : order_controller.go
*/
package api

import (
	"fmt"
	"godesginpattern/failfast/exceptions"
	"godesginpattern/failfast/service"
)

type OrderController struct {
	orderSvc *service.OrderService
}

func NewOrderController(svc *service.OrderService) *OrderController {
	return &OrderController{
		orderSvc: svc,
	}
}

func (c *OrderController) CreateJewelryOrder(customerId, productId string, quantity int) string {
	res, err := c.orderSvc.CreateOrder(customerId, productId, quantity)
	if err != nil {
		if e, ok := err.(*exceptions.ResourceCheckFailedError); ok {
			return "\n❌ 快速失败: " + e.Msg
		}
		return "\n❌ 业务异常: " + err.Error()
	}
	return "\n✅ 订单创建成功!详情:" + fmt.Sprintf("%v", res)
}

  

调用:

/*
# 版权所有  2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:failfast
# Author    : geovindu,Geovin Du 涂聚文.
# IDE       : goLang 2024.3.6 go 26.2
# os        : windows 10
# database  : mysql 9.0 sql server 2019, postgreSQL 17.0  Oracle 21c Neo4j
# Datetime  : 2026/6/30 21:32
# User      :  geovindu
# Product   : GoLand
# Project   : godesginpattern
# File      : failfastbll.go
*/
package bll

import (
	"fmt"
	"godesginpattern/failfast/api"
	"godesginpattern/failfast/repository"
	"godesginpattern/failfast/service"
)

func FailfastMain() {
	// 初始化依赖(和Python代码一一对应)
	inventoryRepo := repository.NewInventoryRepository()
	extServices := repository.NewExternalServices()
	validationService := service.NewValidationService(inventoryRepo, extServices)
	orderService := service.NewOrderService(validationService, inventoryRepo, extServices)
	controller := api.NewOrderController(orderService)

	// ======================
	// 测试场景 完全对齐Python输出
	// ======================
	fmt.Println("==== 场景1:正常下单 ===")
	fmt.Println(controller.CreateJewelryOrder("C1001", "DIA001", 1))

	fmt.Println("\n==== 场景2:库存不足 ===")
	fmt.Println(controller.CreateJewelryOrder("C1001", "DIA002", 1))

	fmt.Println("\n==== 场景3:顾客无效 ===")
	fmt.Println(controller.CreateJewelryOrder("C", "DIA001", 1))

	fmt.Println("\n==== 场景4:支付服务挂了 ===")
	extServices.PaymentGateway = false
	fmt.Println(controller.CreateJewelryOrder("C1001", "DIA001", 1))
}

  

输出:

4221cf3d24cd24b9cd67212fc8678c9a

 

posted @ 2026-06-30 22:17  ®Geovin Du Dream Park™  阅读(3)  评论(0)    收藏  举报