一、题目分析
同学们应该都去麦当劳或肯德基吃过快餐吧?请同学们参考肯德基官网的信息模拟肯德基快餐店的收银系统,合理使用C++或Java或Python结合设计模式(2种以上)至少实现系统的以下功能:
1.正常餐品结算和找零。
2.基本套餐结算和找零。
3.使用优惠劵购买餐品结算和找零。
4.可在一定时间段参与店内活动(自行设计或参考官网信息)。
5.模拟打印小票的功能(写到文件中)。
经过分析可以知道,该收银系统需要设计的有商品展示,顾客选择商品,商品价格的计算,发票的打印四个功能。其中对顾客选择商品中又可以详细设计,可以利用多种设计模式,例如对商品的产生可以用到工厂模式,对付款方式的优惠可以选择策略模式,对于商品又可以选择装饰模式等。综上所述,我决定用到三个模式分别是简单工厂模式、策略模式、装饰模式。
二、算法设计思路
1、简单工厂模式的设计
本系统中需要用到简单工厂模式来设计商品,
抽象商品接口
/*接口,一个抽象的商品*/
public interface Product {
public String show_food();//抽象方法,返回商品的名称
public double price();//抽象方法,返回商品的价格
}
然后分别是具体商品的生成
/*商品的实现类,生产出一个汉堡*/
public class Burger implements Product{
private double burgerprice=6;//汉堡的价格
public String show_food() {
return "一个汉堡";
}
public double price() {
return burgerprice;//返回汉堡的价格
}
}
/*商品的实现类,生产出一杯可乐*/
public class Cola implements Product{
private double colaprice=5;//可乐的价格
public String show_food() {
return "一杯可乐";
}
public double price() {
return colaprice;//返回可乐的价格
}
}
/*商品的实现类,生产出一份薯条*/
public class FrenchFries implements Product{
private double frenchfries=3;//薯条的价格
public String show_food() {
return "一份薯条";
}
public double price() {
return frenchfries;//返回商品价格
}
}
套餐同样设计为实现Product接口
/*商品的实现类,套餐*/
public class SetMeal implements Product{
private static double setmeal1_price;
/*套餐价格的计算方法*/
public double price()
{
final double discount_lable=0.85;//折扣标签,套餐相比于单买优惠的折扣
setmeal1_price=(new Burger().price()+new Cola().price()
+new FrenchFries().price())*discount_lable;
return setmeal1_price;
}
/*返回套餐的内容*/
public String show_food() {
Product product1=new Burger();
System.out.println(product1.show_food());
product1=new Cola();
System.out.println(product1.show_food());
product1=new FrenchFries();
System.out.println(product1.show_food());
return "套餐1";
}
}
对于商品的具体调用实现则在Order类中实现。
2、装饰模式的设计
装饰模式主要是用来对商品进行附加其他的属性,因此装饰模式基于商品进行设计。
设计的抽象的装饰接口继承抽象商品的接口,这样在生成具体商品时产生的就是Product的示例,可以直接进行返回。
/*接口,一个抽象装饰物*/
public interface Decorate extends Product{
public String show_food();
}
/*实现装饰接口,在原有商品的基础上再加上鸡蛋*/
public class Eggs implements Decorate{
private Product product;
public Eggs(Product product) {
this.product = product;
}
装饰接口的实现
/*返回装饰的商品名*/
public String show_food() {
return product.show_food() + "加, 鸡蛋";
}
public double price() {
return product.price() + 2;//返回装饰后的商品价格
}
}
同样的用Ham 和Tomato实现装饰接口,其中的函数设计也与Eggs中的函数相似。
public class Ham implements Decorate{}
public class Tomato implements Decorate{}
对于装饰商品的具体调实现同样放在Order类中
3、策略模式的设计
策略模式设计同样用到策略接口,然后使用具体的策略实现接口
/*接口,抽象的策略*/
public interface DiscountMode {
public double discount(double price);//抽象方法,实现具体的优惠价格计算
public String show_discount_name() ;//抽象方法,用来返回使用的优惠名
}
策略接口的实现
/*折扣方式的实现,使用优惠卷的方式*/
public class Coupon implements DiscountMode{
public String show_discount_name() {
return "优惠方式:使用优惠卷";
}
/*使用优惠卷的方法,为满30减5的优惠*/
public double discount(double price) {
if (price>=30) {
price-=5;
System.out.println("您使用了满30减5的优惠卷");}
else return price;
return price;
}
}
策略接口的实现
/*折扣方式的实现,使用开通vip的方式*/
public class VIP implements DiscountMode{
public String show_discount_name() {
return "优惠方式:VIP";
}
/*使用vip的方法*/
public double discount(double price) {
return price*0.88;
}
}
策略接口的实现
public class Activity implements DiscountMode {
public String show_discount_name() {
return "88折日";
}
/*计算活动后的价格,为满88折的优惠*/
public double discount(double price) {
Date date=new Date();
DateFormat fullFormat=DateFormat.getDateInstance(DateFormat.FULL);
System.out.println("今天是:"+fullFormat.format(date));
int date_=date.getDay();
if (date_==8||date_==18||date_==28) {
System.out.println("今天为88折日(每月的第8、18、28天),你可以享受88折优惠");
return price*0.88;}
else {
System.out.println("今天不是88折日(每月的第8、18、28天),你不能享受88折优惠");
return price;
}
}
}
对于策略模式的具体调用实现放在客户端类中对于价格的计算。
4、文件读写类的设计
文件读写主要设计为对订单信息的写入和读取
import java.io.*;
/*文件读写类*/
public class WriteData {
private File f;
/*新建文件*/
public WriteData() {
f = new File("发票.txt");
}
/*将数据写入文件*/
public void wrtiedata_to_txt(String data,String data1,double data2,double data3) {
FileWriter fw = null;
//File f = new File("发票.txt");
try {
if(!f.exists()){
f.createNewFile();
}
fw = new FileWriter(f);
BufferedWriter out = new BufferedWriter(fw);
/*格式化写入订单信息*/
out.write("订单:"+"\r\n");
out.write(data, 0, data.length());
out.write("\r\n");
out.append(data1+"\r\n");
out.append("收您"+data2+"元"+"\r\n");
out.append("找您"+data3+"元"+"\r\n");
out.close();
} catch (IOException e) {
e.printStackTrace();
}
}
/*从文件中读取数据*/
public String readdata() {
StringBuilder result = new StringBuilder();
try{
BufferedReader br = new BufferedReader(new FileReader(f));//构造一个BufferedReader类来读取文件
String s = null;
while((s = br.readLine())!=null){//使用readLine方法,一次读一行
result.append(System.lineSeparator()+s);
}
br.close();
}catch(Exception e){
e.printStackTrace();
}
return result.toString();
}
}
三、UML类图
1、简单工厂模式
2、装饰模式
3、策略模式
四、调试及测试截屏
五、总结
通过这次对kfc收银台的设计,我用到了三种设计模式,这三种设计模式也是非常的有用,通过抽象的接口可以实现多种商品,多种选择方式,多种付款方式,相比于以前设计的程序大大减轻了单个类以及函数的负担,使得程序更加简洁明了,但这种方法的缺点是设计了大量的类,每个类之间的关系也比较紧密,如果一个关键类出错,将会影响很多类的结果,因此,对于程序的设计也应该考虑到这点。其次是通过这种设计的练习提高了我的程序设计思路,以前对于程序的设计都是希望通过一个类来完成所有的功能,因此一个类中设计了很多函数,通过设计模式的运用可以使自己的更加标准,更加的符合面向对象的设计思路。