精品欧美一区二区三区在线观看 _久久久久国色av免费观看性色_国产精品久久在线观看_亚洲第一综合网站_91精品又粗又猛又爽_小泽玛利亚一区二区免费_91亚洲精品国偷拍自产在线观看 _久久精品视频在线播放_美女精品久久久_欧美日韩国产成人在线

ZOMBIES:在軟件開發中定義邊界和接口(三)

開發
喪尸是沒有邊界感的,需要為你的軟件設定限制和期望。

喪尸沒有邊界感。它們踩倒柵欄,推倒圍墻,進入不屬于它們的地盤。在前面的文章中,我已經解釋了為什么把所有編程問題當作一群喪尸一次性處理是錯誤的。

ZOMBIES 代表首字母縮寫:

  • Z – 最簡場景(Zero)
  • O – 單個元素場景(One)
  • M – 多個元素場景(Many or more complex)
  • B – 邊界行為(Boundary behaviors)
  • I – 接口定義(Interface definition)
  • E – 處理特殊行為(Exercise exceptional behavior)
  • S – 簡單場景用簡單的解決方案(Simple scenarios, simple solutions)

在本系列的前面兩篇文章中,我演示了 ZOMBIES 方法的前三部分:最簡場景、單元素場景和多元素場景。第一篇文章 實現了最簡場景,它提供了代碼中的最簡可行路徑。第二篇文章中針對單元素場景和多元素場景 運行測試。在這篇文章中,我將帶你了解邊界和接口。

回到單元素場景

要想處理邊界,你需要繞回來(迭代)。

首先思考下面的問題:電子商務的邊界是什么?我需要限制購物框的大小嗎?(事實上,我不認為這有任何意義。)

目前唯一合理的邊界條件是確保購物框里的商品數量不能為負數。將這個限制表示成可運行的期望:

[Fact]
public void Add1ItemRemoveItemRemoveAgainHas0Items() {
        var expectedNoOfItems = 0;
        var actualNoOfItems = -1;
        Assert.Equal(expectedNoOfItems, actualNoOfItems);
}

這就是說,如果你向購物框里添加一件商品,然后將這個商品移除兩次,shoppingAPI 的實例應該告訴你購物框里有零個商品。

當然這個可運行期望(微測試)不出意料地會失敗。想要這個微測試能夠通過,最小改動是什么呢?

[Fact]
public void Add1ItemRemoveItemRemoveAgainHas0Items() {
        var expectedNoOfItems = 0;
        Hashtable item = new Hashtable();
        shoppingAPI.AddItem(item);
        shoppingAPI.RemoveItem(item);
        var actualNoOfItems = shoppingAPI.RemoveItem(item);
        Assert.Equal(expectedNoOfItems, actualNoOfItems);
}

這個期望測試依賴于 RemoveItem(item) 功能。目前的 shippingAPI 還不具備該功能,你需要增加該功能。

回到 app 文件夾,打開 IShippingAPI.cs 文件,新增以下聲明:

int RemoveItem(Hashtable item);

到 ShippingAPI.cs 中實現該功能:

public int RemoveItem(Hashtable item) {
        basket.RemoveAt(basket.IndexOf(item));
        return basket.Count;
}

運行,然后你會得到如下錯誤:

Error

Error

系統在移除一個不在購物框的商品,這導致了系統崩潰。加一點點 防御式編程defensive programming:

public int RemoveItem(Hashtable item) {
        if(basket.IndexOf(item) >= 0) {
                basket.RemoveAt(basket.IndexOf(item));
        }
        return basket.Count;
}

在移除商品之前先檢查它是否在購物框中。(你可能試過用捕獲異常的方式來處理,但是我認為上面的處理方式更具可讀性。)

更多具體的期望

在講更多具體的期望之前,讓我們先探討一下什么是接口。在軟件工程中,接口表示一種規范,或者對能力的描述。從某種程度上來說,接口類似于菜譜。它羅列出了制作蛋糕的原材料,但它本身并不能吃。我們只是按照菜譜上的說明來烤蛋糕。

與此類似,我們首先通過說明這個服務能做什么的方式來定義我們的服務。這個描述說明就是所謂的接口。但是接口本身并不能向我們提供任何功能。它只是指導我們實現指定功能的藍圖而已。

