๐Ÿ”ช ๅพฎๆœๅŠกๆ‹†ๅˆ†่‰บๆœฏ๏ผšๅฆ‚ไฝ•ไผ˜้›…ๅœฐ"ๅˆ†ๅฎถ"๏ผŸ

28 ้˜…่ฏป10ๅˆ†้’Ÿ

ๅ‰ฏๆ ‡้ข˜๏ผšDDD้ข†ๅŸŸ้ฉฑๅŠจ่ฎพ่ฎก + ๅบทๅจๅฎšๅพ‹๏ผŒๆ‰“้€ ๅฎŒ็พŽๅพฎๆœๅŠกๆžถๆž„๏ผ๐ŸŽฏ


๐ŸŽฌ ๅผ€ๅœบ๏ผšๆ‹†่ฟ˜ๆ˜ฏไธๆ‹†๏ผŸ

ๅ•ไฝ“ๅบ”็”จ็š„็—›

ๆŸ็”ตๅ•†ๅนณๅฐ็š„ๆผ”่ฟ›ๅฒ๏ผš

็ฌฌ1ๅนด๏ผˆๅˆ›ไธšๆœŸ๏ผ‰๏ผš
ๅ•ไฝ“ๅบ”็”จ๏ผŒไธ€ไธชwarๅŒ…
ไปฃ็ ้‡๏ผš5ไธ‡่กŒ
ๅผ€ๅ‘๏ผš3ไบบ
้ƒจ็ฝฒ๏ผš1ๅฐๆœๅŠกๅ™จ
โœ… ็ฎ€ๅ•ใ€ๅฟซ้€Ÿ

็ฌฌ3ๅนด๏ผˆๆˆ้•ฟๆœŸ๏ผ‰๏ผš
ไปฃ็ ้‡๏ผš50ไธ‡่กŒ
ๅผ€ๅ‘๏ผš30ไบบ
้ƒจ็ฝฒ๏ผš10ๅฐๆœๅŠกๅ™จ
โŒ ็—›็‚นๅ‡บ็Žฐ๏ผš
   โ”œโ”€โ”€ ไปฃ็ ่€ฆๅˆไธฅ้‡
   โ”œโ”€โ”€ ้ƒจ็ฝฒๆ…ข๏ผˆ30ๅˆ†้’Ÿ๏ผ‰
   โ”œโ”€โ”€ ๆ”นไธ€่กŒไปฃ็ ๏ผŒๅ…จ้‡ๅ‘ๅธƒ
   โ”œโ”€โ”€ ๅ›ข้˜Ÿๅไฝœๅ›ฐ้šพ
   โ””โ”€โ”€ ็ณป็ปŸ็ปๅธธๅฎ•ๆœบ

็ฌฌ5ๅนด๏ผˆ็ˆ†ๅ‘ๆœŸ๏ผ‰๏ผš
ไปฃ็ ้‡๏ผš200ไธ‡่กŒ
ๅผ€ๅ‘๏ผš100ไบบ
โŒ ๅ•ไฝ“ๅบ”็”จ็š„ๅ™ฉๆขฆ๏ผš
   โ”œโ”€โ”€ ๅฏๅŠจ้œ€่ฆ10ๅˆ†้’Ÿ
   โ”œโ”€โ”€ ๆ”นbugๅผ•ๅ‘ๆ–ฐbug
   โ”œโ”€โ”€ ๆ— ๆณ•ๆŠ€ๆœฏๅ‡็บง
   โ”œโ”€โ”€ ๆ•ฐๆฎๅบ“ๆˆไธบ็“ถ้ขˆ
   โ””โ”€โ”€ ไธๆ•ข้‡ๆž„

่งฃๅ†ณๆ–นๆกˆ๏ผšๅพฎๆœๅŠกๆ‹†ๅˆ†๏ผ

ๆ‹†ๅˆ†็š„ๆŒ‘ๆˆ˜

้”™่ฏฏ็š„ๆ‹†ๅˆ†๏ผš

ๆ‹†ๅˆ†ๅ‰๏ผšไธ€ไธชๅคงๆณฅ็ƒ
ๆ‹†ๅˆ†ๅŽ๏ผšNไธชๅฐๆณฅ็ƒ

้—ฎ้ข˜๏ผš
โ”œโ”€โ”€ ๆœๅŠก่พน็•Œๆททไนฑ
โ”œโ”€โ”€ ๆœๅŠก้—ด่ฐƒ็”จ้ข‘็น
โ”œโ”€โ”€ ๆ•ฐๆฎไธ€่‡ดๆ€ง้—ฎ้ข˜
โ”œโ”€โ”€ ๅˆ†ๅธƒๅผไบ‹ๅŠกๅคๆ‚
โ””โ”€โ”€ ่ฟ็ปดๆˆๆœฌๆšดๅขž

ๆญฃ็กฎ็š„ๆ‹†ๅˆ†๏ผš

ๆ‹†ๅˆ†ๅ‰๏ผšไธ€ไธชๅคงๆณฅ็ƒ
ๆ‹†ๅˆ†ๅŽ๏ผšNไธช็‹ฌ็ซ‹็š„ใ€ๅ†…่š็š„ๆœๅŠก

็‰น็‚น๏ผš
โ”œโ”€โ”€ ๆœๅŠก่พน็•Œๆธ…ๆ™ฐ
โ”œโ”€โ”€ ๆœๅŠก้—ดไฝŽ่€ฆๅˆ
โ”œโ”€โ”€ ็‹ฌ็ซ‹้ƒจ็ฝฒๅ‘ๅธƒ
โ”œโ”€โ”€ ๆ•ฐๆฎ่‡ชๆฒป
โ””โ”€โ”€ ่Œ่ดฃๅ•ไธ€

๐Ÿ“š ๆ ธๅฟƒๅŽŸๅˆ™

1๏ธโƒฃ ๅ•ไธ€่Œ่ดฃๅŽŸๅˆ™๏ผˆSRP๏ผ‰

ๆฏไธชๆœๅŠกๅชๅšไธ€ไปถไบ‹๏ผŒๅนถไธ”ๅšๅฅฝ

โŒ ้”™่ฏฏ็คบไพ‹๏ผš
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚   ็”จๆˆทๆœๅŠก              โ”‚
โ”‚   โ”œโ”€โ”€ ็”จๆˆท็ฎก็†         โ”‚
โ”‚   โ”œโ”€โ”€ ่ฎขๅ•็ฎก็†         โ”‚
โ”‚   โ”œโ”€โ”€ ๅ•†ๅ“็ฎก็†         โ”‚
โ”‚   โ””โ”€โ”€ ๆ”ฏไป˜็ฎก็†         โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
่Œ่ดฃๅคชๅคš๏ผŒ่€ฆๅˆไธฅ้‡๏ผ

