面向对象编程经典例题 --- 收银系统设计

SALES TAXES

 

Basic sales tax is applicable at a rate of 10% on all goods, except books, food, and medical products that are exempt. Import duty is an additional sales tax applicable on all imported goods at a rate of 5%, with no exemptions.

 

When I purchase items I receive a receipt which lists the name of all the items and their price (including tax), finishing with the total cost of the items, and the total amounts of sales taxes paid. The rounding rules for sales tax are that for a tax rate of n%, a shelf price of p contains (np/100 rounded up to the nearest 0.05) amount of sales tax.

 

Write an application that prints out the receipt details for these shopping baskets...

 

INPUT:

 

Input 1:

1 book at 12.49

1 music CD at 14.99

1 chocolate bar at 0.85

 

Input 2:

1 imported box of chocolates at 10.00

1 imported bottle of perfume at 47.50

 

Input 3:

1 imported bottle of perfume at 27.99

1 bottle of perfume at 18.99

1 packet of headache pills at 9.75

1 box of imported chocolates at 11.25

 

OUTPUT

 

Output 1:

1 book : 12.49

1 music CD: 16.49

1 chocolate bar: 0.85

Sales Taxes: 1.50

Total: 29.83

 

Output 2:

1 imported box of chocolates: 10.50

1 imported bottle of perfume: 54.65

Sales Taxes: 7.65

Total: 65.15

 

Output 3:

1 imported bottle of perfume: 32.19

1 bottle of perfume: 20.89

1 packet of headache pills: 9.75

1 imported box of chocolates: 11.85

Sales Taxes: 6.70

Total: 74.68

 

首先我们看,税种这里有三种:

1. 免消费税;

2. 消费税;

3. 进口税。

则税种组合有以下两种:

1.免消费税+进口税

2.消费税+进口税

因此,我们可以设计一个Tax接口,里头包含一个方法名叫getTax,这个getTax方法作用就是返回纳税值,但是我们需要有哪些类来实现这个接口呢?

1.FixedRateTax,它拥有一个成员变量叫做rate,因此针对不同的实例,它拥有不同的rate,每一个实例对应某一种固定税率,因此其getTax传入的参数便为对应商品价格,返回值即为在此税率之下的相应税收。

2.CompositeTax,它拥有一个成员函数叫做addTax,因此它的作用就是整合某一商品它所包含的所有税收类型,因此其getTax同样传入的对应商品价格作为参数,返回值为某商品其对应的全部税收,事实上了就是一个对于税率类型的遍历,每一种税率类型对应一个FixedRateTax的实例,然后调用FixedRateTaxgetTax方法获得此税率之下的相应税收加入当前税收总和之中,最后返回当前价格下的全部税收总和。

UML图如下:

 面向对象编程经典例题 --- 收银系统设计_第1张图片

 

对应的代码实现如下:

Tax.java

package main.java.com.thoughtworks.demo.taxes;

import java.math.BigDecimal;

/**
 * This interface provides unified access to different taxation kinds.
 * 
 */
public interface Tax {
	
	/**
	 * Calculates the tax value for the given price.
	 * @param price the price
	 * @return the tax value
	 */
	BigDecimal getTax(BigDecimal price);

}
FixedRateTax.java
package main.java.com.thoughtworks.demo.taxes.impl;

import java.math.BigDecimal;
import java.math.RoundingMode;

import main.java.com.thoughtworks.demo.taxes.Tax;

/**
 * A fixed rate implementation of the {@link Tax} interface. It rounds taxes up
 * to the nearest 0.05.
 * 
 */
public class FixedRateTax implements Tax {
	
	private static final BigDecimal TICK_SIZE = new BigDecimal("0.05");
	
	private final BigDecimal rate;
	
	/**
	 * Creates a tax with the specified rate.
	 * @param rate the tax rate
	 */
	public FixedRateTax(BigDecimal rate) {
		this.rate = rate;
	}