到目前為止,我們已經實現了接口(只是某部分實現了,稍后還會增加新功能)和業務處理邊界(也就是購物框里的商品不能是負數)。你指導了 shoppingAPI 怎么向購物框添加商品,并通過 Add2ItemsBasketHas2Items 測試驗證了該功能的有效性。

然而僅僅具備向購物框添加商品的功能還不足以使其成為一個網購應用程序。它還需要能夠計算購物框里的商品的總價。現在需要增加另一個期望。

按照慣例,從最直接明了的期望開始。當你向購物框里加入一件價值 ¥10 的商品時,你希望這個購物 API 能正確地計算出總價為 ¥10。

第五個測試(偽造版)如下:

[Fact]
public void Add1ItemPrice10GrandTotal10() {
        var expectedTotal = 10.00;
        var actualTotal = 0.00;
        Assert.Equal(expectedTotal, actualTotal);
}

還是一樣的老把戲,通過硬編碼一個錯誤的值讓 Add1ItemPrice10GrandTotal10 測試失敗。當然前三個測試成功通過,但第四個新增的測試失敗了:

A total of 1 test files matched the specified pattern.
[xUnit.net 00:00:00.57] tests.UnitTest1.Add1ItemPrice10GrandTotal10 [FAIL]
  X tests.UnitTest1.Add1ItemPrice10GrandTotal10 [4ms]
  Error Message:
   Assert.Equal() Failure
Expected: 10
Actual: 0

Test Run Failed.
Total tests: 4
     Passed: 3
         Failed: 1
 Total time: 1.0320 Seconds

將硬編碼值換成實際的處理代碼。首先,檢查接口是否具備計算訂單總價的功能。根本沒有這種東西。目前為止接口中只聲明了三個功能:

  1. int NoOfItems();
  2. int AddItem(Hashtable item);
  3. int RemoveItem(Hashtable item);

它們都不具備計算總價的能力。所以需要聲明一個新功能:

double CalculateGrandTotal();

這個新功能應該讓 shoppingAPI 具備計算總價的能力。這是通過遍歷購物框中的商品并把它們的價格累加起來實現的。

修改第五個測試:

[Fact]
public void Add1ItemPrice10GrandTotal10() {
        var expectedGrandTotal = 10.00;
        Hashtable item = new Hashtable();
        item.Add("00000001", 10.00);
        shoppingAPI.AddItem(item);
        var actualGrandTotal = shoppingAPI.CalculateGrandTotal();
        Assert.Equal(expectedGrandTotal, actualGrandTotal);
}

這個測試表明了這樣的期望:如果向購物框里加入一件價格 ¥10 的商品,然后調用 CalculateGrandTotal() 方法,它會返回商品總價 ¥10。這是一個完全合理的期望,它完全符合商品總價計算的邏輯。

那么怎么實現這個功能呢?就像以前一樣,先寫一個假的實現。回到 ShippingAPI 類中,實現在接口中聲明的 CalculateGrandTotal() 方法:

public double CalculateGrandTotal() {
                return 0.00;
}

現在先將返回值硬編碼為 0.00,只是為了檢驗這個測試能否正常運行,并確認它是能夠失敗的。事實上,它能夠運行,并且如預期一樣失敗。接下來的工作就是正確實現計算商品總價的處理邏輯:

public double CalculateGrandTotal() {
        double grandTotal = 0.00;
        foreach(var product in basket) {
                Hashtable item = product as Hashtable;
                foreach(var value in item.Values) {
                        grandTotal += Double.Parse(value.ToString());
                }
        }
        return grandTotal;
}

運行,五個測試全部通過!

從單元素場景到多元素場景

現在是時候進入下一輪迭代了。你已經通過處理最簡場景、單元素場景和邊界場景迭代地構建了系統,現在需要處理稍復雜的多元素場景了。

快捷提示:由于我們一直在針對單個元素場景、多元素場景和邊界行為這三點上對軟件進行迭代改進,一些讀者可能會認為我們同樣應該對接口進行改進。我們稍后就會發現,接口已經完全滿足需要了,目前沒有新增功能的必要。請記住,應該保持接口的簡潔。(盲目地)擴增接口不會帶來任何好處,只會引入噪音。我們要遵循 奧卡姆剃刀Occam's Razor 原則:如無必要,勿增實體。 現在我們已經基本完成了接口功能描述的工作,是時候改進實現了。

