一、题目分析
题目:
同学们应该都去麦当劳或肯德基吃过快餐吧?请同学们参考肯德基官网的信息模拟肯德基快餐店的收银系统,合理使用C++或Java或Python结合设计模式(2种以上)至少实现系统的以下功能:
1.正常餐品结算和找零。
2.基本套餐结算和找零。
3.使用优惠劵购买餐品结算和找零。
4.可在一定时间段参与店内活动(自行设计或参考官网信息)。
5.模拟打印小票的功能(写到文件中)。
基本要求:
1.程序设计风格良好,控制台界面友好,最多两人一组完成任务。
2.实现功能测试代码,确保程序的健壮性。
3.画出使用的设计模式图。
提高要求:
1.实现可视化界面(使用MFC)。
2.实现会员储值卡功能,完成储值卡消费。
3.实现当天营业额和餐品销量计算和统计,用数据库记录
分析:
开闭原则:一个软件实体应当对扩展开放,对修改关闭
依赖倒转原则:代码要依赖于抽象的类,而不依赖于具体的类
为了使程序在设计实现过程中更加符合“开闭原则”和“依赖倒转原则”,我们需要针对接口和更加抽象的类编程。
●适配器模式——生产具体餐品
适配器模式(Adapter Pattern)是作为两个不兼容的接口之间的桥梁。这种类型的设计模式属于结构型模式,它结合了两个独立接口的功能。
对于该题目可以分析发现,每一种餐品都需要实现打印输出的功能,并且它们都具有名字、单价、数量等静态的特点。根据特点我们首先设计一个单品接口(interface SingleFood)其中具有一个打印输出的抽象方法,再设计一个抽象类(abstract class FoodID)其中定义了餐品属性。
对于每一类餐品都定义一个抽象类,让该类继承abstract class FoodID实现interface SingleFood(如Hamburger类、Snack类、Drink类、Rice类、SetFood类)
每一个具体餐品都继承对应的餐品抽象类。
●抽象工厂模式——点餐
将KFC工厂抽象化,创建KFC工厂接口(interface KFC_Factory)——该接口中有生产各类餐品的抽象方法(createHamburger()、createSnack()、createDrink()、createRice()、createSetFood()),点餐时只需实例化一个该类型的工厂,调用其中的方法就可以实现点餐功能。
实例KFC工厂(class CKFC_Factory)——生产具体的食物
创建职员类(class Clerk)——通过其中的成员方法实现点餐功能(orderHamburger()、orderSnack()、orderDrink()、orderRice()、orderSetFood())
设计菜单如下:
——————————单品菜单———————
-------------------一、汉堡类 ------------------
1、柚香鸡腿堡-------------------------------19元
2、芝士培根澳牛堡----------------------------25元
3、牛油果香辣鸡腿堡--------------------------17元
—————————————————————
-------------------二、小食类 -----------------
1、香辣黄金鸡柳----------------------------9.9元
2、小鲜肉酥饼------------------------------- 8元
3、上校鸡块----------------------------------7元
—————————————————————
-------------------三、饮品类------------------
1、桃之恋乌龙茶---------------------------13.5元
2、葡萄柚鲜果莫吉托-------------------------14元
—————————————————————
-------------------四、主食类------------------
1、新奥尔良烤鸡腿饭-----------------------19.5元
2、培根蘑菇鸡柳饭---------------------------20元
—————————————————————
————————套餐菜单———————————
1、套餐A:柚香鸡腿堡+桃之恋乌龙茶------------32元
2、套餐B:培根蘑菇鸡柳饭+葡萄柚鲜果莫吉托-----33元
3、套餐C:芝士培根澳牛堡+桃之恋乌龙茶---------38元
————————————————————————
二、UML类图设计
适配器模式:
抽象工厂模式:
三、源代码
package pack1;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Scanner;
import java.io.FileOutputStream;
import java.io.PrintStream;
import java.io.FileNotFoundException;
// 单品接口
interface SingleFood{
public String outPut(); // 单品接口的抽象方法,用来打印输出单品食物的信息
}
// 保存食物信息的抽象类
abstract class FoodID{
public String FoodName; // 食物名称
public double price; // 食物单价
public int num; // 顾客购买该食物的数量
// 计算该餐品的总价
public double totalPrice() {
return price*num;
}
}
// 抽象父类Hamburger
abstract class Hamburger extends FoodID implements SingleFood{
public String outPut() {
return ("--"+this.FoodName+"\t单价:"+this.price+"\t数量:"+this.num+"\t总价:"+this.totalPrice()+"元");
}
}
// 子类柚香鸡腿堡继承抽象父类Hamburger
class Hamburger_1 extends Hamburger{
public Hamburger_1(int num) {
this.FoodName = "柚香鸡腿堡";
this.price = 19;
this.num = num;
}
}
// 子类芝士培根澳牛堡继承抽象父类Hamburger
class Hamburger_2 extends Hamburger{
public Hamburger_2(int num) {
this.FoodName = "芝士培根澳牛堡";
this.price = 25;
this.num = num;
}
}
// 子类牛油果香辣鸡腿堡继承抽象父类Hamburger
class Hamburger_3 extends Hamburger{
public Hamburger_3(int num) {
this.FoodName = "牛油果香辣鸡腿堡";
this.price = 17;
this.num = num;
}
}
// 抽象父类Snack(小食类)
abstract class Snack extends FoodID implements SingleFood{
public String outPut() {
return ("--"+this.FoodName+"\t单价:"+this.price+"\t数量:"+this.num+"\t总价:"+this.totalPrice()+"元");
}
}
// 子类香辣黄金鸡柳继承抽象父类Snack
class Snack_1 extends Snack{
public Snack_1(int num) {
this.FoodName = "香辣黄金鸡柳";
this.price = 9.9;
this.num = num;
}
}
// 子类小鲜肉酥饼继承抽象父类Snack
class Snack_2 extends Snack{
public Snack_2(int num) {
this.FoodName = "小鲜肉酥饼";
this.price = 8;
this.num = num;
}
}
// 子类上校鸡块继承抽象父类Snack
class Snack_3 extends Snack{
public Snack_3(int num) {
this.FoodName = "上校鸡块";
this.price = 7;
this.num = num;
}
}
// 抽象父类Drink
abstract class Drink extends FoodID implements SingleFood{
public String outPut() {
return ("--"+this.FoodName+"\t单格:"+this.price+"\t数量:"+this.num+"\t总价:"+this.totalPrice()+"元");
}
}
// 子类桃之恋乌龙茶继承抽象父类Drink
class Drink_1 extends Drink{
public Drink_1(int num) {
this.FoodName = "桃之恋乌龙茶";
this.price = 13.5;
this.num = num;
}
}
// 子类葡萄柚鲜果莫吉托继承抽象父类Drink
class Drink_2 extends Drink{
public Drink_2(int num) {
this.FoodName = "葡萄柚鲜果莫吉托";
this.price = 14;
this.num = num;
}
}
// 抽象类Rice
abstract class Rice extends FoodID implements SingleFood{
public String outPut() {
return ("--"+this.FoodName+"\t单格:"+this.price+"\t数量:"+this.num+"\t总价:"+this.totalPrice()+"元");
}
}
// 子类新奥尔良烤鸡腿饭继承抽象父类Rice
class Rice_1 extends Rice{
public Rice_1(int num) {
this.FoodName = "新奥尔良烤鸡腿饭";
this.price = 19.5;
this.num = num;
}
}
// 子类培根蘑菇鸡柳饭继承抽象父类Rice
class Rice_2 extends Rice{
public Rice_2(int num) {
this.FoodName = "培根蘑菇鸡柳饭";
this.price = 20;
this.num = num;
}
}
// 抽象套餐类
abstract class SetFood extends FoodID implements SingleFood{
public String outPut() {
return ("--"+this.FoodName+"\t单价:"+this.price+"\t数量:"+this.num+"\t总价:"+this.totalPrice()+"元");
}
}
// 子类套餐A继承父类抽象套餐
class SetFoodA extends SetFood{
public SetFoodA(int num) {
this.FoodName = "套餐A";
this.price = 32;
this.num = num;
}
}
// 子类套餐B继承父类抽象套餐
class SetFoodB extends SetFood{
public SetFoodB(int num) {
this.FoodName = "套餐B";
this.price = 33;
this.num = num;
}
}
// 子类套餐C继承父类抽象套餐
class SetFoodC extends SetFood{
public SetFoodC(int num) {
this.FoodName = "套餐C";
this.price = 38;
this.num = num;
}
}
// 创建KFC工厂接口,生产抽象食物
interface KFC_Factory{
public Hamburger createHamburger(int kind, int num); // 生产抽象汉堡
public Snack createSnack(int kind, int num); // 生产抽象小食
public Drink createDrink(int kind, int num); // 生产抽象饮品
public Rice createRice(int kind, int num); // 生产抽象主食
public SetFood createSetFood(int kind, int num); // 生产抽象套餐
}
// 创建具体工厂类实现KFC工厂接口,生产具体食物
class CKFC_Factory implements KFC_Factory{
// 生产具体汉堡
public Hamburger createHamburger(int kind, int num) {
switch(kind)
{
case 1: // 柚香鸡腿堡
return new Hamburger_1(num);
case 2: // 芝士培根澳牛堡
return new Hamburger_2(num);
case 3: // 牛油果香辣鸡腿堡
return new Hamburger_3(num);
default:
return null;
}
}
// 生产具体小食
public Snack createSnack(int kind, int num) {
switch(kind)
{
case 1: // 香辣黄金鸡柳
return new Snack_1(num);
case 2: // 小鲜肉酥饼
return new Snack_2(num);
case 3: // 上校鸡块
return new Snack_3(num);
default:
return null;
}
}
// 生产具体饮品
public Drink createDrink(int kind, int num) {
switch(kind)
{
case 1: // 桃之恋乌龙茶
return new Drink_1(num);
case 2: // 葡萄柚鲜果莫吉托
return new Drink_2(num);
default:
return null;
}
}
// 生产具体主食
public Rice createRice(int kind, int num) {
switch(kind)
{
case 1: // 新奥尔良烤鸡腿饭
return new Rice_1(num);
case 2: // 培根蘑菇鸡柳饭
return new Rice_2(num);
default:
return null;
}
}
// 生产具体套餐
public SetFood createSetFood(int kind, int num) {
switch(kind)
{
case 1: // 套餐A
return new SetFoodA(num);
case 2: // 套餐B
return new SetFoodB(num);
case 3: // 套餐C
return new SetFoodC(num);
default:
return null;
}
}
}
// 创建职员类
class Clerk{
private KFC_Factory factory_1;
public String s[] = new String[5];
// 构造方法将肯德基抽象工厂传入
public Clerk(KFC_Factory factory_1) {
this.factory_1 = factory_1;
}
// 订购汉堡
public double orderHamburger(int kind, int num) {
Hamburger hamburger = factory_1.createHamburger(kind, num);
hamburger.outPut();
s[0] = hamburger.outPut();
return hamburger.totalPrice();
}
// 订购小食
public double orderSnack(int kind, int num) {
Snack snack = factory_1.createSnack(kind, num);
snack.outPut();
s[1] = snack.outPut();
return snack.totalPrice();
}
// 订购饮品
public double orderDrink(int kind, int num) {
Drink drink = factory_1.createDrink(kind, num);
drink.outPut();
s[2] = drink.outPut();
return drink.totalPrice();
}
// 订购主食
public double orderRice(int kind, int num) {
Rice rice = factory_1.createRice(kind, num);
rice.outPut();
s[3] = rice.outPut();
return rice.totalPrice();
}
// 订购套餐
public double orderSetFood(int kind, int num) {
SetFood setFood = factory_1.createSetFood(kind, num);
setFood.outPut();
s[4] = setFood.outPut();
return setFood.totalPrice();
}
}
// 创建菜单类
class Menu{
public Menu() {
System.out.println("————————————————————单品菜单————————————————————");
System.out.println("——————————————————————————————————————————————");
System.out.println("-------------------一、汉堡类 --------------------");
System.out.println("1、柚香鸡腿堡----------------------------------19元");
System.out.println("2、芝士培根澳牛堡-------------------------------25元");
System.out.println("3、牛油果香辣鸡腿堡------------------------------17元");
System.out.println("——————————————————————————————————————————————");
System.out.println("-------------------二、小食类 --------------------");
System.out.println("1、香辣黄金鸡柳--------------------------------9.9元");
System.out.println("2、小鲜肉酥饼-----------------------------------8元");
System.out.println("3、上校鸡块------------------------------------7元");
System.out.println("——————————————————————————————————————————————");
System.out.println("-------------------三、饮品类-------------------- ");
System.out.println("1、桃之恋乌龙茶------------------------------ 13.5元");
System.out.println("2、葡萄柚鲜果莫吉托------------------------------14元");
System.out.println("——————————————————————————————————————————————");
System.out.println("-------------------四、主食类---------------------");
System.out.println("1、新奥尔良烤鸡腿饭----------------------------19.5元");
System.out.println("2、培根蘑菇鸡柳饭-------------------------------20元");
System.out.println("——————————————————————————————————————————————");
System.out.println("————————————————————套餐菜单————————————————————");
System.out.println("1、套餐A:柚香鸡腿堡+桃之恋乌龙茶--------------------32元");
System.out.println("2、套餐B:培根蘑菇鸡柳饭+葡萄柚鲜果莫吉托-- ------------33元");
System.out.println("3、套餐C:芝士培根澳牛堡+桃之恋乌龙茶------------------38元");
System.out.println("——————————————————————————————————————————————");
}
}
// 实现具体的订购
public class Client {
static KFC_Factory factory = new CKFC_Factory(); // 创建KFC工厂
static Clerk customer = new Clerk(factory); // 创建顾客
static int type; // 顾客选择餐品类别
static int kind; // 顾客选择该类别下的具体餐品
static int num; // 顾客选择餐品数量
/* 实现单品点餐功能 */
public static void orderSingleFood() throws ParseException, FileNotFoundException {
double total = 0; // 顾客所点单品总价
double total_1 = 0;
double total_2 = 0;
double total_3 = 0;
double total_4 = 0;
int flag = 1;
while(flag==1)
{
Scanner sc = new Scanner(System.in);
System.out.println("请选择餐品类别:");
type = sc.nextInt();
System.out.println("请选择该类别下的具体餐品:");
kind = sc.nextInt();
System.out.println("请输入餐品个数:");
num = sc.nextInt();
switch(type)
{
case 1:
total_1 = customer.orderHamburger(kind, num);
break;
case 2:
total_2 = customer.orderSnack(kind, num);
break;
case 3:
total_3 = customer.orderDrink(kind, num);
break;
case 4:
total_4 = customer.orderRice(kind, num);
break;
default:
System.out.println("对不起,没有该类餐品,请重新选择!");
}
System.out.println("继续点餐请选1,结束点餐请选0:");
flag = sc.nextInt();
}
total = total_1 + total_2 + total_3 + total_4;
// 获取系统时间
Date date = new Date();
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd : hh:mm:ss");
// 将系统当前时间与活动时间进行比较,判断是否参与活动
int huodong = 0; // 活动
Date date_1 = new Date();
Date date_2 = new Date();
date_1 = dateFormat.parse("2019-5-11 : 24:00:00");
date_2 = dateFormat.parse("2019-6-22 : 24:00:00");
if((date_1.getTime()<date.getTime()) & (date.getTime()<date_2.getTime()))
huodong = 5;
else
huodong = 0;
Scanner sc = new Scanner(System.in);
System.out.println("餐品总价:"+total);
System.out.println("请输入付款金额:");
double fukuan = sc.nextInt();
// 使用优惠券结算
int youhui = 0;
System.out.println("使用优惠券付款请输入1,不使用请输入0");
int temp = sc.nextInt();
if(temp==1)
{
System.out.println("请输入优惠券额度:");
youhui = sc.nextInt();
System.out.println("----------------小橙子KFC----------------");
System.out.println("账单如下:");
int i=0;
for(i=0; i<5; i++)
System.out.println(customer.s [i]);
System.out.println("本次消费总金额:"+total);
System.out.println("优惠券额度:"+youhui);
System.out.println("共收您金额:"+fukuan);
if(huodong==5)
System.out.println("目前本店正处于店庆期间,凡购买本店餐品者均立减五元");
else
System.out.println("本店暂无活动");
System.out.println("找零:"+(fukuan-(total-youhui-huodong)));
System.out.println(dateFormat.format(date));
System.out.println("---------------------------------------");
PrintStream ps = new PrintStream("G:\\Users\\Administrator\\eclipse-workspace\\KFC小票");
System.setOut(ps);
System.out.println("----------------小橙子KFC----------------");
System.out.println("账单如下:");
int j=0;
for(j=0; j<5; j++)
System.out.println(customer.s [j]);
System.out.println("本次消费总金额:"+total);
System.out.println("优惠券额度:"+youhui);
System.out.println("共收您金额:"+fukuan);
if(huodong==5)
System.out.println("目前本店正处于店庆期间,凡购买本店餐品者均立减五元");
else
System.out.println("本店暂无活动");
System.out.println("找零:"+(fukuan-(total-youhui-huodong)));
System.out.println(dateFormat.format(date));
System.out.println("---------------------------------------");
}
else
{
System.out.println("----------------小橙子KFC----------------");
System.out.println("账单如下:");
int i=0;
for(i=0; i<5; i++)
System.out.println(customer.s [i]);
System.out.println("本次消费总金额:"+total);
System.out.println("共收您金额:"+fukuan);
if(huodong==5)
System.out.println("目前本店正处于店庆期间,凡购买本店餐品者均立减五元");
else
System.out.println("本店暂无活动");
System.out.println("找零:"+(fukuan-(total-huodong)));
System.out.println(dateFormat.format(date));
System.out.println("--------------------------------------");
PrintStream ps = new PrintStream("G:\\Users\\Administrator\\eclipse-workspace\\KFC小票");
System.setOut(ps);
System.out.println("----------------小橙子KFC----------------");
System.out.println("账单如下:");
int k=0;
for(k=0; k<5; k++)
System.out.println(customer.s [k]);
System.out.println("本次消费总金额:"+total);
System.out.println("共收您金额:"+fukuan);
if(huodong==5)
System.out.println("目前本店正处于店庆期间,凡购买本店餐品者均立减五元");
else
System.out.println("本店暂无活动");
System.out.println("找零:"+(fukuan-(total-huodong)));
System.out.println(dateFormat.format(date));
System.out.println("--------------------------------------");
}
}
/* 实现套餐点餐功能 */
public static void orderSetFood() throws ParseException, FileNotFoundException {
double total; // 顾客所点套餐总价
double total_1 = 0;
double total_2 = 0;
double total_3 = 0;
int flag = 1;
while(flag==1)
{
Scanner sc = new Scanner(System.in);
System.out.println("请选择套餐类别:");
kind = sc.nextInt();
System.out.println("请选择套餐数量:");
num = sc.nextInt();
switch(kind)
{
case 1:
total_1 = customer.orderSetFood(kind, num);
break;
case 2:
total_2 = customer.orderSetFood(kind, num);
break;
case 3 :
total_3 = customer.orderSetFood(kind, num);
break;
default:
System.out.println("对不起,没有该类套餐,请重新选择!");
}
System.out.println("继续点餐请选1,结束点餐请选0:");
flag = sc.nextInt();
}
total = total_1 + total_2 + total_3;
// 获取系统时间
Date date = new Date();
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd : hh:mm:ss");
// 将系统当前时间与活动时间进行比较,判断是否参与活动
int huodong = 0; // 活动
Date date_1 = new Date();
Date date_2 = new Date();
date_1 = dateFormat.parse("2019-5-11 : 24:00:00");
date_2 = dateFormat.parse("2019-6-22 : 24:00:00");
if((date_1.getTime()<date.getTime()) & (date.getTime()<date_2.getTime()))
huodong = 5;
else
huodong = 0;
Scanner sc = new Scanner(System.in);
System.out.println("餐品总价:"+total);
System.out.println("请输入付款金额:");
double fukuan = sc.nextInt();
// 使用优惠券结算
int youhui = 0;
System.out.println("使用优惠券付款请输入1,不使用请输入0");
int temp = sc.nextInt();
if(temp==1)
{
System.out.println("请输入优惠券额度:");
youhui = sc.nextInt();
System.out.println("----------------小橙子KFC----------------");
System.out.println("账单如下:");
int i=0;
for(i=0; i<5; i++)
System.out.println(customer.s [i]);
System.out.println("本次消费总金额:"+total);
System.out.println("优惠券额度:"+youhui);
System.out.println("共收您金额:"+fukuan);
if(huodong==5)
System.out.println("目前本店正处于店庆期间,凡购买本店餐品者均立减五元");
else
System.out.println("本店暂无活动");
System.out.println("找零:"+(fukuan-(total-youhui-huodong)));
System.out.println(dateFormat.format(date));
System.out.println("--------------------------------------");
PrintStream ps = new PrintStream("G:\\Users\\Administrator\\eclipse-workspace\\KFC小票");
System.setOut(ps);
System.out.println("----------------小橙子KFC----------------");
System.out.println("账单如下:");
int j=0;
for(j=0; j<5; j++)
System.out.println(customer.s [j]);
System.out.println("本次消费总金额:"+total);
System.out.println("优惠券额度:"+youhui);
System.out.println("共收您金额:"+fukuan);
if(huodong==5)
System.out.println("目前本店正处于店庆期间,凡购买本店餐品者均立减五元");
else
System.out.println("本店暂无活动");
System.out.println("找零:"+(fukuan-(total-youhui-huodong)));
System.out.println(dateFormat.format(date));
System.out.println("--------------------------------------");
}
else
{
System.out.println("----------------小橙子KFC----------------");
System.out.println("账单如下:");
int i=0;
for(i=0; i<5; i++)
System.out.println(customer.s [i]);
System.out.println("本次消费总金额:"+total);
System.out.println("共收您金额:"+fukuan);
if(huodong==5)
System.out.println("目前本店正处于店庆期间,凡购买本店餐品者均立减五元");
else
System.out.println("本店暂无活动");
System.out.println("找零:"+(fukuan-(total-huodong)));
System.out.println(dateFormat.format(date));
System.out.println("--------------------------------------");
PrintStream ps = new PrintStream("G:\\Users\\Administrator\\eclipse-workspace\\KFC小票");
System.setOut(ps);
System.out.println("----------------小橙子KFC----------------");
System.out.println("账单如下:");
int k=0;
for(k=0; k<5; k++)
System.out.println(customer.s [k]);
System.out.println("本次消费总金额:"+total);
System.out.println("共收您金额:"+fukuan);
if(huodong==5)
System.out.println("目前本店正处于店庆期间,凡购买本店餐品者均立减五元");
else
System.out.println("本店暂无活动");
System.out.println("找零:"+(fukuan-(total-huodong)));
System.out.println(dateFormat.format(date));
System.out.println("--------------------------------------");
}
}
public static void main(String[] args) throws ParseException, FileNotFoundException {
Menu menu = new Menu();
System.out.println("欢迎光临小橙子KFC,很高兴为您服务!");
System.out.println("\n点单品请选择0,点套餐请选择1:");
int flag;
Scanner sc = new Scanner(System.in);
flag = sc.nextInt();
switch(flag)
{
case 0:
orderSingleFood();
break;
case 1:
orderSetFood();
break;
default:
System.out.println("对不起,您的选择错误,请重新选择!");
}
}
}
四、运行结果
输出显示到屏幕:
存入文件: