You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何设计合理的面向对象结构:库存系统事务类设计疑问

面向对象库存管理系统类设计疑问

我刚注册了大学的第一门面向对象(OO)课程,目前有些迷茫。我需要用UML设计一个库存管理系统,但在某些方法的归属上遇到了瓶颈。

我已定义Transaction类,按我的理解,类应封装操作特定数据集的所有方法和属性。因此,如果InventoryManager类需要获取所有交易记录,我认为Transaction类应包含类似GetAllTransactions的方法并返回List<Transaction>。但Transaction类如何返回自身实例的列表呢?以下是我设计的TransactionManager和Transaction类的UML文本表示及代码构想(方法命名仅为传达问题意图)。

能否有人从概念层面展示正确的设计方式?


现有UML类设计

TransactionManager类

TransactionManager
private List transactions
public List GetAllTransactionsFromTransactionClass();

Transaction类

Transaction
private string transactionId
Date date
private double price
public void Transaction() {}
public List GetAllTransactions();

另外,若我在GetAllTransactions方法中创建一个交易记录列表的局部变量(用于返回),每次创建新Transaction实例时会不会引发循环引用之类的问题?

我的代码构想如下:

public TransactionManager
{
    public GetAllTransactionsFromTransactionClass
    {
        List<Transaction> transactions = Transaction.GetAllTransactions();
    }
}

public Transaction 
{
    public Transaction()

    public List<Transaction> GetAllTransactions()
    {
        List<Transaction> transactions = new List<Transaction>();
        transactions.Add(new Transaction());

        return transactions;
    }
}

正确的设计思路(概念层面)

1. 职责分离:区分实体类与管理器类

Transaction是实体类,它只应该封装单个交易的属性和行为(比如计算交易金额、验证交易ID格式等),不负责管理所有交易的集合。

TransactionManager(或InventoryManager)是管理器类,它的职责才是维护交易列表、提供查询/新增/删除交易的方法。把GetAllTransactions放在管理器类里才符合单一职责原则。

2. 修正后的UML设计

TransactionManager类

TransactionManager
private List _transactions
+ void AddTransaction(Transaction transaction)
+ List GetAllTransactions()
+ Transaction GetTransactionById(string id)

Transaction类

Transaction
- string _transactionId
- Date _date
- double _price
+ Transaction(string transactionId, Date date, double price)
+ string TransactionId { get; }
+ Date Date { get; }
+ double Price { get; }
+ bool IsValid() // 示例:验证当前交易的合法性

3. 修正后的代码示例

public class TransactionManager
{
    // 维护交易集合的私有字段
    private List<Transaction> _transactions = new List<Transaction>();

    // 添加交易的方法
    public void AddTransaction(Transaction transaction)
    {
        if(transaction.IsValid())
        {
            _transactions.Add(transaction);
        }
    }

    // 获取所有交易的方法
    public List<Transaction> GetAllTransactions()
    {
        // 返回副本避免外部直接修改内部集合
        return new List<Transaction>(_transactions);
    }
}

public class Transaction
{
    // 私有字段封装属性
    private readonly string _transactionId;
    private readonly DateTime _date;
    private readonly double _price;

    // 构造函数初始化属性
    public Transaction(string transactionId, DateTime date, double price)
    {
        _transactionId = transactionId;
        _date = date;
        _price = price;
    }

    // 只读属性暴露数据
    public string TransactionId => _transactionId;
    public DateTime Date => _date;
    public double Price => _price;

    // 实体自身的行为:验证当前交易是否合法
    public bool IsValid()
    {
        return !string.IsNullOrEmpty(_transactionId) && _price >= 0;
    }
}

4. 关于循环引用的疑问

你当前的代码里,Transaction.GetAllTransactions()每次创建新的Transaction实例并加入列表,这不会直接导致循环引用,但会出现逻辑错误:每次调用这个方法都会生成一个只包含新交易的列表,而不是实际存储的所有交易。

正确的设计中,交易集合由管理器维护,实体类不需要自己生成实例列表,自然不会有这类问题。


内容的提问来源于stack exchange,提问作者Scott

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.23 13:54:22