โœ… ๆญฃ็กฎ็คบไพ‹๏ผš
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚ ็”จๆˆทๆœๅŠก โ”‚  โ”‚ ่ฎขๅ•ๆœๅŠก โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
     โ†‘             โ†‘
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚ ๅ•†ๅ“ๆœๅŠก โ”‚  โ”‚ ๆ”ฏไป˜ๆœๅŠก โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
ๆฏไธชๆœๅŠก่Œ่ดฃๅ•ไธ€๏ผ

2๏ธโƒฃ ้ซ˜ๅ†…่šใ€ไฝŽ่€ฆๅˆ

้ซ˜ๅ†…่š๏ผš
็›ธๅ…ณ็š„ๅŠŸ่ƒฝ่š้›†ๅœจไธ€ไธชๆœๅŠกๅ†…

ไพ‹ๅฆ‚๏ผš่ฎขๅ•ๆœๅŠก
โ”œโ”€โ”€ ๅˆ›ๅปบ่ฎขๅ•      โœ… ้ซ˜ๅบฆ็›ธๅ…ณ
โ”œโ”€โ”€ ๆŸฅ่ฏข่ฎขๅ•      โœ… ้ซ˜ๅบฆ็›ธๅ…ณ
โ”œโ”€โ”€ ๅ–ๆถˆ่ฎขๅ•      โœ… ้ซ˜ๅบฆ็›ธๅ…ณ
โ””โ”€โ”€ ่ฎขๅ•็ปŸ่ฎก      โœ… ้ซ˜ๅบฆ็›ธๅ…ณ

ไฝŽ่€ฆๅˆ๏ผš
ๆœๅŠกไน‹้—ดไพ่ต–ๅฐฝๅฏ่ƒฝๅฐ‘

โŒ ้”™่ฏฏ๏ผš
่ฎขๅ•ๆœๅŠก โ†’ ็”จๆˆทๆœๅŠก โ†’ ๅ•†ๅ“ๆœๅŠก โ†’ ๅบ“ๅญ˜ๆœๅŠก โ†’ ไปทๆ ผๆœๅŠก
้“พๅผ่ฐƒ็”จ๏ผŒ่€ฆๅˆไธฅ้‡

โœ… ๆญฃ็กฎ๏ผš
่ฎขๅ•ๆœๅŠก โ†’ ็”จๆˆทๆœๅŠก
        โ†’ ๅ•†ๅ“ๆœๅŠก
        โ†’ ๅบ“ๅญ˜ๆœๅŠก
ๅนถ่กŒ่ฐƒ็”จ๏ผŒ้™ไฝŽ่€ฆๅˆ

3๏ธโƒฃ ไธšๅŠก้ฉฑๅŠจ๏ผŒ่€Œ้žๆŠ€ๆœฏ้ฉฑๅŠจ

โŒ ๆŠ€ๆœฏ้ฉฑๅŠจ๏ผˆ้”™่ฏฏ๏ผ‰๏ผš
โ”œโ”€โ”€ ControllerๆœๅŠก
โ”œโ”€โ”€ ServiceๆœๅŠก
โ”œโ”€โ”€ DAOๆœๅŠก
โ””โ”€โ”€ ็ผ“ๅญ˜ๆœๅŠก
ๆŒ‰ๆŠ€ๆœฏๅฑ‚ๆ‹†ๅˆ†๏ผŒๆฏซๆ— ๆ„ไน‰๏ผ

โœ… ไธšๅŠก้ฉฑๅŠจ๏ผˆๆญฃ็กฎ๏ผ‰๏ผš
โ”œโ”€โ”€ ็”จๆˆทๆœๅŠก๏ผˆUser Domain๏ผ‰
โ”œโ”€โ”€ ่ฎขๅ•ๆœๅŠก๏ผˆOrder Domain๏ผ‰
โ”œโ”€โ”€ ๅ•†ๅ“ๆœๅŠก๏ผˆProduct Domain๏ผ‰
โ””โ”€โ”€ ๆ”ฏไป˜ๆœๅŠก๏ผˆPayment Domain๏ผ‰
ๆŒ‰ไธšๅŠก้ข†ๅŸŸๆ‹†ๅˆ†๏ผ

๐ŸŽฏ DDD้ข†ๅŸŸ้ฉฑๅŠจ่ฎพ่ฎก

DDDๆ ธๅฟƒๆฆ‚ๅฟต

DDD๏ผˆDomain-Driven Design๏ผ‰:
้ข†ๅŸŸ้ฉฑๅŠจ่ฎพ่ฎก๏ผŒๅพฎๆœๅŠกๆ‹†ๅˆ†็š„็†่ฎบๅŸบ็ก€

ๆ ธๅฟƒๆฆ‚ๅฟต๏ผš
1. ้ข†ๅŸŸ๏ผˆDomain๏ผ‰๏ผšไธšๅŠก่Œƒๅ›ด
2. ๅญๅŸŸ๏ผˆSubdomain๏ผ‰๏ผšไธšๅŠก็ป†ๅˆ†
3. ้™็•ŒไธŠไธ‹ๆ–‡๏ผˆBounded Context๏ผ‰๏ผšๅพฎๆœๅŠก่พน็•Œ
4. ่šๅˆ๏ผˆAggregate๏ผ‰๏ผšๆ•ฐๆฎๅ’Œ่กŒไธบ็š„้›†ๅˆ
5. ๅฎžไฝ“๏ผˆEntity๏ผ‰๏ผšๆœ‰ๅ”ฏไธ€ๆ ‡่ฏ†็š„ๅฏน่ฑก
6. ๅ€ผๅฏน่ฑก๏ผˆValue Object๏ผ‰๏ผšๆ— ๆ ‡่ฏ†็š„ๅฏน่ฑก

็”ตๅ•†็ณป็ปŸDDDๅˆ†ๆž

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚        ็”ตๅ•†็ณป็ปŸ๏ผˆDomain๏ผ‰           โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
                  โ”‚
        โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
        โ”‚                   โ”‚
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ–ผโ”€โ”€โ”€โ”€โ”€โ”      โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ–ผโ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚  ๆ ธๅฟƒๅŸŸ     โ”‚      โ”‚  ๆ”ฏๆ’‘ๅŸŸ     โ”‚
โ”‚ (Core)      โ”‚      โ”‚ (Supporting)โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜      โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
        โ”‚                   โ”‚
  โ”Œโ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”       โ”Œโ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”
  โ”‚           โ”‚       โ”‚           โ”‚
่ฎขๅ•ๅŸŸ    ๅ•†ๅ“ๅŸŸ    ็”จๆˆทๅŸŸ    ๆ”ฏไป˜ๅŸŸ
(Order)  (Product) (User)   (Payment)

่ฏ†ๅˆซ้™็•ŒไธŠไธ‹ๆ–‡

/**
 * ่ฎขๅ•้™็•ŒไธŠไธ‹ๆ–‡
 */
// Order่šๅˆๆ น
@Entity
public class Order {
    private Long id;              // ๅฎžไฝ“ๆ ‡่ฏ†
    private Long userId;          // ็”จๆˆทๅผ•็”จ๏ผˆๅชๅญ˜ID๏ผ‰
    private List<OrderItem> items;// ่ฎขๅ•้กน๏ผˆ่šๅˆๅ†…้ƒจ๏ผ‰
    private OrderStatus status;   // ่ฎขๅ•็Šถๆ€
    private BigDecimal totalAmount;
    
    // ้ข†ๅŸŸ่กŒไธบ
    public void create() { }      // ๅˆ›ๅปบ่ฎขๅ•
    public void pay() { }         // ๆ”ฏไป˜่ฎขๅ•
    public void cancel() { }      // ๅ–ๆถˆ่ฎขๅ•
    public void ship() { }        // ๅ‘่ดง
}

// OrderItemๅ€ผๅฏน่ฑก๏ผˆๅฑžไบŽOrder่šๅˆ๏ผ‰
@Embeddable
public class OrderItem {
    private Long productId;       // ๅ•†ๅ“ๅผ•็”จ
    private String productName;   // ๅ•†ๅ“ๅ็งฐๅฟซ็…ง
    private BigDecimal price;     // ไปทๆ ผๅฟซ็…ง
    private Integer quantity;     // ๆ•ฐ้‡
}

/**
 * ๅ•†ๅ“้™็•ŒไธŠไธ‹ๆ–‡
 */
@Entity
public class Product {
    private Long id;
    private String name;
    private String description;
    private BigDecimal price;
    private Integer stock;
    
    // ้ข†ๅŸŸ่กŒไธบ
    public void updateStock(int delta) { }
    public void updatePrice(BigDecimal newPrice) { }
}

/**
 * ็”จๆˆท้™็•ŒไธŠไธ‹ๆ–‡
 */
@Entity
public class User {
    private Long id;
    private String username;
    private String email;
    private String phone;
    
    // ้ข†ๅŸŸ่กŒไธบ
    public void register() { }
    public void updateProfile() { }
}

้™็•ŒไธŠไธ‹ๆ–‡ๆ˜ ๅฐ„

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚  ่ฎขๅ•ไธŠไธ‹ๆ–‡  โ”‚
โ”‚  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”  โ”‚      โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚  โ”‚  Order โ”‚  โ”‚โ”€โ”€โ”€โ”€โ”€โ–ถโ”‚  ็”จๆˆทไธŠไธ‹ๆ–‡  โ”‚
โ”‚  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜  โ”‚  U   โ”‚  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”  โ”‚
โ”‚      โ”‚       โ”‚      โ”‚  โ”‚  User  โ”‚  โ”‚
โ”‚      โ”‚       โ”‚      โ”‚  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜  โ”‚
โ”‚  โ”Œโ”€โ”€โ”€โ–ผโ”€โ”€โ”€โ”€โ”  โ”‚      โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
โ”‚  โ”‚OrderItemโ”‚ โ”‚
โ”‚  โ””โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”˜  โ”‚      โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚       โ”‚      โ”‚โ”€โ”€โ”€โ”€โ”€โ–ถโ”‚  ๅ•†ๅ“ไธŠไธ‹ๆ–‡  โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”˜  P   โ”‚  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”  โ”‚
        โ”‚             โ”‚  โ”‚Product โ”‚  โ”‚
        โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ–ถโ”‚  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜  โ”‚
                      โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

ๆ˜ ๅฐ„ๅ…ณ็ณป๏ผš
U: Upstream๏ผˆไธŠๆธธ๏ผ‰
P: Partner๏ผˆๅˆไฝœไผ™ไผด๏ผ‰

่ฎขๅ•ไธŠไธ‹ๆ–‡๏ผš
- ไพ่ต–็”จๆˆทไธŠไธ‹ๆ–‡๏ผˆ่Žทๅ–็”จๆˆทไฟกๆฏ๏ผ‰
- ไพ่ต–ๅ•†ๅ“ไธŠไธ‹ๆ–‡๏ผˆ่Žทๅ–ๅ•†ๅ“ไฟกๆฏ๏ผ‰
- ไฝ†ๅชๅญ˜ๅ‚จๅผ•็”จID๏ผŒไธๅญ˜ๅ‚จๅฎŒๆ•ดๆ•ฐๆฎ

๐Ÿ”ช ๆ‹†ๅˆ†ๆ–นๆณ•

ๆ–นๆณ•1๏ผšๆŒ‰ไธšๅŠก่ƒฝๅŠ›ๆ‹†ๅˆ† โญโญโญโญโญ

่ฏ†ๅˆซไธšๅŠก่ƒฝๅŠ›๏ผˆBusiness Capability๏ผ‰

็”ตๅ•†็ณป็ปŸ็š„ไธšๅŠก่ƒฝๅŠ›๏ผš
1. ็”จๆˆท็ฎก็†
   โ”œโ”€โ”€ ๆณจๅ†Œ็™ปๅฝ•
   โ”œโ”€โ”€ ไธชไบบไฟกๆฏ
   โ””โ”€โ”€ ๅœฐๅ€็ฎก็†

2. ๅ•†ๅ“็ฎก็†
   โ”œโ”€โ”€ ๅ•†ๅ“ๅฑ•็คบ
   โ”œโ”€โ”€ ๅˆ†็ฑป็ฎก็†
   โ””โ”€โ”€ ๅบ“ๅญ˜็ฎก็†

3. ่ฎขๅ•็ฎก็†
   โ”œโ”€โ”€ ไธ‹ๅ•
   โ”œโ”€โ”€ ๆ”ฏไป˜
   โ””โ”€โ”€ ๅ‘่ดง

4. ่ฅ้”€็ฎก็†
   โ”œโ”€โ”€ ไผ˜ๆƒ ๅˆธ
   โ”œโ”€โ”€ ไฟƒ้”€ๆดปๅŠจ
   โ””โ”€โ”€ ็งฏๅˆ†็ณป็ปŸ

ๅฏนๅบ”็š„ๅพฎๆœๅŠก๏ผš
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚ ็”จๆˆทๆœๅŠก โ”‚  โ”‚ ๅ•†ๅ“ๆœๅŠก โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚ ่ฎขๅ•ๆœๅŠก โ”‚  โ”‚ ่ฅ้”€ๆœๅŠก โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

ไปฃ็ ็คบไพ‹๏ผš

/**
 * ็”จๆˆทๆœๅŠก
 */
@RestController
@RequestMapping("/user")
public class UserController {
    
    @PostMapping("/register")
    public Result register(@RequestBody RegisterRequest request) {
        // ็”จๆˆทๆณจๅ†Œ
    }
    
    @PostMapping("/login")
    public Result login(@RequestBody LoginRequest request) {
        // ็”จๆˆท็™ปๅฝ•
    }
    
    @GetMapping("/{userId}")
    public Result<User> getUser(@PathVariable Long userId) {
        // ่Žทๅ–็”จๆˆทไฟกๆฏ
    }
}

/**
 * ๅ•†ๅ“ๆœๅŠก
 */
@RestController
@RequestMapping("/product")
public class ProductController {
    
    @GetMapping("/{productId}")
    public Result<Product> getProduct(@PathVariable Long productId) {
        // ่Žทๅ–ๅ•†ๅ“่ฏฆๆƒ…
    }
    
    @PostMapping("/deductStock")
    public Result deductStock(@RequestBody StockRequest request) {
        // ๆ‰ฃๅ‡ๅบ“ๅญ˜
    }
}

/**
 * ่ฎขๅ•ๆœๅŠก๏ผˆ็ป„ๅˆๅ…ถไป–ๆœๅŠก๏ผ‰
 */
@Service
public class OrderService {
    
    @Autowired
    private UserServiceClient userServiceClient;
    
    @Autowired
    private ProductServiceClient productServiceClient;
    
    /**
     * ๅˆ›ๅปบ่ฎขๅ•
     */
    @Transactional
    public Order createOrder(CreateOrderRequest request) {
        Long userId = request.getUserId();
        List<OrderItem> items = request.getItems();
        
        // 1. ่ฐƒ็”จ็”จๆˆทๆœๅŠก๏ผŒ้ชŒ่ฏ็”จๆˆท
        User user = userServiceClient.getUser(userId);
        if (user == null) {
            throw new BusinessException("็”จๆˆทไธๅญ˜ๅœจ");
        }
        
        // 2. ่ฐƒ็”จๅ•†ๅ“ๆœๅŠก๏ผŒ้ชŒ่ฏๅ•†ๅ“ๅ’Œๅบ“ๅญ˜
        for (OrderItem item : items) {
            Product product = productServiceClient.getProduct(item.getProductId());
            if (product == null) {
                throw new BusinessException("ๅ•†ๅ“ไธๅญ˜ๅœจ");
            }
            
            if (product.getStock() < item.getQuantity()) {
                throw new BusinessException("ๅบ“ๅญ˜ไธ่ถณ");
            }
        }
        
        // 3. ๅˆ›ๅปบ่ฎขๅ•
        Order order = new Order();
        order.setUserId(userId);
        order.setItems(items);
        order.setStatus(OrderStatus.CREATED);
        order.calculateTotalAmount();
        
        orderRepository.save(order);
        
        // 4. ๆ‰ฃๅ‡ๅบ“ๅญ˜๏ผˆๅ‘้€MQๆถˆๆฏ๏ผ‰
        for (OrderItem item : items) {
            stockMQProducer.send(new StockDeductMessage(
                item.getProductId(), 
                item.getQuantity()
            ));
        }
        
        return order;
    }
}

ๆ–นๆณ•2๏ผšๆŒ‰ๆ•ฐๆฎๆ‰€ๆœ‰ๆƒๆ‹†ๅˆ†

ๅŽŸๅˆ™๏ผšๆฏไธชๆœๅŠกๆ‹ฅๆœ‰่‡ชๅทฑ็š„ๆ•ฐๆฎๅบ“

โŒ ้”™่ฏฏ๏ผšๅ…ฑไบซๆ•ฐๆฎๅบ“
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚ ็”จๆˆทๆœๅŠก โ”‚  โ”‚ ่ฎขๅ•ๆœๅŠก โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”˜  โ””โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”˜
      โ”‚             โ”‚
      โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”˜
             โ”‚
        โ”Œโ”€โ”€โ”€โ”€โ–ผโ”€โ”€โ”€โ”€โ”
        โ”‚  MySQL  โ”‚
        โ”‚ (ๅ…ฑไบซ)  โ”‚
        โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
้—ฎ้ข˜๏ผš
- ๆ•ฐๆฎ่€ฆๅˆ
- ๆ— ๆณ•็‹ฌ็ซ‹ๆผ”ๅŒ–
- ๆ‰ฉๅฑ•ๅ›ฐ้šพ

โœ… ๆญฃ็กฎ๏ผšๆ•ฐๆฎๅบ“ๅˆ†็ฆป
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚ ็”จๆˆทๆœๅŠก โ”‚  โ”‚ ่ฎขๅ•ๆœๅŠก โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”˜  โ””โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”˜
      โ”‚             โ”‚
โ”Œโ”€โ”€โ”€โ”€โ”€โ–ผโ”€โ”€โ”€โ”€โ”  โ”Œโ”€โ”€โ”€โ”€โ”€โ–ผโ”€โ”€โ”€โ”€โ”
โ”‚ User DB  โ”‚  โ”‚ Order DB โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
ไผ˜็‚น๏ผš
- ๆ•ฐๆฎ่‡ชๆฒป
- ็‹ฌ็ซ‹ๆผ”ๅŒ–
- ๆ˜“ไบŽๆ‰ฉๅฑ•

ๆ•ฐๆฎๅ†—ไฝ™็ญ–็•ฅ๏ผš

/**
 * ่ฎขๅ•่กจ่ฎพ่ฎก๏ผˆๆ•ฐๆฎๅ†—ไฝ™๏ผ‰
 */
@Entity
@Table(name = "orders")
public class Order {
    @Id
    private Long id;
    
    // ็”จๆˆทไฟกๆฏ๏ผˆๅ†—ไฝ™๏ผ‰
    private Long userId;
    private String username;      // ๅ†—ไฝ™๏ผšไธ‹ๅ•ๆ—ถ็š„็”จๆˆทๅ
    private String userPhone;     // ๅ†—ไฝ™๏ผšไธ‹ๅ•ๆ—ถ็š„ๆ‰‹ๆœบๅท
    private String deliveryAddress; // ๅ†—ไฝ™๏ผšๆ”ถ่ดงๅœฐๅ€
    
    // ๅ•†ๅ“ไฟกๆฏ๏ผˆๅ†—ไฝ™๏ผ‰
    @OneToMany(cascade = CascadeType.ALL)
    private List<OrderItem> items;
    
    private OrderStatus status;
    private BigDecimal totalAmount;
    private Date createTime;
}

@Entity
@Table(name = "order_items")
public class OrderItem {
    @Id
    private Long id;
    
    private Long orderId;
    
    // ๅ•†ๅ“ไฟกๆฏ๏ผˆๅ†—ไฝ™๏ผŒๅฟซ็…ง๏ผ‰
    private Long productId;
    private String productName;    // ๅ†—ไฝ™๏ผšไธ‹ๅ•ๆ—ถ็š„ๅ•†ๅ“ๅ
    private BigDecimal price;      // ๅ†—ไฝ™๏ผšไธ‹ๅ•ๆ—ถ็š„ไปทๆ ผ
    private String productImage;   // ๅ†—ไฝ™๏ผšๅ•†ๅ“ๅ›พ็‰‡
    
    private Integer quantity;
    private BigDecimal subtotal;
}

/**
 * ไธบไป€ไนˆ่ฆๅ†—ไฝ™๏ผŸ
 * 
 * 1. ๅކๅฒๅฟซ็…ง๏ผš็”จๆˆท/ๅ•†ๅ“ไฟกๆฏไผšๅ˜ๅŒ–๏ผŒ่ฎขๅ•้œ€่ฆไฟ็•™ไธ‹ๅ•ๆ—ถ็š„็Šถๆ€
 * 2. ๅ‡ๅฐ‘ไพ่ต–๏ผš้ฟๅ…ๆŸฅ่ฏข่ฎขๅ•ๆ—ถ้ข‘็น่ฐƒ็”จๅ…ถไป–ๆœๅŠก
 * 3. ๆ€ง่ƒฝไผ˜ๅŒ–๏ผšๆœฌๅœฐๆŸฅ่ฏขๆฏ”่ฟœ็จ‹่ฐƒ็”จๅฟซๅพ—ๅคš
 */

ๆ–นๆณ•3๏ผšๆŒ‰ๅ›ข้˜Ÿ็ป“ๆž„ๆ‹†ๅˆ†๏ผˆๅบทๅจๅฎšๅพ‹๏ผ‰

ๅบทๅจๅฎšๅพ‹๏ผˆConway's Law๏ผ‰๏ผš
็ณป็ปŸ็š„ๆžถๆž„ๅๆ˜ ไบ†็ป„็ป‡็š„ๆฒŸ้€š็ป“ๆž„

ไพ‹ๅญ๏ผš
็”ตๅ•†ๅ…ฌๅธ็š„ๅ›ข้˜Ÿ็ป“ๆž„๏ผš
โ”œโ”€โ”€ ็”จๆˆทๅ›ข้˜Ÿ๏ผˆ10ไบบ๏ผ‰
โ”œโ”€โ”€ ๅ•†ๅ“ๅ›ข้˜Ÿ๏ผˆ15ไบบ๏ผ‰
โ”œโ”€โ”€ ่ฎขๅ•ๅ›ข้˜Ÿ๏ผˆ20ไบบ๏ผ‰
โ””โ”€โ”€ ๆ”ฏไป˜ๅ›ข้˜Ÿ๏ผˆ8ไบบ๏ผ‰

ๅฏนๅบ”็š„ๅพฎๆœๅŠกๆžถๆž„๏ผš
โ”œโ”€โ”€ ็”จๆˆทๆœๅŠก๏ผˆ็”จๆˆทๅ›ข้˜Ÿ่ดŸ่ดฃ๏ผ‰
โ”œโ”€โ”€ ๅ•†ๅ“ๆœๅŠก๏ผˆๅ•†ๅ“ๅ›ข้˜Ÿ่ดŸ่ดฃ๏ผ‰
โ”œโ”€โ”€ ่ฎขๅ•ๆœๅŠก๏ผˆ่ฎขๅ•ๅ›ข้˜Ÿ่ดŸ่ดฃ๏ผ‰
โ””โ”€โ”€ ๆ”ฏไป˜ๆœๅŠก๏ผˆๆ”ฏไป˜ๅ›ข้˜Ÿ่ดŸ่ดฃ๏ผ‰

ไผ˜็‚น๏ผš
- ๅ›ข้˜Ÿ่‡ชๆฒป
- ่Œ่ดฃๆธ…ๆ™ฐ
- ๆฒŸ้€š้กบ็•…
- ๅฟซ้€Ÿ่ฟญไปฃ

ๆ–นๆณ•4๏ผšๆŒ‰ๅ˜ๅŒ–้ข‘็އๆ‹†ๅˆ†

ๅŽŸๅˆ™๏ผšๅ˜ๅŒ–้ข‘็އไธๅŒ็š„ๅŠŸ่ƒฝๅˆ†็ฆป

้ซ˜้ข‘ๅ˜ๅŒ–๏ผš่ฅ้”€ๆดปๅŠจใ€ๆŽจ่็ฎ—ๆณ•
ไฝŽ้ข‘ๅ˜ๅŒ–๏ผš็”จๆˆทๅŸบ็ก€ไฟกๆฏใ€่ฎขๅ•ๆ ธๅฟƒๆต็จ‹

ๆ‹†ๅˆ†็ญ–็•ฅ๏ผš
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚ ๆ ธๅฟƒๆœๅŠก    โ”‚  ๅ˜ๅŒ–้ข‘็އไฝŽ๏ผŒ็จณๅฎš
โ”‚ (็จณๅฎš)      โ”‚  ไพ‹ๅฆ‚๏ผš็”จๆˆทใ€่ฎขๅ•
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚ ่ฅ้”€ๆœๅŠก    โ”‚  ๅ˜ๅŒ–้ข‘็އ้ซ˜๏ผŒ็ตๆดป
โ”‚ (็ตๆดป)      โ”‚  ไพ‹ๅฆ‚๏ผšไฟƒ้”€ใ€ๆŽจ่
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

ๅฅฝๅค„๏ผš
- ๆ ธๅฟƒๆœๅŠก็จณๅฎš๏ผŒไธๅ—ๅฝฑๅ“
- ่ฅ้”€ๆœๅŠกๅฏไปฅ้ข‘็นๅ‘ๅธƒ
- ้™ไฝŽ้ฃŽ้™ฉ

๐ŸŽจ ๅฎžๆˆ˜ๆกˆไพ‹๏ผš็”ตๅ•†็ณป็ปŸๆ‹†ๅˆ†

ๆ‹†ๅˆ†ๅ‰๏ผˆๅ•ไฝ“ๅบ”็”จ๏ผ‰

็”ตๅ•†ๅ•ไฝ“ๅบ”็”จ๏ผš
โ”œโ”€โ”€ controller
โ”‚   โ”œโ”€โ”€ UserController
โ”‚   โ”œโ”€โ”€ ProductController
โ”‚   โ”œโ”€โ”€ OrderController
โ”‚   โ””โ”€โ”€ PaymentController
โ”œโ”€โ”€ service
โ”‚   โ”œโ”€โ”€ UserService
โ”‚   โ”œโ”€โ”€ ProductService
โ”‚   โ”œโ”€โ”€ OrderService
โ”‚   โ””โ”€โ”€ PaymentService
โ”œโ”€โ”€ dao
โ”‚   โ”œโ”€โ”€ UserMapper
โ”‚   โ”œโ”€โ”€ ProductMapper
โ”‚   โ”œโ”€โ”€ OrderMapper
โ”‚   โ””โ”€โ”€ PaymentMapper
โ””โ”€โ”€ model
    โ”œโ”€โ”€ User
    โ”œโ”€โ”€ Product
    โ”œโ”€โ”€ Order
    โ””โ”€โ”€ Payment

้—ฎ้ข˜๏ผš
- ไปฃ็ ่€ฆๅˆไธฅ้‡
- ๅ…จ้‡้ƒจ็ฝฒ
- ๆ•ฐๆฎๅบ“ๅ•็‚น
- ๆ— ๆณ•็‹ฌ็ซ‹ๆ‰ฉๅฑ•

ๆ‹†ๅˆ†ๅŽ๏ผˆๅพฎๆœๅŠกๆžถๆž„๏ผ‰

ๅพฎๆœๅŠกๆžถๆž„๏ผš

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚           API็ฝ‘ๅ…ณ                  โ”‚
โ”‚     (่ทฏ็”ฑใ€้™ๆตใ€้‰ดๆƒ)             โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
         โ”‚
    โ”Œโ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
    โ”‚         โ”‚        โ”‚        โ”‚
โ”Œโ”€โ”€โ”€โ–ผโ”€โ”€โ”€โ”€โ” โ”Œโ”€โ–ผโ”€โ”€โ”€โ”€โ” โ”Œโ”€โ–ผโ”€โ”€โ”€โ”€โ” โ”Œโ”€โ–ผโ”€โ”€โ”€โ”€โ”
โ”‚็”จๆˆทๆœๅŠกโ”‚ โ”‚ๅ•†ๅ“  โ”‚ โ”‚่ฎขๅ•  โ”‚ โ”‚ๆ”ฏไป˜  โ”‚
โ”‚        โ”‚ โ”‚ๆœๅŠก  โ”‚ โ”‚ๆœๅŠก  โ”‚ โ”‚ๆœๅŠก  โ”‚
โ””โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”˜ โ””โ”€โ”ฌโ”€โ”€โ”€โ”€โ”˜ โ””โ”€โ”ฌโ”€โ”€โ”€โ”€โ”˜ โ””โ”€โ”ฌโ”€โ”€โ”€โ”€โ”˜
    โ”‚        โ”‚        โ”‚        โ”‚
โ”Œโ”€โ”€โ”€โ–ผโ”€โ”€โ”€โ”€โ” โ”Œโ”€โ–ผโ”€โ”€โ”€โ”€โ” โ”Œโ”€โ–ผโ”€โ”€โ”€โ”€โ” โ”Œโ”€โ–ผโ”€โ”€โ”€โ”€โ”
โ”‚User DB โ”‚ โ”‚Productโ”‚ โ”‚Order โ”‚ โ”‚Paymentโ”‚
โ”‚        โ”‚ โ”‚  DB  โ”‚ โ”‚  DB  โ”‚ โ”‚  DB  โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

    โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
    โ”‚   ๆถˆๆฏ้˜Ÿๅˆ—MQ   โ”‚
    โ”‚  (ๅผ‚ๆญฅ้€šไฟก)    โ”‚
    โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

    โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
    โ”‚   ้…็ฝฎไธญๅฟƒ     โ”‚
    โ”‚  (็ปŸไธ€้…็ฝฎ)    โ”‚
    โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

ๆœๅŠกๆธ…ๅ•๏ผš

# ็”จๆˆทๆœๅŠก
user-service:
  port: 8001
  database: user_db
  responsibilities:
    - ็”จๆˆทๆณจๅ†Œ็™ปๅฝ•
    - ไธชไบบไฟกๆฏ็ฎก็†
    - ๅœฐๅ€็ฎก็†
    - ๆƒ้™็ฎก็†

# ๅ•†ๅ“ๆœๅŠก
product-service:
  port: 8002
  database: product_db
  responsibilities:
    - ๅ•†ๅ“ๅฑ•็คบ
    - ๅˆ†็ฑป็ฎก็†
    - ๅบ“ๅญ˜็ฎก็†
    - ๅ•†ๅ“ๆœ็ดข

# ่ฎขๅ•ๆœๅŠก
order-service:
  port: 8003
  database: order_db
  responsibilities:
    - ่ฎขๅ•ๅˆ›ๅปบ
    - ่ฎขๅ•ๆŸฅ่ฏข
    - ่ฎขๅ•ๅ–ๆถˆ
    - ่ฎขๅ•็ปŸ่ฎก

# ๆ”ฏไป˜ๆœๅŠก
payment-service:
  port: 8004
  database: payment_db
  responsibilities:
    - ๆ”ฏไป˜ๅค„็†
    - ้€€ๆฌพๅค„็†
    - ๆ”ฏไป˜ๅ›ž่ฐƒ
    - ่ดฆๅ•ๆŸฅ่ฏข

โš ๏ธ ๅธธ่ง้™ท้˜ฑ

้™ท้˜ฑ1๏ผš่ฟ‡ๅบฆๆ‹†ๅˆ†

โŒ ้”™่ฏฏ๏ผšๆ‹†ๅˆ†ๆˆๅ‡ ๅไธชๅพฎๆœๅŠก

็”จๆˆทๆœๅŠก็ป†ๅˆ†๏ผš
โ”œโ”€โ”€ ็”จๆˆทๆณจๅ†ŒๆœๅŠก
โ”œโ”€โ”€ ็”จๆˆท็™ปๅฝ•ๆœๅŠก
โ”œโ”€โ”€ ็”จๆˆทไฟกๆฏๆœๅŠก
โ”œโ”€โ”€ ็”จๆˆทๅœฐๅ€ๆœๅŠก
โ”œโ”€โ”€ ็”จๆˆทๆƒ้™ๆœๅŠก
โ””โ”€โ”€ ...

้—ฎ้ข˜๏ผš
- ่ฟ็ปดๆˆๆœฌๆšดๅขž
- ๆœๅŠก่ฐƒ็”จ้“พ่ฟ‡้•ฟ
- ๅˆ†ๅธƒๅผไบ‹ๅŠกๅคๆ‚
- ๆ€ง่ƒฝไธ‹้™

โœ… ๆญฃ็กฎ๏ผš้€‚ๅบฆๆ‹†ๅˆ†

็”จๆˆทๆœๅŠก๏ผˆๆ•ดๅˆ๏ผ‰๏ผš
โ”œโ”€โ”€ ๆณจๅ†Œ็™ปๅฝ•
โ”œโ”€โ”€ ไฟกๆฏ็ฎก็†
โ”œโ”€โ”€ ๅœฐๅ€็ฎก็†
โ””โ”€โ”€ ๆƒ้™็ฎก็†

้™ท้˜ฑ2๏ผšๅฟฝ็•ฅๆ•ฐๆฎไธ€่‡ดๆ€ง

/**
 * โŒ ้”™่ฏฏ๏ผšๅฟฝ็•ฅๅˆ†ๅธƒๅผไบ‹ๅŠก
 */
public Order createOrder(CreateOrderRequest request) {
    // 1. ๅˆ›ๅปบ่ฎขๅ•
    Order order = orderRepository.save(new Order(...));
    
    // 2. ๆ‰ฃๅ‡ๅบ“ๅญ˜๏ผˆ่ฟœ็จ‹่ฐƒ็”จ๏ผ‰
    productServiceClient.deductStock(productId, quantity);
    // ๅฆ‚ๆžœ่ฟ™้‡Œๅคฑ่ดฅ๏ผŒ่ฎขๅ•ๅทฒๅˆ›ๅปบ๏ผŒไฝ†ๅบ“ๅญ˜ๆœชๆ‰ฃๅ‡ โŒ
    
    // 3. ๆ‰ฃๅ‡ไฝ™้ข๏ผˆ่ฟœ็จ‹่ฐƒ็”จ๏ผ‰
    accountServiceClient.deductBalance(userId, amount);
    // ๅฆ‚ๆžœ่ฟ™้‡Œๅคฑ่ดฅ๏ผŒ่ฎขๅ•ๅทฒๅˆ›ๅปบ๏ผŒๅบ“ๅญ˜ๅทฒๆ‰ฃๅ‡๏ผŒไฝ†ไฝ™้ขๆœชๆ‰ฃ โŒ
    
    return order;
}

/**
 * โœ… ๆญฃ็กฎ๏ผšไฝฟ็”จSagaๆจกๅผ
 */
public Order createOrder(CreateOrderRequest request) {
    // ไฝฟ็”จSaga็ผ–ๆŽ’
    SagaOrchestrator saga = new SagaOrchestrator();
    
    // Step 1: ๅˆ›ๅปบ่ฎขๅ•
    saga.addStep(
        () -> orderRepository.save(new Order(...)),
        order -> orderRepository.delete(order)  // ่กฅๅฟ
    );
    
    // Step 2: ๆ‰ฃๅ‡ๅบ“ๅญ˜
    saga.addStep(
        () -> productServiceClient.deductStock(productId, quantity),
        () -> productServiceClient.addStock(productId, quantity)  // ่กฅๅฟ
    );
    
    // Step 3: ๆ‰ฃๅ‡ไฝ™้ข
    saga.addStep(
        () -> accountServiceClient.deductBalance(userId, amount),
        () -> accountServiceClient.addBalance(userId, amount)  // ่กฅๅฟ
    );
    
    // ๆ‰ง่กŒSaga
    return saga.execute();
}

้™ท้˜ฑ3๏ผšๅพช็Žฏไพ่ต–

โŒ ้”™่ฏฏ๏ผšๆœๅŠก้—ดๅพช็Žฏไพ่ต–

่ฎขๅ•ๆœๅŠก โ†’ ็”จๆˆทๆœๅŠก
    โ†‘           โ†“
    โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
ๅพช็Žฏไพ่ต–๏ผ

โœ… ๆญฃ็กฎ๏ผšๅ•ๅ‘ไพ่ต–

่ฎขๅ•ๆœๅŠก โ†’ ็”จๆˆทๆœๅŠก
่ฎขๅ•ๆœๅŠก โ†’ ๅ•†ๅ“ๆœๅŠก
่ฎขๅ•ๆœๅŠก โ†’ ๆ”ฏไป˜ๆœๅŠก

็”จๆˆทๆœๅŠกใ€ๅ•†ๅ“ๆœๅŠกใ€ๆ”ฏไป˜ๆœๅŠกไน‹้—ดไธไบ’็›ธไพ่ต–

๐ŸŽฏ ๆ‹†ๅˆ†ๆฃ€ๆŸฅๆธ…ๅ•

ๆ‹†ๅˆ†ๅ‰่ฏ„ไผฐ

โ–ก ๅ•ไฝ“ๅบ”็”จๆ˜ฏๅฆ็œŸ็š„้‡ๅˆฐ็“ถ้ขˆ๏ผŸ
โ–ก ๅ›ข้˜Ÿๆ˜ฏๅฆๆœ‰ๅพฎๆœๅŠก็ป้ชŒ๏ผŸ
โ–ก ๅŸบ็ก€่ฎพๆ–ฝๆ˜ฏๅฆๅฎŒๅ–„๏ผˆDockerใ€K8s๏ผ‰๏ผŸ
โ–ก ็›‘ๆŽงๅ‘Š่ญฆๆ˜ฏๅฆๅˆฐไฝ๏ผŸ
โ–ก ๆ˜ฏๅฆๆœ‰DevOps่ƒฝๅŠ›๏ผŸ