	@Override
	public BigDecimal getTax(BigDecimal price) {
		return roundOff(price.multiply(rate));
	}
	
	private static BigDecimal roundOff(BigDecimal value) {
		return value.divide(TICK_SIZE).setScale(0, RoundingMode.UP).multiply(TICK_SIZE);
	}

}
CompositeTax.java

package main.java.com.thoughtworks.demo.taxes.impl;

import java.math.BigDecimal;
import java.util.LinkedList;
import java.util.List;

import main.java.com.thoughtworks.demo.taxes.Tax;

/**
 * An implementation of the {@link Tax} interface that works as a superposition
 * of multiple taxes.
 * 
 */
public class CompositeTax implements Tax {
	
	private final List taxes = new LinkedList();
	
	/**
	 * Adds another tax to this composite.
	 * @param tax the tax to add
	 */
	public void addTax(Tax tax) {
		taxes.add(tax);
	}

	@Override
	public BigDecimal getTax(BigDecimal price) {
		BigDecimal result = BigDecimal.ZERO;
		for (Tax tax : taxes) {
			result = result.add(tax.getTax(price));
		}
		return result;
	}

}

说完了税收部分的设计,接下来的重点便是如何设计商品清单,

很显然如上输入所示,不同产品种类的货物对应不同的税率,因此首先我们要想到我们必须创建一个对应不同产品种类的类,使得这个类能够承载不同的产品类别及其对应的税率,这就是ProductCategory的由来。

有了ProductCategory之后,接下来我们需要考虑的就是针对每一件商品,我们都必须给予它一个条目详情,该条目详情包含四个属性,分别为商品ID,商品条目名称,商品价格,商品是否进口以及商品的类别(即为ProductCategory),通过这样的方式,我们就对每一条商品进行了登记,我们称之为CatalogItem

有了CatalogItem还不够,因为CatalogItem只是对商品的总体信息进行了登记,并没有记录用户实际买卖的信息,因此对于用户实际的某一条购买记录,我们创建一个类叫做OrderItem,显然每一条这个记录对应于某一个CatalogItem,而且OrderItem之中包含有四个特别的属性分别为,税务信息,购买数量,总支出,总税收。

显然对于每个客户,他都有若干条购买记录,所有这些购买记录构成一个新的实例,我们称之为order,这个order包含如下三条信息:票据编码,总消费税和总支出;

那么讲了这么多我们也大致将商品和清单之间的关系也理清楚了,其UML图如下:

 面向对象编程经典例题 --- 收银系统设计_第2张图片

对应的代码实现如下:

ProductCategory.java

package main.java.com.thoughtworks.demo.taxes;

import java.math.BigDecimal;

/**
 * Enumeration of product categories. Every category encapsulates its sales tax
 * rate.
 * 
 */
public enum ProductCategory {
	
	/**
	 * Books category. No sales tax.
	 */
	BOOK ("0"),

	/**
	 * Food category. No sales tax.
	 */
	FOOD ("0"),
	
	/**
	 * Medical products category. No sales tax.
	 */
	MEDICINE ("0"),

	/**
	 * Music products category.
	 */
	MUSIC,
	
	/**
	 * Perfume products category.
	 */
	PERFUME,	
	
	/**
	 * All other goods.
	 */
	OTHER;
	
	private final BigDecimal salesTax;

	/**
	 * Default constructor for product categories those have basic sales tax rate. 
	 */
	private ProductCategory() {
		this("0.1");
	}	
	
	/**
	 * This constructor defines sales tax rate for a product category.
	 * @param salesTax the sales tax rate
	 */
	private ProductCategory(String salesTax) {
		this.salesTax = new BigDecimal(salesTax);
	}

	/**
	 * Returns sales tax rate of this product category.
	 * @return sales tax rate value
	 */
	public BigDecimal getSalesTax() {
		return salesTax;
	}
	
}

