Java 如何使用TDD方法为一个简单的购物车示例设计类?

Java 如何使用TDD方法为一个简单的购物车示例设计类?,java,design-patterns,tdd,ooad,Java,Design Patterns,Tdd,Ooad,我遇到了一个使用Java学习OOAD和TDD的购物车练习 这项工作是: 第一步:设计结账系统 为一家出售面包、牛奶和香蕉三种产品的商店建立一个结账系统 这些产品的成本是:面包-1美元,牛奶-0.60美元,香蕉-0.40美元 建立一个系统来结帐购物车,购物车可以有这3种产品的倍数,并显示订单总数。 例如: 面包、牛奶、香蕉=2美元 面包、面包、牛奶、香蕉=3美元 牛奶、香蕉、牛奶、香蕉=2.00美元 作为下一步:增强代码以应用以下折扣和优惠 买一个面包,免费得到另一个面包 以2英镑的价格购买

我遇到了一个使用Java学习OOAD和TDD的购物车练习

这项工作是:


第一步:设计结账系统

  • 为一家出售面包、牛奶和香蕉三种产品的商店建立一个结账系统
  • 这些产品的成本是:面包-1美元,牛奶-0.60美元,香蕉-0.40美元
  • 建立一个系统来结帐购物车,购物车可以有这3种产品的倍数,并显示订单总数。 例如: 面包、牛奶、香蕉=2美元 面包、面包、牛奶、香蕉=3美元 牛奶、香蕉、牛奶、香蕉=2.00美元
作为下一步:增强代码以应用以下折扣和优惠

买一个面包,免费得到另一个面包 以2英镑的价格购买3杯牛奶 买两个香蕉,送一个

首先构建一个最简单的解决方案,仅满足第一种情况。然后对代码进行重新因子化,以将其扩展到第二步


第一步似乎很简单,但当涉及到第二步时,应用适当的OOAD原则和设计模式是很有挑战性的。 我看了两个相关的问题,如
. 但这并没有多大帮助。 感谢您对如何进行的任何建议

第一步我能想到的代码是:

  • ShoppingCartTest.java:

    public class ShoppingCartTest {
    
    ShoppingCart cart;
    
    @Before
    public void setUp(){
        cart = new ShoppingCart();
    }
    
    @Test
    public void addOneItemToCart() {
        cart.add("Bread");
        assertThat(cart.getTotalItems(), is(1));
        assertThat(cart.doesContain("Bread"), is(true));
    }
    
    @Test
    public void addTwoItemsToCart(){
        cart.add("Bread");
        cart.add("Milk");
        assertThat(cart.getTotalItems(), is(2));
        assertTrue(cart.doesContain("Bread"));
        assertTrue(cart.doesContain("Milk"));
    }
    
    @Test
    public void addThreeItemsToCart(){
        cart.add("Bread");
        cart.add("Milk");
        cart.add("Banana");
        assertThat(cart.getTotalItems(), is(3));
        assertTrue(cart.doesContain("Bread"));
        assertTrue(cart.doesContain("Milk"));
        assertTrue(cart.doesContain("Banana"));
    }
    
    @Test
    public void addAnItemTwice(){
        cart.add("Bread");
        cart.add("Bread");
        assertThat(cart.getTotalItems(), is(2));
    }
    
    @Test
    public void checkOutOneItem(){
        cart.add("Bread");
        assertThat(cart.checkout(), is(1.0));
    }
    
    @Test
    public void checkoutTwoSeparateItems(){
        cart.add("Bread");
        cart.add("Milk");
        assertThat(cart.checkout(), is(1.60));
    }
    
    @Test
    public void checkoutThreeSeparateItems(){
        cart.add("Bread");
        cart.add("Milk");
        cart.add("Banana");
        assertThat(cart.checkout(), is(2.0));
    }
    
    @Test
    public void checkoutTwoSameItems(){
        cart.add("Bread");
        cart.add("Bread");
        assertThat(cart.checkout(), is(2.0));
    }
    
    @Test
    public void checkoutThreeItems(){
        cart.add("Bread");
        cart.add("Bread");
        cart.add("Milk");
        assertThat(cart.checkout(), is(2.6));
    }
    
    @Test
    public void checkoutManyItems(){
        cart.add("Bread");
        cart.add("Bread");
        cart.add("Milk");
        cart.add("Milk");
        cart.add("Banana");
        assertThat(cart.checkout(), is(3.60));
    }
    
    @Test 
    public void checkOutAnInvalidItem(){
        cart.add("InvalidItem");
        assertThat(cart.checkout(),is(0.0));
    }}
    
  • Shopping Cart.java:

    import java.util.ArrayList;
    import java.util.List;
    
    public class ShoppingCart {
    
    List<String> items;
    
    public ShoppingCart(){
        items = new ArrayList<String>();
    }
    
    public void add(String item) {
        items.add(item);
    }
    
    public int getTotalItems() {
        return items.size();
    }
    
    public Boolean doesContain(String itemName) {
        return items.contains(itemName);
    }
    
    public Double checkout() {
        double total = 0;
        for(String item: items){
            if(item.equals("Bread")){
                total += 1;
            }else if(item.equals("Milk")){
                total += 0.6;
            }else if(item.equals("Banana")){
                total += 0.4;
            }
        }
        return total;
    }   
    
    }
    
    import java.util.ArrayList;
    导入java.util.List;
    公共类购物车{
    清单项目;
    公共购物车(){
    items=newarraylist();
    }
    公共无效添加(字符串项){
    项目。添加(项目);
    }
    公共int getTotalItems(){
    返回items.size();
    }
    公共布尔值doesContain(字符串itemName){
    返回项目。包含(itemName);
    }
    公共双签出(){
    双倍合计=0;
    用于(字符串项:项){
    如果(项目等于(“面包”)){
    总数+=1;
    }如果(项目等于(“牛奶”)){
    总数+=0.6;
    }else if(项等于(“香蕉”)){
    总数+=0.4;
    }
    }
    返回总数;
    }   
    }
    
    相反,您可以用java中的HashMap简单地实现购物车流程

    其形式如下:

    Map<String === itemname , Item === Item object>
    
    Map<String, Item> cart = new HashMap<String, Item>();
    
    Class Item{
    private int count;
    private String Name;
    private int prices;
    //getters and setters go here
    }
    
    Map
    Map cart=newhashmap();
    类项目{
    私人整数计数;
    私有字符串名称;
    私人价格;
    //能手和二传手都在这里
    }
    
    实现这一点的方法太多了。正如问题中提到的,您的第二步是重构您的第一步。因此,如果我们知道您如何实施第一步,那么缩小范围会容易得多。TDD的一般方法是首先编写代码(测试)来调用给定的功能(这显然会失败),然后修改应用程序代码以确保测试通过。@GurusharanS同意您的意见。我将开发代码的第一部分,并很快与大家分享。@GurusharanS,我创建了一个类似的部分,好吧,GitHub项目看起来相当成熟-您是否面临任何问题?如果是这样的话,你能告诉我你面临着什么样的错误吗?@Vivek感谢你提供了详细的项目。我正在看一看。您是基于TDD得出此解决方案的,还是首先开发此解决方案并添加测试?