ๅฆ‚ๆžœ้ƒฝๆ˜ฏโœ…๏ผŒๅฏไปฅๅผ€ๅง‹ๆ‹†ๅˆ†
ๅฆ‚ๆžœๆœ‰โŒ๏ผŒๅ…ˆๅฎŒๅ–„ๅŸบ็ก€่ฎพๆ–ฝ

ๆ‹†ๅˆ†ๅŽ้ชŒ่ฏ

โ–ก ๆœๅŠก่พน็•Œๆ˜ฏๅฆๆธ…ๆ™ฐ๏ผŸ
โ–ก ๆœๅŠก้—ด่ฐƒ็”จๆ˜ฏๅฆ้ข‘็น๏ผŸ
โ–ก ๆ˜ฏๅฆๅญ˜ๅœจๅพช็Žฏไพ่ต–๏ผŸ
โ–ก ๆ•ฐๆฎไธ€่‡ดๆ€งๅฆ‚ไฝ•ไฟ่ฏ๏ผŸ
โ–ก ๆ€ง่ƒฝๆ˜ฏๅฆๆปก่ถณ่ฆๆฑ‚๏ผŸ
โ–ก ่ฟ็ปดๆˆๆœฌๆ˜ฏๅฆๅฏๆŽง๏ผŸ

๐ŸŽ‰ ๆ€ป็ป“

ๆ‹†ๅˆ†ๅŽŸๅˆ™ๆ€ป็ป“

1. ๅ•ไธ€่Œ่ดฃ
   ๆฏไธชๆœๅŠกๅชๅšไธ€ไปถไบ‹

2. ้ซ˜ๅ†…่šไฝŽ่€ฆๅˆ
   ็›ธๅ…ณๅŠŸ่ƒฝ่š้›†๏ผŒๆœๅŠก้—ดๅฐ‘ไพ่ต–

3. ไธšๅŠก้ฉฑๅŠจ
   ๆŒ‰ไธšๅŠก่ƒฝๅŠ›ๆ‹†ๅˆ†๏ผŒ้žๆŠ€ๆœฏๅฑ‚

4. ๆ•ฐๆฎ่‡ชๆฒป
   ๆฏไธชๆœๅŠกๆ‹ฅๆœ‰่‡ชๅทฑ็š„ๆ•ฐๆฎๅบ“

5. ็‹ฌ็ซ‹้ƒจ็ฝฒ
   ๆœๅŠกๅฏไปฅ็‹ฌ็ซ‹ๅ‘ๅธƒไธŠ็บฟ

6. ๅ›ข้˜Ÿ่‡ชๆฒป
   ไธ€ไธชๅ›ข้˜Ÿ่ดŸ่ดฃไธ€ไธชๆˆ–ๅคšไธชๆœๅŠก

7. ๆธ่ฟ›ๅผๆ‹†ๅˆ†
   ๅ…ˆๆ‹†ๆ ธๅฟƒ๏ผŒๅ†ๆ‹†่พน็ผ˜

8. ้ฟๅ…่ฟ‡ๅบฆๆ‹†ๅˆ†
   ้€‚ๅบฆๅณๅฏ๏ผŒๅˆซ่ตฐๆž็ซฏ

ๆ‹†ๅˆ†ๆ–นๆณ•

ๆ–นๆณ•้€‚็”จๅœบๆ™ฏๆŽจ่ๅบฆ
ๆŒ‰ไธšๅŠก่ƒฝๅŠ›้€š็”จโญโญโญโญโญ
ๆŒ‰ๆ•ฐๆฎๆ‰€ๆœ‰ๆƒๆ•ฐๆฎๅบ“ๅˆ†็ฆปโญโญโญโญโญ
ๆŒ‰ๅ›ข้˜Ÿ็ป“ๆž„ๅคงๅ›ข้˜Ÿโญโญโญโญ
ๆŒ‰ๅ˜ๅŒ–้ข‘็އ็จณๅฎšๆ€ง่ฆๆฑ‚้ซ˜โญโญโญโญ

่ฎฐๅฟ†ๅฃ่ฏ€

ๅพฎๆœๅŠกๆ‹†ๅˆ†ๆœ‰ๅŽŸๅˆ™๏ผŒ
ๅ•ไธ€่Œ่ดฃๆ˜ฏๆ ธๅฟƒใ€‚
้ซ˜ๅ†…่šไฝŽ่€ฆๅˆ๏ผŒ
ไธšๅŠก้ฉฑๅŠจไธๆŠ€ๆœฏใ€‚

DDD้ข†ๅŸŸ้ฉฑๅŠจๅฅฝ๏ผŒ
้™็•ŒไธŠไธ‹ๆ–‡ๆ‰พ่พน็•Œใ€‚
่šๅˆๅฎžไฝ“ๅ’Œๅ€ผๅฏน่ฑก๏ผŒ
ๆ•ฐๆฎ่กŒไธบ่ฆๅ†…่šใ€‚

ๆ‹†ๅˆ†ๆ–นๆณ•ๆœ‰ๅคš็ง๏ผŒ
ไธšๅŠก่ƒฝๅŠ›ๆœ€ๅธธ็”จใ€‚
ๆ•ฐๆฎๆ‰€ๆœ‰ๆƒ่‡ชๆฒป๏ผŒ
ๅ›ข้˜Ÿ็ป“ๆž„่ฆๅŒน้…ใ€‚

ๅบทๅจๅฎšๅพ‹่ฆ่ฎฐ็‰ข๏ผŒ
ๆžถๆž„ๅๆ˜ ็ป„็ป‡็ป“ๆž„ใ€‚
้ฟๅ…่ฟ‡ๅบฆ็ป†ๆ‹†ๅˆ†๏ผŒ
้€‚ๅบฆๆ‰ๆ˜ฏๆœ€ๅ…ณ้”ฎ๏ผ

ๆ‹†ๅˆ†ไธๆ˜ฏ้“ถๅผน่ฏ๏ผŒ
ๅŸบ็ก€่ฎพๆ–ฝ่ฆๅฎŒๅ–„ใ€‚
็›‘ๆŽงๅ‘Š่ญฆๅ’Œ่ฟ็ปด๏ผŒ
ไธ€ไธช้ƒฝไธ่ƒฝๅฐ‘๏ผ

ๆ„ฟไฝ ็š„ๅพฎๆœๅŠก่พน็•Œๆธ…ๆ™ฐ๏ผŒๆžถๆž„ไผ˜้›…ๅฆ‚่ฏ—๏ผ ๐Ÿ”ชโœจ