CatalogItem.java

package main.java.com.thoughtworks.demo.taxes;

import java.math.BigDecimal;

/**
 * Catalog item abstraction. Contains base properties of an item in the catalog.
 * Immutable.
 * 
 */
public class CatalogItem {
	
	private final long id;
	
	private final String title;
	
	private final BigDecimal price;
	
	private final ProductCategory category;
	
	private final boolean imported;
	
	/**
	 * Constructor initializing all fields.
	 * @param id the item id
	 * @param title the item title
	 * @param price the item price
	 * @param category the product category
	 * @param imported the the flag defining if the item is imported or not
	 */
	public CatalogItem(long id, String title, BigDecimal price, ProductCategory category, boolean imported) {
		super();
		this.id = id;
		this.title = title;
		this.price = price;
		this.category = category;
		this.imported = imported;
	}

	public long getId() {
		return id;
	}

	public String getTitle() {
		return title;
	}

	public BigDecimal getPrice() {
		return price;
	}

	public boolean isImported() {
		return imported;
	}

	public ProductCategory getCategory() {
		return category;
	}
	
}
OrderItem.java

package main.java.com.thoughtworks.demo.taxes;

import java.math.BigDecimal;

/**
 * Order item abstraction. Contains a {@link CatalogItem} and an applied tax
 * value. Immutable.
 * 
 */
public class OrderItem {
	
	private final CatalogItem catalogItem;
	
	private final BigDecimal tax;
	
	private final int quantity;
	
	private final BigDecimal total;
	
	private final BigDecimal totalTax;
	
	/**
	 * Constructor.
	 * @param catalogItem the catalog item
	 * @param tax the value of applied tax
	 * @param quantity the number of catalog items (positive number)
	 */
	public OrderItem(CatalogItem catalogItem, BigDecimal tax, int quantity) {
		if (quantity <= 0) {
			throw new IllegalArgumentException("Quantity shall be positive");
		}
		this.catalogItem = catalogItem;
		this.tax = tax;
		this.quantity = quantity;
		this.totalTax = tax.multiply(new BigDecimal(quantity));		
		this.total = catalogItem.getPrice().multiply(new BigDecimal(quantity)).add(totalTax);

	}

	public CatalogItem getCatalogItem() {
		return catalogItem;
	}

	public BigDecimal getTax() {
		return tax;
	}

	public int getQuantity() {
		return quantity;
	}
	
	public BigDecimal getTotal() {
		return total;
	}

	public BigDecimal getTotalTax() {
		return totalTax;
	}

	@Override
	public String toString() {
		return quantity + " " + catalogItem.getTitle() + " : " + total;
	}
	
}
Order.java

package main.java.com.thoughtworks.demo.taxes;

import java.math.BigDecimal;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;

/**
 * A abstraction of an order. Contains ordered items. Immutable.
 * 
 */
public class Order {
	
	private final long id;
	
	private final List orderItems = new LinkedList();
	
	private final BigDecimal salesTaxes;
	
	private final BigDecimal total;
	
	/**
	 * Constructor.
	 * @param id the order's id
     * @param orderItems the list oder's items
	 */
	public Order(long id, List orderItems) {
		this.id = id;
		this.orderItems.addAll(orderItems);
		// calculate taxes and total
		BigDecimal salesTaxes = BigDecimal.ZERO;
		BigDecimal total = BigDecimal.ZERO;
		for (OrderItem orderItem : orderItems) {
			salesTaxes = salesTaxes.add(orderItem.getTotalTax());
			total = total.add(orderItem.getTotal());
		}
		this.salesTaxes = salesTaxes;
		this.total = total;
	}
	

	public long getId() {
		return id;
	}

	public List getOrderItems() {
		return Collections.unmodifiableList(orderItems);
	}

