wiki:codekata/harrypotter4

Version 1 (modified by chenyang, 12 years ago) (diff)

--

2013年9月13,9.20日代码道场活动纪实

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

地点:4G会议室

回顾一下,上一期,我们做了购书活动的扩展,将下面的几种折扣方案进行比较,哪种最优惠,就有哪种方案结帐。

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

考虑到,实际生活中,商场有时也会进行一些折上折的促俏活动,所以,我们将再一次对购书活动的促俏方式进行扩展
我们按照顺序,依次对上面几种促销方案,进行折扣,最后计算出总价
我们设计折上折的促俏方案类为Best2Calculator,它实现了PriceCalculator接口。
我们对各个方案组合开发了测试代码,如下:

package cn.pconline.harrypotter;

import static org.junit.Assert.*;

import java.util.ArrayList;
import java.util.List;

import org.junit.Before;
import org.junit.Test;

public class Best2CalculatorTest {
	private List<Book> books = null;
	private Best2Calculator best2Calculator = null;
	private Book book1 = new Book(BookType.one);
	private Book book2 = new Book(BookType.two);
	private Book book3 = new Book(BookType.three);
	private Book book4 = new Book(BookType.four);
	private Book book5 = new Book(BookType.five);
	private Book book6 = new Book(BookType.six);
	private Book book7 = new Book(BookType.seven);
	
	@Before
	public  void setup() {
		books = new ArrayList<Book>();
		best2Calculator = new Best2Calculator();				
	}
	

	/**
	 * 测试无满足方案(只买一本)
	 * @throws Exception
	 */
	@Test
	public void testCalculate0() throws Exception {
		books.add(book1);
		int price = best2Calculator.calculate(books);
		assertEquals(800, price);
	}
	
	/**
	 * //满足1种方案
	 */
	@Test
	public void testCalculate1() {
	   //只满足第1种方案,多集少于5本,一共少于7本
		books.add(book1);
		books.add(book2);
		books.add(book3);
		int price = best2Calculator.calculate(books);
		assertEquals(3 * 800 * 90/100 ,price);
		
	   //只满足第2种方案,单集只买5-6本
		books.clear();
		for (int i=0; i<5; i++) {
			books.add(book1);
		}
		price = best2Calculator.calculate(books);
		assertEquals(5 * 800 - 700, price);
		
		books.add(book1);
		price = best2Calculator.calculate(books);
		assertEquals(6 * 800 - 700, price);

	   //只满足第3种方案不存在
		
	   //只满足第4种方案不存在
	}
	
	
	
	/**
	 * 满足2种方案
	 */
	@Test
	public void testCalculate2(){
		 //(单集5本,另有1集1本)符合方案1,方案2
		  
		for (int i=0; i<5; i++) {
			books.add(book1);
		}
		books.add(book2);
		int price = best2Calculator.calculate(books);
		assertEquals(6 * 800 * 95/100 - 700, price);
		
		  //(7-12本,单集不能等于或大于5本)符合方案1,方案3
		books.clear();
		for (int i = 0; i < 4; i++) {
			books.add(book1);
		}
		
		for(int i = 0; i < 3; i++) {
			books.add(book3);
		}
		
		price = best2Calculator.calculate(books);
		assertEquals(7 * 800 * 95/100 - 800, price);
		
		//等于12本,单集不能等于或大于5本
		books.clear();
		for (int i = 0; i < 4; i++) {
			books.add(book2);
		}
		
		for  (int i = 0; i < 4; i++) {
			books.add(book5);
		}
		
		for (int i = 0; i < 4; i++) {
			books.add(book3);
		}
		
		price = best2Calculator.calculate(books);
		assertEquals(12 * 800 * 90 / 100 - 800, price);
		
		//符合方案1,方案4,没有这种方案
		
		//符合方案2,方案3,
		books.clear();
		for (int i = 0; i < 7; i++) {
			books.add(book3);
		}
		price = best2Calculator.calculate(books);
		assertEquals(800 * 7 - 700 - 800, price);
		//符合方案2,方案4,没有这种方案
		
		//符合方案3,方案4,没有这种方案
	}
	
