KFC实验报告
一.题目要求
同学们应该都去麦当劳或肯德基吃过快餐吧?请同学们参考肯德基官网的信息模拟肯德基快餐店的收银系统,合理使用C++或Java或Python结合设计模式(2种以上)至少实现系统的以下功能:
1.正常餐品结算和找零。
2.基本套餐结算和找零。
3.使用优惠劵购买餐品结算和找零。
4.可在一定时间段参与店内活动(自行设计或参考官网信息)。
5.模拟打印小票的功能(写到文件中)。
基本要求:
1.程序设计风格良好,控制台界面友好,最多两人一组完成任务。
2.实现功能测试代码,确保程序的健壮性。
3.画出使用的设计模式图。
二.问题分析
2.1 题目分析
(1)实验需要选择两种以上的设计模式来完成KFC的收银系统,故本实验选择了工厂方法设计模式和抽象工厂设计模式。
在工厂方法模式中,工厂父类负责定义创建产品对象的公共接口,而工厂子类则负责生成具体的产品对象,这样做的目的是将产品类的实例化操作延迟到工厂子类中完成,即通过工厂子类来确定究竟应该实例化哪一个具体产品类。本实验中的汉堡工厂、饮品工厂、甜品工厂和配餐工厂均实现了餐品基类的接口,这样在完全符合“开闭原则”,实现了可扩展性。
抽象工厂模式提供了一个接口,用于创建相关或者依赖对象的家族,而不需要指定具体实现类。抽象工厂模式允许客户使用抽象接口来创建一组相关的产品,客户类和工厂类分开,客户需要任何产品的时候,只需要向工厂请求即可,客户无须修改就可以获得新产品。通过抽象工厂来实现,把所有的实物都抽象成一个类,且每一个食物都由一个基类派生而来,每一种类型的食物均有一个食物工厂来实现,(例如香辣鸡腿堡、奥尔良堡以及劲脆鸡腿堡等汉堡有汉堡类工厂生产;各种饮品由饮品工厂实现;各种甜品由甜品工厂生产;套餐由配餐工厂实现。) 这样在增加新的食物时就不需要修改太多程序。
(2)本实验需要将点餐信息写入文件中去,即实现打印小票的功能。本实验利用了Java的文件输入输出流FileOutputStream将顾客点餐信息保存在文件中去。
2.2 模块设计
主要模块设计如下:
(1)实现类text1实现如下:(实现顾客点餐和文件保存)
package KFC;
import java.io.File;
import java.io.FileOutputStream;
import java.io.PrintStream;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Scanner;
public class text1 {
public static void main(String[] args) {
// TODO Auto-generated method stub
System.out.println("您好,欢迎光临!\n");
//获取当前系统时间
SimpleDateFormat df=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
//调用优惠日
String strday=df.format(new Date());
System.out.println("请选择1.单点 2.生成套餐:");
Scanner scanner=new Scanner(System.in);
int num=scanner.nextInt();
//选择生成套餐
if (num==2) {
//director dir=new director();
System.out.println("正在为您生成套餐,请稍等...\n");
//延时1.5秒
try {
Thread.currentThread().sleep(1500);
} catch (Exception e) {
// TODO: handle exception
}
Director director1=new Director();
System.out.println("本店提供的套餐如下:");
FoodPackage taocanFactory1 = director1.getfoodfactory1();
System.out.println("套餐一:");
System.out.println(taocanFactory1.getkind());
System.out.println("价格:"+taocanFactory1.getPrice());
//生产套餐二
FoodPackage taocanFactory2 = director1.getfoodfactory2();
System.out.println("套餐二:");
System.out.println(taocanFactory2.getkind());
System.out.println("价格:"+taocanFactory2.getPrice());
System.out.println("请您选择套餐:1:套餐一 2:套餐二");
int number = scanner.nextInt();
if( number == 1) {
System.out.println("------------------账单------------------");
interfaceKFCfactory akfcFoctory = new KFCfactory();
//创建顾客对象
customer customer1 = new customer(akfcFoctory);
//顾客点餐
//汉堡
double hamburgCost = customer1.orderhamburg(1,1);
//饮品
double drinkCost=customer1.orderdrink(1, 1);
//甜品
double dessertCost=customer1.orderdessert(2,1);
//配餐
double food_matchingCost=customer1.orderFood_matching(1, 1);
System.out.println(taocanFactory1.getkind());
System.out.println("价格:"+taocanFactory1.getPrice()+"\t 数量:"+taocanFactory1.getnumber());
System.out.println("累计消费:"+(hamburgCost+drinkCost+dessertCost+food_matchingCost+taocanFactory1.getPrice())+"元");
System.out.println("----------------------------------------");
System.out.println("用户支付金额:");
int money = scanner.nextInt();
System.out.println("找零钱"+(money-(hamburgCost+drinkCost+dessertCost+food_matchingCost+taocanFactory1.getPrice()))+"元");
try {
//写文件
File file=new File("D:\\eclipse\\KFC\\src\\KFC\\tips.txt");
if (file.exists()==false) {
file.getParentFile().mkdirs();
}
// 创建基于文件的输出流
PrintStream ps = new PrintStream(new FileOutputStream(file));
// 把数据写入到输出流
ps.println(" 账单 ");
ps.println(" 餐品:"+taocanFactory1.getkind());
ps.println(" 累计消费:"+taocanFactory1.getPrice()+"元");
ps.println();
ps.println(" 用户支付金额:"+money+"元");
ps.println(" 找零钱:"+(money-(hamburgCost+drinkCost+dessertCost+food_matchingCost+taocanFactory1.getPrice()))+"元");
ps.println();
ps.println(" 祝您用餐愉快,欢迎下次光临!");
ps.println("-----------------------");
ps.println();
// 关闭输出流
ps.close();
} catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
}
}
if(number==2) {
System.out.println("------------------账单------------------");
interfaceKFCfactory akfcFoctory = new KFCfactory();
//创建顾客对象
customer customer1 = new customer(akfcFoctory);
//顾客点餐
//汉堡
double hamburgCost = customer1.orderhamburg(2,1);
//饮品
double drinkCost=customer1.orderdrink(3, 1);
//甜品
double dessertCost=customer1.orderdessert(3,1);
//配餐
double food_matchingCost=customer1.orderFood_matching(2, 1);
System.out.println(taocanFactory2.getkind());
System.out.println("价格:"+taocanFactory2.getPrice()+"\t 数量:"+taocanFactory2.getnumber());
System.out.println("累计消费:"+(hamburgCost+drinkCost+dessertCost+food_matchingCost+taocanFactory2.getPrice())+"元");
System.out.println("----------------------------------------");
System.out.println("用户支付金额:");
int money = scanner.nextInt();
System.out.println("找零钱"+(money-(hamburgCost+drinkCost+dessertCost+food_matchingCost+taocanFactory2.getPrice()))+"元");
try {
//写文件
File file=new File("D:\\eclipse\\KFC\\src\\KFC\\tips.txt");
if (file.exists()==false) {
file.getParentFile().mkdirs();
}
// 创建基于文件的输出流
PrintStream ps = new PrintStream(new FileOutputStream(file));
// 把数据写入到输出流
ps.println(" 账单 ");
ps.print(" 餐品:"+taocanFactory2.getkind());
ps.println(" 累计消费:"+taocanFactory2.getPrice()+"元");
ps.println();
ps.println(" 用户支付金额:"+money+"元");
ps.println(" 找零钱:"+(money-(hamburgCost+drinkCost+dessertCost+food_matchingCost+taocanFactory2.getPrice()))+"元");
ps.println();
ps.println(" 祝您用餐愉快,欢迎下次光临!");
ps.println("-----------------------");
ps.println();
// 关闭输出流
ps.close();
} catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
}
}
}
else {
//生成
choose choose1=new choose();
}
}
}
(2)餐品基类设计如下(创建餐品基类和餐品接口)
package KFC;
//定义产品基类
abstract class abstractFood {
//定义餐品价格
protected double price;
//定义餐品数量
protected int number;
//定义餐品种类
protected String kind;
//计算消费金额
public double Price() {
return this.price*this.number;
}
}
package KFC;
public interface interfaceFood {
//打印消费信息
public void printConsumptionMassage();
}
(3)定义各个食物基类(汉堡基类、饮品基类、甜品基类和配餐基类,因为各个基类创建类似,所以只列出汉堡基类)
package KFC;
//定义汉堡基类
abstract class hamburg extends abstractFood implements interfaceFood{
public void printConsumptionMassage() {
System.out.println(this.kind+"汉堡:\n"+"单价:"+this.price+"\n"+"数量:"+this.number+"\n");
}
}
(4)定义具体餐品类(因为各个具体餐品类创建类似,所以只列出汉堡类具体餐品的创建)
package KFC;
public class Orlean_roast_Castle extends hamburg{
public Orlean_roast_Castle(int number) {
this.kind="奥尔良烤堡";
this.price=35.0;
this.number=number;
}
}
public class Extra_Tasty_Crispy_Burger extends hamburg{
public Extra_Tasty_Crispy_Burger(int number) {
this.kind="劲脆鸡腿堡";
this.price=32.0;
this.number=number;
}
}
public class Zinger_burger extends hamburg{
public Zinger_burger(int number) {
this.kind="香辣鸡腿堡";
this.price=29.0;
this.number=number;
}
}
(5)抽象工厂基类
package KFC;
public interface interfaceKFCfactory {
//生产汉堡
public Zinger_burger createZinger_burgee(int number);
public Orlean_roast_Castle createOrlean_roast_Castle(int number);
public Extra_Tasty_Crispy_Burger createExtra_Tasty_Crispy_Burger(int number);
//生产饮品
public Pepsi_Cola createPepsi_Cola(int number);
public Hot_lemon_black_tea createHot_lemon_black_tea(int number);
public Classic_coffee createClassic_coffee(int number);
//生产甜品
public Strawberry_sundae createStrawberry_sundae(int number);
public Portuguese_Egg_Tart createPortuguese_Egg_Tart(int number);
public Red_bean_pie createRed_bean_pie(int number);
//生产配餐
public Popcorn_Chicken createPopcorn_Chicken(int number);
public Golden_Chicken_block createGolden_Chicken_block(int number);
public Orlean_roasted_wings createOrlean_roasted_wings(int number);
}
(6)生产工厂实现抽象工厂基类接口
package KFC;
public class KFCfactory implements interfaceKFCfactory {
//生产汉堡
public Zinger_burger createZinger_burgee(int number){
return new Zinger_burger(number);
}
public Orlean_roast_Castle createOrlean_roast_Castle(int number) {
return new Orlean_roast_Castle(number);
}
public Extra_Tasty_Crispy_Burger createExtra_Tasty_Crispy_Burger(int number) {
return new Extra_Tasty_Crispy_Burger(number);
}
//生产饮品
public Pepsi_Cola createPepsi_Cola(int number) {
return new Pepsi_Cola(number);
}
public Hot_lemon_black_tea createHot_lemon_black_tea(int number) {
return new Hot_lemon_black_tea(number);
}
public Classic_coffee createClassic_coffee(int number) {
return new Classic_coffee(number);
}
//生产甜品
public Strawberry_sundae createStrawberry_sundae(int number) {
return new Strawberry_sundae(number);
}
(7)顾客类(实现点餐)
package KFC;
public class customer {
//定义抽象工厂变量
private interfaceKFCfactory kfcfactory;
//定义顾客类构造函数
public customer(interfaceKFCfactory kfCfactory) {
//一个顾客对应一个抽象工厂
this.kfcfactory=kfCfactory;
}
//选购餐品
//购买汉堡
public double orderhamburg(int hamburgkind,int number) {
hamburg hamburge1;
//获得汉堡种类
switch (hamburgkind) {
case 1:hamburge1=kfcfactory.createZinger_burgee(number);
break;
case 2:hamburge1=kfcfactory.createOrlean_roast_Castle(number);
break;
default:hamburge1=kfcfactory.createExtra_Tasty_Crispy_Burger(number);
break;
}
//打印购买信息
hamburge1.printConsumptionMassage();
//返回消费情况
return hamburge1.Price();
}
//购买饮品
public double orderdrink(int dringkkind,int number) {
drink drink1;
//获得饮品种类
switch (dringkkind) {
case 1:drink1=kfcfactory.createPepsi_Cola(number);
break;
case 2:drink1=kfcfactory.createHot_lemon_black_tea(number);
break;
default:drink1=kfcfactory.createClassic_coffee(number);
break;
}
//打印购买信息
drink1.printConsumptionMassage();
//返回消费信息
return drink1.Price();
}
//购买甜品
public double orderdessert(int dessertkind,int number) {
dessert dessert1;
//获得饮品种类
switch (dessertkind) {
case 1:dessert1=kfcfactory.createStrawberry_sundae(number);
break;
case 2:dessert1=kfcfactory.createPortuguese_Egg_Tart(number);
break;
default:dessert1=kfcfactory.createRed_bean_pie(number);
break;
}
//打印购买信息
dessert1.printConsumptionMassage();
//返回消费信息
return dessert1.Price();
}
//购买配餐
public double orderFood_matching(int Food_matchingkind,int number) {
Food_matching food_matching;
//获得配餐种类
switch (Food_matchingkind) {
case 1:food_matching=kfcfactory.createPopcorn_Chicken(number);
break;
case 2:food_matching=kfcfactory.createGolden_Chicken_block(number);
break;
default:food_matching=kfcfactory.createOrlean_roasted_wings(number);
break;
}
//打印购买信息
food_matching.printConsumptionMassage();
//返回消费信息
return food_matching.Price();
}
}
(8)套餐基类(生成套餐1和套餐2)
package KFC;
abstract class kfcbuilder {
//定义套餐对象
protected final FoodPackage foodPackage = new FoodPackage();
//制定套餐种类
public void setkind(String kind) {
this.foodPackage.setkind(kind);
}
//制定套餐数量
public void setnumber(int number) {
this.foodPackage.setnumber(number);
}
//制定套餐价格
public void setprice(double price) {
this.foodPackage.setprice(price);
}
//制定套餐
public abstract FoodPackage setFoodpackage();
}
public class Set_meal1 extends kfcbuilder{
//生成餐品
@Override
public FoodPackage setFoodpackage() {
//重载
super.foodPackage.setkind("香辣鸡腿堡、百事可乐、葡式蛋挞、劲爆鸡米花");
super.foodPackage.setnumber(1);
super.foodPackage.setprice(61.0);
return super.foodPackage;
}
}
public class Set_meal2 extends kfcbuilder{
//生成餐品
@Override
public FoodPackage setFoodpackage() {
//重载
super.foodPackage.setkind("奥尔良烤堡、经典咖啡、红豆派、黄金鸡块");
super.foodPackage.setnumber(1);
super.foodPackage.setprice(69.0);
return super.foodPackage;
}
}
(9)顾客点餐
package KFC;
import java.io.File;
import java.io.FileOutputStream;
import java.io.PrintStream;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Scanner;
class choose {
interfaceKFCfactory akfcFoctory = new KFCfactory();
//创建顾客对象
customer customer1 = new customer(akfcFoctory);
//顾客点餐
//汉堡
double[] hamburgCost=new double[3];
//饮品
double[] drinkCost=new double[3] ;
//甜品
double[] dessertCost=new double[3];
//配餐
double[] food_matchingCost=new double[3];
//消费
double sum;
//餐品名称
String string="";
public choose() {
// TODO Auto-generated constructor stub
menu1();
fun();
}
private void menu1() {
System.out.println(" 汉堡 ");
System.out.println(" 1.香辣鸡腿堡 ");
System.out.println(" 2.奥尔良烤堡 ");
System.out.println(" 3.劲脆鸡腿堡 ");
System.out.println(" 饮品 ");
System.out.println(" 4.百事可乐 ");
System.out.println(" 5.热柠檬红茶 ");
System.out.println(" 6.经典咖啡 ");
System.out.println(" 甜品 ");
System.out.println(" 7.草莓圣代 ");
System.out.println(" 8.葡式蛋挞 ");
System.out.println(" 9.红豆派 ");
System.out.println(" 配餐 ");
System.out.println(" 10.劲爆鸡米花 ");
System.out.println(" 11.黄金鸡块 ");
System.out.println(" 12.奥尔良烤翅 ");
System.out.println(" 13.点餐完成 ");
}
//点餐
public void fun() {
System.out.println("请点餐:");
Scanner scanner=new Scanner(System.in);
int kind=scanner.nextInt();
switch (kind) {
case 1:{
System.out.println("请输入数量:");
int num=scanner.nextInt();
hamburgCost[0]=customer1.orderhamburg(1, num);
string+="香辣鸡腿堡 ";
sum+=29.0;
fun();
}
break;
case 2:{
System.out.println("请输入数量:");
int num=scanner.nextInt();
hamburgCost[1]=customer1.orderhamburg(2, num);
string+="奥尔良烤堡 ";
sum+=35.0;
fun();
}
break;
case 3:{
System.out.println("请输入数量:");
int num=scanner.nextInt();
hamburgCost[2]=customer1.orderhamburg(3, num);
string+="劲脆鸡腿堡 ";
sum+=32.0;
fun();
}
break;
case 4:{
System.out.println("请输入数量:");
int num=scanner.nextInt();
drinkCost[0]=customer1.orderdessert(1, num);
string+="百事可乐 ";
sum+=12.0;
fun();
}
break;
case 5:{
System.out.println("请输入数量:");
int num=scanner.nextInt();
drinkCost[1]=customer1.orderdessert(2, num);
string+="热柠檬红茶 ";
sum+=11.0;
fun();
}
break;
case 6:{
System.out.println("请输入数量:");
int num=scanner.nextInt();
drinkCost[2]=customer1.orderdessert(3, num);
string+="经典咖啡 ";
sum+=10.0;
fun();
}
break;
case 7:{
System.out.println("请输入数量:");
int num=scanner.nextInt();
dessertCost[0]=customer1.orderdessert(1, num);
string+="草莓圣代 ";
sum+=11.0;
fun();
}
break;
case 8:{
System.out.println("请输入数量:");
int num=scanner.nextInt();
dessertCost[1]=customer1.orderdessert(2, num);
string+="葡式蛋挞 ";
sum+=7.0;
fun();
}
break;
case 9:{
System.out.println("请输入数量:");
int num=scanner.nextInt();
dessertCost[2]=customer1.orderdessert(3, num);
string+="红豆派 ";
sum+=6.0;
fun();
}
break;
case 10:{
System.out.println("请输入数量:");
int num=scanner.nextInt();
food_matchingCost[0]=customer1.orderFood_matching(1, num);
string+="劲爆鸡米花 ";
sum+=13.0;
fun();
}
break;
case 11:{
System.out.println("请输入数量:");
int num=scanner.nextInt();
food_matchingCost[1]=customer1.orderFood_matching(2, num);
string+="黄金鸡块 ";
sum+=18.0;
fun();
}
break;
case 12:{
System.out.println("请输入数量:");
int num=scanner.nextInt();
food_matchingCost[2]=customer1.orderFood_matching(3, num);
string+="奥尔良烤翅 ";
sum+=11.0;
fun();
}
break;
default:break;
}
System.out.println("累计消费:"+sum+"元");
System.out.println("----------------------------------------");
System.out.println("用户支付金额:");
int money = scanner.nextInt();
System.out.println("找零钱"+(money-sum)+"元");
try {
//写文件
File file=new File("D:\\eclipse\\KFC\\src\\KFC\\tips.txt");
if (file.exists()==false) {
file.getParentFile().mkdirs();
}
// 创建基于文件的输出流
PrintStream ps = new PrintStream(new FileOutputStream(file));
// 把数据写入到输出流
ps.println(" 账单 ");
ps.println(" 餐品:"+string);
ps.println(" 累计消费:"+sum+"元");
ps.println();
ps.println(" 用户支付金额:"+money+"元");
ps.println(" 找零钱:"+(money-sum)+"元");
ps.println();
ps.println(" 祝您用餐愉快,欢迎下次光临!");
ps.println("-----------------------");
ps.println();
// 关闭输出流
ps.close();
} catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
}
}
}
}
三.UML类图
注(由于类图过大,放在word中太小,看不清楚,所以在文件夹中放有一份绘图1.vsdx,可以点击该绘图查看清晰版类图)
四.调试及测试截图
(1)开始界面,选择单点或者套餐
(2)选择1,则进行单点操作,打印所有菜品
(3)输入菜单编号进行点餐,并输入该菜品个数
(3)按照菜单提示,输入13,则点餐结束,输出累计消费,并实现找零
(4)成功将点餐信息保存在文件中
(5)选择套餐
五.个人总结
(1)通过此次章节实现,让我对设计模式有了进一步的了解,针对不同的场景,选择合适的设计模式,提高设计效率,增强程序的可维护性与易修改性。
(2)让我对Java文件输入输出流有了更加深入的了解,通过文件输出流来实现文件信息的写入操作。
(3)让我对Java接口以及实现类以及基类与子类之间的继承关系有了更加深入的认识。
(4)通过uml类图的绘制,能更加熟练地进行类图的绘制。对接口类、聚合、依赖关系有了更加清楚的认识。
参考资料:https://blog.youkuaiyun.com/leying521/article/details/85234096
https://blog.youkuaiyun.com/Vchen_hao/article/details/54922736