	@Override
	public String toString() {
		StringBuilder sb = new StringBuilder("Order ").append(id).append(":\n");
		for (OrderItem orderItem : orderItems) {
			sb.append(orderItem).append('\n');
		}
		sb.append("Sales taxes: ").append(salesTaxes).append('\n');
		sb.append("Total: ").append(total).append('\n');
		return sb.toString();
	}

}

接下来便是实际操作,在实际操作中我们涉及到两个问题,谁来对商品类别进行管理,谁来对购物清单进行管理,为此,我们建立了两个接口,一个叫做 CatalogManager ,另一个叫做 OrderManager ,在 CatalogManager 之中有两个接口函数,一个叫 addItem 另一个叫 removeItem ,很显然这两个函数接口的作用就是将添加或者删除不同的商品种类。

那么除此以外,所谓的OrderManager在这里的作用就是负责创建清单,取消清单,添加购买记录以及结账。当然我们不会忘记,既然对商品要进行管理,同时对税收我们也要进行对应的管理,因此我们还需要一个接口叫做TaxManager。这个TaxManager主要就完成一件事情,就是getTax收税,因为此前我们对于税务实现了两个类,那么这些类之间的关系和操作就由这个TaxManager来实现。

注意到CatalogManager需要实现删除的功能,显然要删除一个CatalogItem需要知道其对应的ID,但是对于OrderManager这边,注意到我们有结账的功能,考虑结账的时候需要知道相应商品的税率,这些税率来自ProductCategory,而ProductCategory不独立出现,ProductCategory是来自于CatalogItem,每一个CatalogItem也具有独立的ID,因此我们决定创立一个接口Catalog,里头就一个接口函数getItem,分别由OrderManager以及CatalogManager的实现类共同继承实现。

那么既然讲到OrderManager以及CatalogManager的实现类,那么它们各自有何特征呢?

对于CatalogManager,我们实现一个类叫做TrivialCatalogImpl,那么这个类实现了CatalogCatalogManager接口,重点进行商品种类的管理。

那么对于TrivialOrderManagerImpl,同样我们也实现了OrderManager的接口,但同时我们这里采用了一些IoC的手段来注入TaxManagerCatalogManager,理由是显然TrivialOrderManagerImplTaxManagerCatalogManager不存在一种继承关系,但是TrivialOrderManagerImpl当中的结账需要用到TaxManager来帮忙,自然TaxManager中的汇率信息必须由CatalogManager来提供,因此就形成了这样的一种关系。所以,这些类之间的UML关系图就如下所示:

 面向对象编程经典例题 --- 收银系统设计_第3张图片

CatalogManager.java

package main.java.com.thoughtworks.demo.taxes;

import java.math.BigDecimal;

/**
 * This service provides methods for catalog modification.
 * 
 */
public interface CatalogManager {
	
	/**
	 * Adds a new item.
	 * @param title the item's title
	 * @param price the item's price
	 * @param category the product category
	 * @param imported the flag defining if the item is imported or not
	 * @return the added item's id
	 */
	long addItem(String title, BigDecimal price, ProductCategory category, boolean imported);
	
	/**
	 * Removes the specified item.
	 * @param id the item's id
	 * @throws NoSuchItemException if there is no catalog item with the given id
	 */
	void removeItem(long id);

}
OrderManager.java

package main.java.com.thoughtworks.demo.taxes;

/**
 * This service is used to manage orders: create order, add item to the order,
 * checkout, etc.
 * 
 */
public interface OrderManager {
	
	/**
	 * Creates a new order.
	 * @return the order id
	 */
	long createOrder();
	
	/**
	 * Cancels the specified order.
	 * @param orderId the order id
	 */
	void cancelOrder(long orderId);
	
	/**
	 * Adds the specified catalog item to the specified order.
	 * @param orderId the order id
	 * @param itemId the catalog item id
	 * @param quantity the number of items to add
	 * @throws NoSuchItemException if there is no order or catalog item found for the specified ids
	 */
	void addItem(long orderId, long itemId, int quantity);
	
	/**
	 * Checkouts the specified order. The order is no longer available for updates after this operation.
	 * @param orderId the order id
	 * @return the order
	 * @throws NoSuchItemException if there is no order found for the specified id
	 */
	Order checkout(long orderId);
	
}
TaxManager.java

package main.java.com.thoughtworks.demo.taxes;

/**
 * Defines tax rates for catalog items.
 * 
 */
public interface TaxManager {
	
	/**
	 * Calculates a tax rate for the specified item's attributes.
	 * @param category the product category
	 * @param isImported the flag defining if the product was imported
	 * @return the {@link Tax} object to be applied
	 */
	Tax getTax(ProductCategory category, boolean isImported);

}
Catalog.java

package main.java.com.thoughtworks.demo.taxes;

/**
 * This service is intended for read only catalog access.
 * 
 */
public interface Catalog {
	
	/**
	 * Returns an item by its id.
	 * @param id the item's id
	 * @return the item
	 * @throws NoSuchItemException if there is no catalog item with the given id
	 */
	CatalogItem getItem(long id);

}
TaxManagerImpl.java

package main.java.com.thoughtworks.demo.taxes.impl;

import java.math.BigDecimal;

import main.java.com.thoughtworks.demo.taxes.ProductCategory;
import main.java.com.thoughtworks.demo.taxes.Tax;
import main.java.com.thoughtworks.demo.taxes.TaxManager;

/**
 * An implementation of the {@link TaxManager} interface that is able to manage
 * base sales taxes and import duties.
 * 
 */
public class TaxManagerImpl implements TaxManager {
	
	private static final BigDecimal IMPORT_DUTY_RATE = new BigDecimal("0.05");

	@Override
	public Tax getTax(ProductCategory category, boolean isImported) {
		CompositeTax result = new CompositeTax();
		result.addTax(new FixedRateTax(category.getSalesTax()));
		if (isImported) {
			result.addTax(new FixedRateTax(IMPORT_DUTY_RATE));
		}
		return result;
	}


}
TrivialCatalogImpl.java

package main.java.com.thoughtworks.demo.taxes.impl;

import java.math.BigDecimal;
import java.util.HashMap;
import java.util.Map;

import main.java.com.thoughtworks.demo.taxes.Catalog;
import main.java.com.thoughtworks.demo.taxes.CatalogItem;
import main.java.com.thoughtworks.demo.taxes.CatalogManager;
import main.java.com.thoughtworks.demo.taxes.NoSuchItemException;
import main.java.com.thoughtworks.demo.taxes.ProductCategory;

/**
 * Trivial in-memory implementation of the {@link Catalog} interface. It holds a
 * map {@link CatalogItem} objects using their ids as keys.
 * 
 */
public class TrivialCatalogImpl implements Catalog, CatalogManager {
	
	private final Map items = new HashMap();
	
	private final IdGenerator idGenerator = new IdGenerator();
	
	@Override
	public synchronized long addItem(String title, BigDecimal price, ProductCategory category, boolean imported) {
		long id = idGenerator.getId();
		CatalogItem item = new CatalogItem(id, title, price, category, imported);
		items.put(id, item);
		return id;
	}

	@Override
	public synchronized void removeItem(long id) {
		if (items.remove(id) == null) {
			throw new NoSuchItemException("There is no catalog item: " + id);
		}
	}

	@Override
	public synchronized CatalogItem getItem(long id) {
		CatalogItem item = items.get(id);
		if (item == null) {
			throw new NoSuchItemException("There is no catalog item: " + id);
		}
		return item;
	}
	
}
TrivialOrderManagerImpl.java

package main.java.com.thoughtworks.demo.taxes.impl;


import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;


import main.java.com.thoughtworks.demo.taxes.Catalog;
import main.java.com.thoughtworks.demo.taxes.CatalogItem;
import main.java.com.thoughtworks.demo.taxes.NoSuchItemException;
import main.java.com.thoughtworks.demo.taxes.Order;
import main.java.com.thoughtworks.demo.taxes.OrderItem;
import main.java.com.thoughtworks.demo.taxes.OrderManager;
import main.java.com.thoughtworks.demo.taxes.Tax;
import main.java.com.thoughtworks.demo.taxes.TaxManager;


/**
 * Trivial in-memory implementation of the {@link OrderManager} interface. It
 * holds a map {@link Order} objects using their ids as keys.
 * 
 */
public class TrivialOrderManagerImpl implements OrderManager {
	
	private final HashMap> orders = new HashMap>();
	
	private final IdGenerator idGenerator = new IdGenerator();
	
	private Catalog catalog;
	
	private TaxManager taxManager;
	
	public void setCatalog(Catalog catalog) {
		this.catalog = catalog;
	}
	
	public void setTaxManager(TaxManager taxManager) {
		this.taxManager = taxManager;
	}


	@Override
	public synchronized long createOrder() {
		long id = idGenerator.getId();
		List orderItems = new LinkedList();
		orders.put(id, orderItems);
		return id;
	}
	
	@Override
	public synchronized void cancelOrder(long orderId) {
		List orderItems = orders.remove(orderId);
		if (orderItems == null) {
			throw new NoSuchItemException("There is no order: " + orderId);
		}
	}	


	@Override
	public synchronized void addItem(long orderId, long itemId, int quantity) {
		List orderItems = orders.get(orderId);
		if (orderItems == null) {
			throw new NoSuchItemException("There is no order: " + orderId);
		}
		// create order item
		CatalogItem catalogItem = catalog.getItem(itemId);
		Tax tax = taxManager.getTax(catalogItem.getCategory(), catalogItem.isImported());
		OrderItem orderItem = new OrderItem(catalogItem, tax.getTax(catalogItem.getPrice()), 
                                                    quantity);
		orderItems.add(orderItem);
	}


	@Override
	public synchronized Order checkout(long orderId) {
		List orderItems = orders.remove(orderId);
		if (orderItems == null) {
			throw new NoSuchItemException("There is no order: " + orderId);
		}
		return new Order(orderId, orderItems);
	}
	
}
最后,我们需要一些工具类便于程序中的一些操作,例如产生 ID 以及抛出异常,如下所示:

 面向对象编程经典例题 --- 收银系统设计_第4张图片

 

IdGenerator.java

package main.java.com.thoughtworks.demo.taxes.impl;

import java.util.concurrent.atomic.AtomicLong;

/**
 * Trivial unique id generator. It just holds an id value and increments it each
 * time.
 *  
 */
class IdGenerator {

	private final AtomicLong nextId = new AtomicLong(1);
	
	/**
	 * Returns the next id value.
	 * @return the id
	 */
	public long getId() {
		return nextId.getAndIncrement();
	}
	
}
NoSuchItemException.java

package main.java.com.thoughtworks.demo.taxes;

/**
 * This exception is thrown when an item is not found in a repository.
 * 
 */
public class NoSuchItemException extends RuntimeException {
	/**
	 * Constructor.
	 * @param message the message describing this exception
	 */
	public NoSuchItemException(String message) {
		super(message);
	}

}
 总的UML图如下:

面向对象编程经典例题 --- 收银系统设计_第5张图片

main函数测试程序如下:

package main.java.com.thoughtworks.demo;

import java.math.BigDecimal;

import main.java.com.thoughtworks.demo.taxes.CatalogManager;
import main.java.com.thoughtworks.demo.taxes.Order;
import main.java.com.thoughtworks.demo.taxes.OrderManager;
import main.java.com.thoughtworks.demo.taxes.ProductCategory;
import main.java.com.thoughtworks.demo.taxes.impl.TaxManagerImpl;
import main.java.com.thoughtworks.demo.taxes.impl.TrivialCatalogImpl;
import main.java.com.thoughtworks.demo.taxes.impl.TrivialOrderManagerImpl;