	/**
	 *  满足3种方案
	 */
	@Test
	public void testCalculate3(){
		//符合方案1,方案2,方案3
			// 买7 本,一集买2本,二集买5本
		int price = 0;
		books.clear();
		for (int i = 0; i < 5; i++) {
			books.add(book2);
		}
		books.add(book1);
		books.add(book1);
		
		price = best2Calculator.calculate(books);
		assertEquals(800 * 7 * 95 / 100 - 700 - 800,  price);
		
	      //符合方案1,方案2,方案4,没有这种方案
		
			//符合方案1,方案3,方案4
		      //买19本,四集各买4本,一集买3本
		 books.clear();
		 for (int i = 0; i < 4; i++) {
			 books.add(book1);
			 books.add(book2);
			 books.add(book3);
			 books.add(book4);
		 }
		 books.add(book5);
		 books.add(book5);
		 books.add(book5);
		 price = best2Calculator.calculate(books);
		 assertEquals(800 * 19 * 80 / 100 - (800 * 2) - 1000,  price);
			
			//符合方案2,方案3,方案4
		 /*
		  * 单集18本
		  * 
		  * (18 * 800) - (3 * 700) - (2 * 800) = 10700
		  * 所以单集18本满足方案2,3,4
		  */
		 books.clear();
		 for (int i = 0; i < 18; i++) {
			 books.add(book1);
		 }
		 
		 price = best2Calculator.calculate(books);
		 assertEquals(((18 * 800) - (3 * 700) - (2 * 800) - 10 * 100), price);
	}
	
	/**
	 * 满足4种方案
	 */
	@Test
	public void testCalculate4(){
		//符合全部方案
		/*买18本,买两集分别为9本
		 * (18 * 800 * 95 / 100 - (2 * 700) - (2 * 800))
		 */
		
		for (int i = 0; i < 9 ; i++) {
			books.add(book1);
			books.add(book2);
		}
		int price = best2Calculator.calculate(books);
		assertEquals((18 * 800 * 95 / 100 - (2 * 700) - (2 * 800) - 10 * 100) , price);
		
	}
}

Best2Calculator实现代码如下

package cn.pconline.harrypotter;

import java.util.List;

public class Best2Calculator implements PriceCalculator {

	@Override
	public int calculate(List<Book> list) {
	    if (list == null || list.isEmpty()) {
	    	return 0;
	    }
	    //方案1
	    PriceCalculator pc1 = new DefaultCashier();
	    //方案2
	    PriceCalculator pc2 = new DiscountCashier();
	    //方案3
	    PriceCalculator pc3 = new SendBookActivity();
	    //方案4
	    PriceCalculator pc4 = new SendMoneyActivity();
	    //没打折的总价
	    int tempPrice = list.size() * 800; 

	    int currentPrice = 0; // 保存当前价钱
	    
	    currentPrice = tempPrice - (tempPrice - pc1.calculate(list));
	    
	    currentPrice = currentPrice - (tempPrice - pc2.calculate(list));
	    
	    currentPrice = currentPrice - (tempPrice - pc3.calculate(list));
	    
	    if (currentPrice >= 1000) {
	    	currentPrice = currentPrice - (currentPrice / 10000) * 1000; 
	    }
	    
	    
	    
		return currentPrice;
	}
    
}
	

销售哈里波特书籍这个题目,真的很不错,我们从实现最基本功能到实现各种促俏方案,从易到难,循序渐进,
我们做了好几期,大家都有收获,大家一起讨论,团队协作能力有一定的提高。对单元测试有了更深的理解,对大家养成单元测试的习惯,有了很大的促进作用。
中间,我们使用模拟测试的技术,让新同事耳目一新。