今天我們通過一個“超市收銀”業務來作為我們的示例(雖然這個示例看上去不太正常,但是它確表述我們所需要的)。我們將從業務分析到業務建模然後最後的編碼來用“面向領域對象”的方式來做我們的項目。

好,我們開始吧!

 

一、業務分析


大家都去超市買過東西,對超市收銀業務都比較熟悉。什麼?你不熟?好吧,那我們找個收銀員給大家講解下(領域專家)。

 

收銀員小慧:哦,是這樣呢。顧客排隊銀帳我就收銀呢,我要使用收銀機呢。收銀機就能計算出要收的錢呢,我就掃一下呢,就OK了呢。然後就收銀了呢。

 

聽了小慧的講解,我們心中有了業務的概念了。我們這裏採用《業務關鍵字分析法》來找出此業務流程裏面的一些關係字:


商品

顧客

收銀員

收銀機

*收銀

*選商品

*收銀員使用收銀機

*收銀機掃商品計算金額

 

好了,列出這些“業務關鍵字”了,我們就可以建我們的對象模型了。

 

二、系統建模


上面我們分析出了一些“業務關鍵字”接下來我們分析這些業務關鍵字並深入他們的業務。

 

商品對象(Goods)。

屬性:商品名稱(GoodsName)、商品價格(GoodsPrice)。

行為:在這裏商品對象是沒有行為的,我們也可以叫它“值對象”。

 

顧客對象(Customer)。

屬性:顧客姓名(CustomerName)、顧客選購的商品(Goodss)

行為:選購想買的商品(LikeBuy)、聽收銀員説要收多少RMB(ListenAmount)

 

收銀員對象(Cashier)。

屬性:收銀員姓名(CashierName)

行為:收銀(CashierRegister)

 

收銀機對象(CashierRegister)。

屬性:收銀機編號(CashRegisterNo)

字段:總金額(_totalAmount)

行為:收銀(CashRegisters)、顯示收銀總額(ShowAmount)

 

java對接收錢吧實現支付_java對接收錢吧實現支付

 

有木有!有木有?有木有很直觀,這也就是面向對象分析的好處,因為對象就是對現實的抽象,我們現實中的事務可以很方便的用對象抽象出來。我們很容易發現,這和用表來描述這些業務模型顯然要不方便的多。表還只能描述屬性,造成了屬性與行為的分離。

 

三、代碼示例


商品對象
 
/// <summary>
    /// 商品
    /// </summary>
    public class Goods
    {
        /// <summary>
        /// 對象標識
        /// </summary>
        public Guid OKey { get; set; }
        /// <summary>
        /// 商品名稱
        /// </summary>
        public string GoodsName { get; set; }
        /// <summary>
        /// 商品價格
        /// </summary>
        public decimal GoodsPrice { get; set; }
    } 
顧客對象
 
/// <summary>
    /// 顧客
    /// </summary>
    public class Customer
    {
        /// <summary>
        /// 對象標識
        /// </summary>
        public Guid OKey { get; set; }
        /// <summary>
        /// 顧客姓名
        /// </summary>
        public string CustomerName { get; set; }

        private List<Goods> _goodss = new List<Goods>();
        /// <summary>
        /// 顧客購買的商品
        /// </summary>
        public List<Goods> Goodss
        {
            get { return _goodss; }
            set { _goodss = value; }
        }

        /// <summary>
        /// 顧客選購商品
        /// </summary>
        /// <param name="goods">商品</param>
        public void LikeBuy(Goods goods)
        {
            this._goodss.Add(goods);
        }

        /// <summary>
        /// 聽收銀員應收多少錢
        /// </summary>
        /// <param name="amount"></param>
        public void ListenAmount(decimal amount)
        {
            Console.WriteLine("我是[{0}],我買了{1}件商品。我共花了{2}元RMB。", this.CustomerName, this.Goodss.Count, amount.ToString("f2"));
        } 
收銀員對象
 
/// <summary>
    /// 收銀員
    /// </summary>
    public class Cashier
    {
        /// <summary>
        /// 對象標識
        /// </summary>
        public Guid OKey { get; set; }
        /// <summary>
        /// 收銀員姓名
        /// </summary>
        public string CashierName { get; set; }

        /// <summary>
        /// 收銀
        /// </summary>
        /// <param name="customer">顧客</param>
        public void CashRegister(Customer customer)
        {
            //打開使用收銀機
            CashRegister cashRegister = new CashRegister();

            //對顧客的商品進行收銀機掃碼,收銀
            foreach (var goods in customer.Goodss)
            {
                //使用收銀機掃商品進行收銀
                cashRegister.CashRegisters(goods);
            }

            //通知顧客一共收多少錢
            customer.ListenAmount(cashRegister.ShowAmount());
        }
    } 
收銀機對象
 
/// <summary>
        /// 對象標識
        /// </summary>
        public Guid OKey { get; set; }
        /// <summary>
        /// 收銀機編號
        /// </summary>
        public string CashRegisterNo { get; set; }

        /// <summary>
        /// 總價格
        /// </summary>
        private decimal _totalAmount { get; set; }

        public CashRegister()
        {
            //收銀總額置0
            this._totalAmount = 0;
        }

        /// <summary>
        /// 收銀
        /// </summary>
        /// <param name="goods">商品</param>
        public void CashRegisters(Goods goods)
        {
            this._totalAmount += goods.GoodsPrice;
        }

        /// <summary>
        /// 顯示收銀總額
        /// </summary>
        /// <returns></returns>
        public decimal ShowAmount()
        {
            return this._totalAmount;
        } 
模擬業務流程
 
//我們創建幾樣商品
            Goods RedWine = new Goods() { GoodsName = "紅酒", GoodsPrice = 1800,OKey=Guid.NewGuid() };
            Goods Condoms = new Goods() { GoodsName = "安全套", GoodsPrice = 35,OKey=Guid.NewGuid() };

            //我們創建幾位顧客
            Customer Chunge = new Customer() { CustomerName = "春哥", OKey = Guid.NewGuid() };
            Customer Beianqi = new Customer() { CustomerName = "貝安琪", OKey = Guid.NewGuid() };

            //當然,我們需要收銀員啊
            Cashier CashierMM = new Cashier() { CashierName = "收銀員MM", OKey = Guid.NewGuid() };

            //顧客逛了一圈,選了自己想要的商品
            Chunge.LikeBuy(RedWine);
            Beianqi.LikeBuy(RedWine);
            Beianqi.LikeBuy(Condoms);

            //顧客開始排隊結帳了
            Queue<Customer> customerQueue = new Queue<Customer>();
            customerQueue.Enqueue(Chunge);
            customerQueue.Enqueue(Beianqi);

            //隊伍過來,按先後順序挨個收銀嘍
            foreach (var customer in customerQueue)
            {
                //收銀
                CashierMM.CashRegister(customer);
            }

 

顯示結果

 

java對接收錢吧實現支付_業務流程_02

 

上面的例子雖然不是很恰當,但是它也很好的像我們表達出了領域驅動分析問題、面向對象驅動開發的好處了。


最後大家回想一下,用數據庫表驅動的方式。分析這個業務會是什麼樣子的。。。。