通過上一輪的迭代,系統已經能夠處理購物框里有超過一件商品的情況了。現在我么來讓系統具備購物框里有超過一件商品時計算總價的能力。首先寫可執行期望:

[Fact]
public void Add2ItemsGrandTotal30() {
        var expectedGrandTotal = 30.00;
        var actualGrandTotal = 0.00;
        Assert.Equal(expectedGrandTotal, actualGrandTotal);
}

硬編碼所有值,盡量讓期望測試失敗。

測試確實失敗了,現在得想辦法讓它通過。向購物框添加兩件商品,然后調用 CalculateGrandTotal() 方法:

[Fact]
public void Add2ItemsGrandTotal30() {
	      var expectedGrandTotal = 30.00;
        Hashtable item = new Hashtable();
        item.Add("00000001", 10.00);
        shoppingAPI.AddItem(item);
        Hashtable item2 = new Hashtable();
        item2.Add("00000002", 20.00);
        shoppingAPI.AddItem(item2);
        var actualGrandTotal = shoppingAPI.CalculateGrandTotal();
        Assert.Equal(expectedGrandTotal, actualGrandTotal);
}

測試通過。現在共有六個可以通過的微測試,系統回到了穩態。

設定期望

作為一個認真負責的工程師,你希望確保當用戶向購物框添加一些商品然后又移除一些商品后系統仍然能夠計算出正確出總價。下面是這個新的期望:

[Fact]
public void Add2ItemsRemoveFirstItemGrandTotal200() {
        var expectedGrandTotal = 200.00;
        var actualGrandTotal = 0.00;
        Assert.Equal(expectedGrandTotal, actualGrandTotal);
}

這個期望表示將兩件商品加入到購物框,然后移除第一件后期望的總價是 ¥200。硬編碼行為失敗了。現在設計更具體的正面測試樣例,然后運行代碼:

[Fact]
public void Add2ItemsRemoveFirstItemGrandTotal200() {
        var expectedGrandTotal = 200.00;
        Hashtable item = new Hashtable();
        item.Add("00000001", 100.00);
        shoppingAPI.AddItem(item);
        Hashtable item2 = new Hashtable();
        item2.Add("00000002", 200.00);
        shoppingAPI.AddItem(item2);
        shoppingAPI.RemoveItem(item);
        var actualGrandTotal = shoppingAPI.CalculateGrandTotal();
        Assert.Equal(expectedGrandTotal, actualGrandTotal);
}

在這個正面測試樣例中,先向購物框加入第一件商品(編號為 00000001,價格為 ¥100),再加入第二件商品(編號為 00000002,價格為 ¥200)。然后將第一件商品移除,計算總價,比較計算值與期望值是否相等。

運行期望測試,系統正確地計算出了總價,滿足這個期望測試。現在有七個能順利通過的測試了。系統運行良好,無異常!

Test Run Successful.
Total tests: 7
     Passed: 7
 Total time: 0.9544 Seconds

敬請期待

現在你已經學習了 ZOMBIES 方法中的 ZOMBI 部分,下一篇文章將介紹處理特殊行為。到那個時候,你可以試試自己的測試!

責任編輯:龐桂玉 來源: Linux中國
相關推薦

2023-05-16 17:34:49

ZOMBIES軟件開發

2023-05-30 18:26:49

ZOMBIES軟件開發

2023-05-13 17:38:03

ZOMBIES軟件開發

2010-03-24 14:37:29

Python編程語言

2024-04-02 06:03:00

GenAI軟件開發人工智能

2023-08-01 15:24:18

DevOps自動化軟件開發

2024-05-20 12:47:03

AI軟件開發

2009-06-12 11:35:28

模式框架軟件設計

2023-06-08 16:47:09

軟件開發工具

2023-02-09 16:48:12

軟件開發測試結對測試

2024-07-23 08:06:19

緩存技術策略

2024-03-14 06:51:22

GenAI人工智能

2021-12-14 09:00:00

IT開發運營

2020-03-31 10:08:15

零信任安全軟件

2023-06-09 19:01:03

軟件開發

2011-07-04 17:09:54

