wiki:codekata/harrypoter

Version 2 (modified by chenyang, 13 years ago) (diff)

--

2013年8月9日代码道场活动纪实

代码道场的参与者:秦鸿源,陈阳,王安宁,丁健勇,邝巨恒,李炳岳,黄志强,李剑文,张艺辉, 李峰

地点:4G会议室

本次代码道场的题目,从大家推荐的题目中选出,考虑到上次活动的题目难度太大,我们选择了秦鸿源提供的题目.
题目如下:

	购买哈利波特书本,每本8块钱
	1.买2集,9.5折
	2.买3集,9折
	3.买4集,8.5折
	4.买5集,8折
	5.买6集,7.5折
	6.买7集,7折
	
	求出读者所买的书的总价

	扩展:
	单集购买5本,优惠7元。
	支持买6送1活动。
	支持购买100元送10活动。

活动刚开始,我们依然是先讨论需求,包括本人(陈阳)在内少部分同事,一开始没理解"几本","几集",的概念,将它们混淆,经过小组成员的
解释,大家都明白后,由我起头,创建了名为harrypotter的项目,按照讨论的结果,我们先创建了Book对象,设计了两个属性价格和第几集,
编写测试代码的时候,发现用int类型表示第几集,不合理,然后由秦鸿源提出,用枚举,于是将第几集,设计成枚举,代码如下:

package cn.pconline.harrypotter;

/**
 *
 * @author pc
 */
public enum BookType {
    one,
    two,
    three,
    four,
    five,
    six,
    seven
    
}
	

Book.java 如下:

package cn.pconline.harrypotter;

/**
 *
 * @author pc
 */
public class Book {
    private int price;
    private BookType bookType;

    private Book(){
        
    }
    
    public Book(BookType bookType){
        this.price = 800;
        this.bookType = bookType;
    }
    
    public Book(int price,BookType bookType){
        this.price = price;
        this.bookType = bookType;
    }
    
    public int getPrice() {
        return price;
    }

    public void setPrice(int price) {
        this.price = price;
    }

    public BookType getBookType() {
        return bookType;
    }

    public void setBookType(BookType bookType) {
        this.bookType = bookType;
    }

}
	

我们不想一开始的时候,就实现得很复杂,我们循序渐进,由易到难,先完成,每一本书都买一本的情况。
经大家计论,我们设计BookStore对象来实现,计算总价的方法,public int calculate(List<Book> list)
这里有一个小插曲,这个方法,本来被设计成返回类型是double的,但考虑到用浮点数计算,会损失精度,我们用分表示,总价的单位,所以最后被改成int类型
我们先编写测试代码

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package cn.pconline.harrypotter;

import java.util.ArrayList;
import java.util.List;
import org.junit.After;
import org.junit.AfterClass;
import org.junit.Assert;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
import static org.junit.Assert.*;

/**
 *
 * @author pc
 */
public class BookStoreTest {
    private List<Book> list = new ArrayList<Book>();
    private BookStore bs = null;
    
    public BookStoreTest() {
    }
    
    @BeforeClass
    public static void setUpClass() {
    }
    
    @AfterClass
    public static void tearDownClass() {
    }
    
    @Before
    public void setUp() {
         bs = new BookStore();
    }
    
    @After
    public void tearDown() {
    }

    /**
     * Test of calculate method, of class BookStore.
     */
    @Test
    public void testCalculate() {
        
        //没买任何书
        int price0 = bs.calculate(list);
        Assert.assertEquals(price0, 0);
        //买一集1本,计算价格
        Book book1 = new Book(BookType.one);
        list.add(book1);
        int price = bs.calculate(list);
        Assert.assertEquals(price, 800);
        
        list.add(new Book(BookType.two));       
        int price2 =  bs.calculate(list);
        assertEquals(price2, ((800 * 2 * 95)/ 100));
        
        list.add(new Book(BookType.three));
        int price3 = bs.calculate(list);
        Assert.assertEquals(price3, (800 * 3 * 90) / 100);
        
        list.add(new Book(BookType.four));
        int price4 = bs.calculate(list);
        Assert.assertEquals(price4, (800 * 4 * 85) / 100);
        
        list.add(new Book(BookType.five));
        int price5 = bs.calculate(list);
        Assert.assertEquals(price5, (800 * 5 * 80) / 100);
        
        list.add(new Book(BookType.six));
        int price6 = bs.calculate(list);
        Assert.assertEquals(price6, (800 * 6 * 75) / 100);
        
        list.add(new Book(BookType.seven));
        int price7 = bs.calculate(list);
        Assert.assertEquals(price7,(800 * 7 * 70)/100);
        
    }
  
    
    
}
		

接下来,准备写这个方法的实现了,轮到了王安宁操刀,王安宁给大家带了惊喜,王安宁以非常简洁优雅的代码代替 了穷举式的if...else...else if... else 代码如下:

    public int calculate(List<Book> list) {
        if (list == null || list.isEmpty()) {
            return 0;
        }
        int discount = 100 - (5 * (list.size() - 1));
        return 800 * list.size() * discount / 100;
    }
	

这次的活动,比较完美,达到了预期的目的,每个小组成员都得到了编写代码的机会,也享受到了,团队协作完成任务的乐趣。
还从有经验的同事身上学习到了编程技巧,还得到了李峰赞扬。
下次活动,我们将实现扩展需求,待续......