/**
 * Demo program illustrating basic concepts of "sales taxes" problem solution.
 * 
 */
public class TaxesDemo {
	
	private CatalogManager catalogManager;
	
	private OrderManager orderManager;
	
	public void setCatalogManager(CatalogManager catalogManager) {
		this.catalogManager = catalogManager;
	}

	public void setOrderManager(OrderManager orderManager) {
		this.orderManager = orderManager;
	}

	public void demoCase1() {
		// prepare all needed goods
		long bookId = catalogManager.addItem("book", new BigDecimal("12.49"), ProductCategory.BOOK, false);
		long cdId = catalogManager.addItem("music CD", new BigDecimal("14.99"), ProductCategory.MUSIC, false);
		long chocolateId = catalogManager.addItem("chocolate bar", new BigDecimal("0.85"), ProductCategory.FOOD, false);
		// order these goods
		long orderId = orderManager.createOrder();
		orderManager.addItem(orderId, bookId, 1);
		orderManager.addItem(orderId, cdId, 1);
		orderManager.addItem(orderId, chocolateId, 1);
		Order order = orderManager.checkout(orderId);
		// print receipt
		System.out.println(order);
	}
	
	public void demoCase2() {
		// prepare all needed goods
		long chocolateId = catalogManager.addItem("imported box of chocolates", new BigDecimal("10.00"), ProductCategory.FOOD, true);
		long perfumeId = catalogManager.addItem("imported bottle of perfume", new BigDecimal("47.50"), ProductCategory.PERFUME, true);
		// order these goods
		long orderId = orderManager.createOrder();
		orderManager.addItem(orderId, chocolateId, 1);
		orderManager.addItem(orderId, perfumeId, 1);
		Order order = orderManager.checkout(orderId);
		// print receipt
		System.out.println(order);		
	}
	
	public void demoCase3() {
		// prepare all needed goods
		long perfumeId = catalogManager.addItem("imported bottle of perfume", new BigDecimal("27.99"), ProductCategory.PERFUME, true);
		long anotherPerfumeId = catalogManager.addItem("bottle of perfume", new BigDecimal("18.99"), ProductCategory.PERFUME, false);
		long pillsId = catalogManager.addItem("packet of headache pills", new BigDecimal("9.75"), ProductCategory.MEDICINE, false);
		long chocolateId = catalogManager.addItem("imported box of chocolates", new BigDecimal("11.25"), ProductCategory.FOOD, true);		
		// order these goods
		long orderId = orderManager.createOrder();
		orderManager.addItem(orderId, perfumeId, 1);
		orderManager.addItem(orderId, anotherPerfumeId, 1);
		orderManager.addItem(orderId, pillsId, 1);
		orderManager.addItem(orderId, chocolateId, 1);
		Order order = orderManager.checkout(orderId);
		// print receipt
		System.out.println(order);
	}	

	public static void main(String[] args) {
		// create services and wire them
		TaxManagerImpl taxManagerImpl = new TaxManagerImpl();
		TrivialCatalogImpl catalogImpl = new TrivialCatalogImpl();
		TrivialOrderManagerImpl orderManagerImpl = new TrivialOrderManagerImpl();
		orderManagerImpl.setTaxManager(taxManagerImpl);
		orderManagerImpl.setCatalog(catalogImpl);
		// create demo
		TaxesDemo demo = new TaxesDemo();
		demo.setCatalogManager(catalogImpl);
		demo.setOrderManager(orderManagerImpl);
		// run demo cases
		demo.demoCase1();
		demo.demoCase2();
		demo.demoCase3();
	}

}

根据main程序的流程,我们可以总结出以下的工作流程:

面向对象编程经典例题 --- 收银系统设计_第6张图片

你可能感兴趣的:(IT技术)