2011-08-11 09:56:50

模式

2020-10-16 10:21:23

大數據開發軟件開發技術

2014-03-21 09:30:26

軟件開發碼農

2017-03-17 08:15:17

敏捷軟件開發軟件開發
點贊
收藏

51CTO技術棧公眾號

欧美日韩一区二区在线视频| 99久久久精品| 久久精品亚洲一区| 少妇献身老头系列| 综合久久2023| 日韩一区中文字幕| 精品久久久久久中文字幕动漫| 区一区二在线观看| 综合色一区二区| 亚洲精品永久免费| 亚洲欧美一区二区三区不卡| segui88久久综合9999| 久久久激情视频| 91精品久久久久久久久青青| 精品成人久久久| 青青草原综合久久大伊人精品 | 69堂精品视频在线播放| 亚洲色欲色欲www| 欧美激情第一页在线观看| 国产精品国产一区二区三区四区| 一区二区三区成人精品| 蜜月aⅴ免费一区二区三区| www.久久国产| 亚洲一区二区三区日本久久九| 日韩欧美中文在线| 日本大胆人体视频| avav免费在线观看| 91亚洲精品久久久蜜桃网站 | 成人免费毛片网| 高h视频在线观看| 欧美韩国日本综合| 欧美精品免费观看二区| 日本韩国在线观看| 国产乱妇无码大片在线观看| 国产脚交av在线一区二区| 国产精品theporn动漫| 亚洲综合婷婷| 最近的2019中文字幕免费一页| 特级西西人体wwwww| 一区三区自拍| 日韩一区二区三区免费看| 天天干天天草天天| 无人区在线高清完整免费版 一区二| 亚洲线精品一区二区三区八戒| 国产一区一区三区| 欧美激情办公室videoshd| 国产日韩欧美在线一区| 欧美日韩亚洲一区二区三区在线观看| 亚洲成人777777| 国产精品一二三四区| 91久热免费在线视频| 亚洲天堂男人网| 蜜桃视频在线一区| 国产精品香蕉国产| 中文字幕精品无码亚| 日本在线播放一区二区三区| 国产999在线观看| jizz国产在线观看| 视频一区二区三区在线| 国产成人亚洲综合91精品| 日本高清不卡码| 久久激情视频| 国产精品福利小视频| 波多野结衣毛片| 蜜臀av性久久久久蜜臀aⅴ流畅 | 91精品国产91| 国产三级av片| 日本欧美大码aⅴ在线播放| 国产成人91久久精品| 探花国产精品一区二区| 蜜臀av性久久久久蜜臀aⅴ流畅 | 麻豆一区一区三区四区| 亚洲国产欧美一区二区丝袜黑人 | 亚洲国产精品三区| 色综合视频一区二区三区日韩| 欧美日韩国产另类一区| 一级 黄 色 片一| 超碰精品在线观看| 亚洲电影免费观看高清完整版在线观看 | 欧美日韩国产va另类| 免费人成在线观看| 国产亚洲毛片| 国产精品日韩电影| 国产黄色片av| 91视视频在线观看入口直接观看www | 久久人人精品| 成人精品视频99在线观看免费| 国产欧美一级片| 99riav久久精品riav| 日产国产精品精品a∨| 欧美激情视频在线播放| 午夜av一区二区| 天堂中文视频在线| 日韩区一区二| 亚洲日本中文字幕免费在线不卡| 色偷偷男人天堂| 在线看片日韩| 国产在线视频2019最新视频| 亚洲欧美另类综合| 欧美激情综合网| 日韩欧美猛交xxxxx无码| 欧美大电影免费观看| 91精品国产综合久久精品麻豆| 亚洲欧美日韩色| 日韩一级毛片| 午夜精品一区二区三区在线播放| 综合久久中文字幕| av激情亚洲男人天堂| 在线观看日韩片| 中文字幕在线中文字幕在线中三区| 欧美日本一区二区在线观看| 内射中出日韩无国产剧情| 一区二区三区四区电影| 国产精品极品美女在线观看免费 | 日韩在线免费av| 你懂的国产视频| 国产麻豆91精品| 婷婷四房综合激情五月| 国产三级电影在线播放| 91精品国产91久久久久久一区二区| 给我看免费高清在线观看| 欧美黄色大片网站| 国产欧美 在线欧美| 青青久在线视频| 亚洲国产人成综合网站| 日本在线观看视频一区| 成人a'v在线播放| 欧美在线中文字幕| 日韩在线视频第一页| 亚洲蜜臀av乱码久久精品蜜桃| 亚洲欧美日韩一级| 精品久久久久久久| 日本高清不卡的在线| 日韩一级片免费看| 亚洲成人综合网站| 久久人妻少妇嫩草av蜜桃| 综合精品一区| 成人a在线视频| 调教视频免费在线观看| 欧美四级电影在线观看| 欧美另类z0zx974| 视频一区在线播放| 欧洲精品久久| 欧美成人黑人| 伊人久久五月天| 特级西西444www大胆免费看| 国产丝袜美腿一区二区三区| 国产日韩一区二区在线观看| 牲欧美videos精品| 91精品国产777在线观看| 香蕉国产在线视频| 精品久久久久久久久久久久久久| 日本黄色录像片| 中国女人久久久| 欧美久久久久久| 电影亚洲精品噜噜在线观看| 一区二区三区国产视频| 中文无码av一区二区三区| 欧美韩日一区二区三区| 欧美在线aaa| 911精品美国片911久久久| 99精彩视频| 国产传媒在线观看| 亚洲毛片在线观看.| 黄色污污网站在线观看| 国产欧美一区二区精品性色| 潘金莲激情呻吟欲求不满视频| 亚洲网色网站| 国产亚洲情侣一区二区无 | 国产在线精品自拍| 视频在线观看入口黄最新永久免费国产 | 无码日韩人妻精品久久蜜桃| 色中色综合网| 成人看片在线| 欧美日韩免费看片| xvideos亚洲| 日韩性xxxx| 欧美日韩一区二区三区在线| 印度午夜性春猛xxx交| eeuss国产一区二区三区| 欧美日韩在线成人| 自拍偷拍欧美专区| 久久免费看av| www.久久99| 欧日韩不卡在线视频| 欧美成人xxx| 亚洲黄一区二区| 免费在线不卡av| 亚洲综合激情网| 亚洲天堂最新地址| 成人一级视频在线观看| 一级黄色香蕉视频| 欧美日本久久| 日韩一区二区电影在线观看| 日韩在线视频一区二区三区| 91福利视频网| av色综合久久天堂av色综合在| 精品国产乱码久久久久久1区2区 | 日本高清不卡三区| 日韩在线观看中文字幕| 国产精品成人久久久久| caopen在线视频| 一区二区av在线| 桃花色综合影院| 日韩欧美一级二级三级久久久| 无码人妻精品一区二区50| 一区二区三区在线免费视频| av网站免费在线看| 成人高清免费观看| 波多野结衣国产精品| 久久在线精品| 国产真人做爰毛片视频直播| 国产精品国内免费一区二区三区| 久久久久一区二区三区| 97品白浆高清久久久久久| 国产一区视频在线播放| 欧洲av一区二区| 国产91精品久久久| 国产色婷婷在线| 欧美精品一区三区| 欧美日韩在线看片| 国产亚洲欧美aaaa| 日本亚洲一区| 日韩成人中文字幕在线观看| www.五月激情| 91精品国产综合久久小美女| 中文无码av一区二区三区| 色综合久久精品| 亚洲男人第一av| 红桃视频成人在线观看| 久久精品欧美一区二区| 亚洲精品免费在线| 91麻豆精品成人一区二区| 国产精品午夜春色av| 在线观看国产精品一区| 日韩电影免费网站| 国产精品一区二区av| 视频一区日韩精品| 亚洲精品日韩av| www.成人在线.com| 亚洲一区二区在线| 99视频有精品高清视频| 成人信息集中地欧美| 色综合视频一区二区三区日韩| 国产精品夜色7777狼人| 97精品国产99久久久久久免费| 国产成人拍精品视频午夜网站 | 好吊一区二区三区视频| 成人综合婷婷国产精品久久 | 成人性免费视频| 欧美性色综合| 搞av.com| 亚洲伊人观看| 精品久久久久av| 日本视频在线一区| www.久久91| 国产精品一级二级三级| www.四虎精品| www国产亚洲精品久久麻豆| 亚洲专区区免费| 国产精品三级av| 天天色影综合网| 一区二区三区视频在线看| 日本三级片在线观看| 欧美三级免费观看| 少妇无套内谢久久久久| 91精品国产综合久久精品| 亚洲av综合色区无码一二三区 | 国产区av在线| 中文字幕欧美日韩在线| sm国产在线调教视频| 国外成人在线播放| 蜜桃视频成人m3u8| 国产欧美精品xxxx另类| 亚洲国产视频二区| 久久久久久九九| 欧美一区二区性| 日韩精品手机在线观看| 夜久久久久久| 亚洲综合欧美在线| 福利视频网站一区二区三区| 成年人的黄色片| 国产精品色哟哟| 国产精品999久久久| 欧美亚洲国产一区二区三区va| 国产口爆吞精一区二区| 亚洲精品国产美女| 在线观看av的网站| 久久欧美在线电影| 福利一区在线| 精品91免费| 99久久夜色精品国产亚洲96 | 亚洲成人a级网| 高清av在线| 欧美精品videossex88| 深夜视频一区二区| 国产高清自拍一区| 奇米影视亚洲| 成年人观看网站| 国产电影精品久久禁18| 日本少妇xxxxx| 亚洲成人精品在线观看| 国产精品人人爽| 亚洲日本成人网| 97人人在线视频| 成人有码在线视频| 国产乱码精品一区二区三区四区| 在线观看17c| 精品一二线国产| 播金莲一级淫片aaaaaaa| 中文字幕综合网| 糖心vlog精品一区二区| 亚洲精品狠狠操| 四虎av在线| 成人精品一区二区三区电影免费| 在线看成人短视频| 成人午夜免费在线视频| 看电视剧不卡顿的网站| 精品久久久久久中文字幕人妻最新| 亚洲男人的天堂一区二区| www.亚洲激情| 日韩精品在线视频美女| 伦理av在线| 99三级在线| 午夜久久福利| 久久久久久久久久毛片| 国产精品天干天干在线综合| 狠狠人妻久久久久久| 精品不卡在线视频| 啪啪免费视频一区| 91中文字幕在线| 亚洲影视一区二区三区| www.亚洲自拍| 亚洲精品五月天| 国产欧美第一页| 欧美成人性生活| 日韩一级淫片| 国产精品www在线观看| 成人午夜精品在线| 国产精品99无码一区二区| 亚洲成人xxx| 最近在线中文字幕| 欧美一区激情视频在线观看| 久久午夜精品| 在线观看免费小视频| 欧美在线观看视频一区二区| 国产乱理伦片a级在线观看| 国产成人一区二区| 日韩午夜电影网| 精品国产鲁一鲁一区二区三区| 自拍偷拍欧美精品| 午夜精品久久久久久久91蜜桃| 欧美大片在线看免费观看| 色悠久久久久综合先锋影音下载| 国产女教师bbwbbwbbw| 国产69精品久久久久毛片 | 在线视频观看一区| 成人在线免费看| 成人高清视频观看www| 91精品1区| 国产婷婷在线观看| 欧美日韩国产一区在线| 欧美黄色小说| 国产精品中文久久久久久久| 香蕉国产精品| 久久久久99人妻一区二区三区| 亚洲一区二区黄色| 亚洲av毛片成人精品| 国产精品国产三级国产aⅴ浪潮| 色999国产精品| 亚洲欧洲日韩综合| 欧美日韩在线看| 日本免费视频在线观看| 国产不卡一区二区在线观看| 国产精品一二| 免费黄色国产视频| 亚洲国产精品成人av| 性欧美freehd18| 日本大片免费看| 久久久久久久久久久99999| 一二区在线观看| 午夜精品福利电影| 久久99久久人婷婷精品综合 | jizz国产精品| 国产精品无码av无码| 亚洲女同一区二区| 欧美日韩免费做爰大片| 444亚洲人体| 日韩精品一区第一页| 欧美三根一起进三p| 亚洲男人av电影| 天堂va在线高清一区| 日本爱爱免费视频| 亚洲成人免费看| 乱人伦中文视频在线| 免费看成人av| 高清不卡一区二区| 一级黄色大片免费| 欧美亚洲成人网| 你懂的成人av|