Java实现模拟KFC点餐系统(设计模式)

xiaoxiao2022-06-03  15

 

同学们应该都去麦当劳或肯德基吃过快餐吧?请同学们参考肯德基官网的信息模拟肯德基快餐店的收银系统,合理使用C++/python/Java,结合设计模式(2种以上)至少实现系统的以下功能:

1.正常餐品结算和找零。

2.基本套餐结算和找零。

3.使用优惠劵购买餐品结算和找零。

4.可在一定时间段参与店内活动(自行设计或参考官网信息)。

5.模拟打印小票的功能(写到文件中)。

设计思路

1.模式定义

(1)工厂方法模式 

工厂方法模式Factory Method,又称多态性工厂模式。在工厂方法模式中,核心的工厂类不再负责所有的产品的创建,而是将具体创建的工作交给子类去做。该核心类成为一个抽象工厂角色,仅负责给出具体工厂子类必须实现的接口,而不接触哪一个产品类应当被实例化这种细节。

工厂方法模式是简单工厂模式的衍生,解决了许多简单工厂模式的问题。首先完全实现‘开-闭 原则’,实现了可扩展。其次更复杂的层次结构,可以应用于产品结果复杂的场合。

(2)抽象工厂模式

抽象工厂模式是所有形态的工厂模式中最为抽象和最具一般性的一种形态。抽象工厂模式是指当有多个抽象角色时,使用的一种工厂模式。抽象工厂模式可以向客户端提供一个接口,使客户端在不必指定产品的具体的情况下,创建多个产品族中的产品对象。根据里氏替换原则,任何接受父类型的地方,都应当能够接受子类型。因此,实际上系统所需要的,仅仅是类型与这些抽象产品角色相同的一些实例,而不是这些抽象产品的实例。换言之,也就是这些抽象产品的具体子类的实例。工厂类负责创建抽象产品的具体子类的实例。

为创建一组相关或相互依赖的对象提供一个接口,而且无需指定他们的具体类。

2.抽象化分析

        开-闭”原则和“依赖倒置”原则 

让程序对扩展开放,对修改关闭,——抽象!我们要对系统模型进行最大化的抽象,才能达到“开-闭”原则的要求,“依赖倒置”原则为我们指明了一条方向,从具体的类型来进行抽象。

     肯德基实体店——生产食物的工厂;食物(汉堡、鸡翅、薯条、可乐等等)——工厂生产的产品;职员——负责点餐;用户——食物购买者。

  肯德基店就是一个具体的工厂,这时,我们需要抽象一个工厂,在抽象工厂中指明了生产各种抽象食物的方法,如生产汉堡、鸡翅等,肯德基店就需要实现这个抽象工厂,生产具体的食品,如生产麻辣鸡腿汉堡、生产奥尔良鸡翅等。前面提到了“抽象食物”,我们还需要对每个具体的食物添加抽象父类,如汉堡就是抽象父类,麻辣鸡腿汉堡就是汉堡的一个子类,依次类推。这时,我们会发现,每一种食物又都存在着一些共同的属性,如风味、单价、数量等,因此,我们继续进行抽象,所有的抽象食物都继承一个抽象父类。客户如何订购肯德基生产的食物呢?这与上一章的工厂方法模式有所不同,这里我们使用组合的方式,将抽象工厂作为客户类中的一个实例变量,客户需要任何产品的时候,只需要向工厂请求即可,这就是抽象工厂模式的应用方式。客户类和工厂类分开,客户无须修改就可以获得新产品。

3.类图

4.主要模块程序

1.单品的接口

/** * 所有单品的接口 * 随后添加的单品类只需要implements此接口并实现其方法 * 定义打印输出不同单品的相关信息 */ public interface SingleFood { void showInfo(); //抽象方法,打印输出输出食物信息 }

2.单品基本信息抽象类

/** * 单品抽象基类 * 定义单品的共同属性 * */ public abstract class FoodBaseInfo { public String type; //每个大种类下的具体种类 public int num; //数量 public double price; //价格 //计算餐品总价 public double totalPrice(){ //return this.num * this.price; return num * price; } }

3.单品抽象工厂

/** * 肯德基抽象工厂:生产抽象食物 * 抽象工厂中创建各种食物,都是抽象食物。 * */ public interface KFCFoodFactory { public Hamburgers createHamburgers(int kind, int num); //根据不同的kind参数确定不同的汉堡种类,生产汉堡 public FrenchFries createFrenchFries(int kind, int num); //生产薯条 public Chicken createChickens(int kind, int num); //生产鸡 public Drinkings createDrinkings(int kind, int num); //生产饮料 public Rices createRices(int kind, int num); //生产米饭 }

4.实例工厂,生产具体食物

//肯德基实体店1,可以生产具体食物 public class KFCFactory_1 implements KFCFoodFactory{ /** * 生产汉堡 * */ public Hamburgers createHamburgers(int kind, int num){ //香辣鸡腿堡 if(1==kind) return new Hamburger_1(num); //新奥尔良烤鸡腿堡 else if(2==kind) return new Hamburger_2(num); //劲脆鸡腿堡 else if(3==kind) return new Hamburger_3(num); else return null; } /** * 生产薯条 * */ public FrenchFries createFrenchFries(int kind, int num) { if(1==kind) return new Frenchfries_1(num); else return null; } /** * 生产鸡 * */ public Chicken createChickens(int kind, int num) { //吮指原味鸡 if(1==kind) return new Chicken_1(num); //香辣鸡翅 else if(2==kind) return new Chicken_2(num); else return null; } /** * 生产饮料 * */ public Drinkings createDrinkings(int kind, int num) { //可乐 if(1==kind) return new Drinking_1(num); //九珍果汁饮料 else if(2==kind) return new Drinking_2(num); //柠檬红茶 else if(3==kind) return new Drinking_3(num); else return null; } /** * 生产米饭 * */ public Rices createRices(int kind, int num) { //海苔盐烧大鸡腿饭 if(1==kind) return new Rice_1(num); //川辣泡椒鸡块饭 else if(2==kind) return new Rice_2(num); else return null; } }

5.职员点餐时,就向肯德基店(工厂)请求

package client.clerk; import kfcfactory.foodfactory.KFCFoodFactory; import kfcfactory.kfcmodel.Chicken; import kfcfactory.kfcmodel.Drinkings; import kfcfactory.kfcmodel.FrenchFries; import kfcfactory.kfcmodel.Hamburgers; import kfcfactory.kfcmodel.Rices; /** * 职员类中含有一个抽象工厂KFCFoodFactory类型的实例变量factory_1 * Clerk类可通过构造方法将肯德基店实例(实体店)传入 * 职员点餐时,就向肯德基店(工厂)请求,职员不生产食物(不使用new生成对象) * */ public class Clerk { //肯德基抽象工厂 private KFCFoodFactory factory_1; //构造方法将抽象工厂传入 public Clerk(KFCFoodFactory factory_1){ this.factory_1 = factory_1; } /** * 订购食物 */ //汉堡 public double orderHamburgers(int kind,int num){ //获得不同种类的汉堡 Hamburgers hamburger = factory_1.createHamburgers(kind, num); //输出订购信息 hamburger.showInfo(); //返回总价 return hamburger.totalPrice(); } //鸡 public double orderChickens(int kind, int num){ //获得不同种类鸡 Chicken chicken = factory_1.createChickens(kind,num); //输出订购信息 chicken.showInfo(); //返回总价 return chicken.totalPrice(); } //薯条 public double orderFrenchFries(int kind, int num){ //获得薯条 FrenchFries frenchFries = factory_1.createFrenchFries(kind,num); //输出订购信息 frenchFries.showInfo(); //返回总价 return frenchFries.totalPrice(); } //饮品 public double orderDrinkings(int kind, int num){ //获得不同种类的饮料 Drinkings drink = factory_1.createDrinkings(kind, num); //输出订购信息 drink.showInfo(); //返回总价 return drink.totalPrice(); } //饮品 public double orderRices(int kind, int num){ //获得不同种类的饮料 Rices rice = factory_1.createRices(kind, num); //输出订购信息 rice.showInfo(); //返回总价 return rice.totalPrice(); } }

6.点餐类

package client.Consumers; import client.clerk.Menu; import client.clerk.Clerk; import kfcfactory.foodfactory.KFCFactory_1; import kfcfactory.foodfactory.KFCFoodFactory; import kfcfactory.kfcmodel.Chicken; import kfcfactory.kfcmodel.Drinkings; import kfcfactory.kfcmodel.FrenchFries; import kfcfactory.kfcmodel.Hamburgers; import kfcfactory.kfcmodel.Rices; import kfcfactory.kfcmodel.realfood.Hamburger_1; import java.io.BufferedOutputStream; import java.io.BufferedWriter; import java.io.DataOutputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.FileWriter; import java.io.IOException; import java.io.PrintStream; import java.util.Scanner; public class OrderFoods { /** * 定义一个肯德基 * (KFCFoodFactory接口类型) */ static KFCFoodFactory factory_1 = new KFCFactory_1(); /** * 创建职员 */ static Clerk customer = new Clerk(factory_1); static int order; //用户选的的菜系 static int kind; //用户选择的食物 static int num; //数量 public static void main(String[] args) { //菜单显示,点餐 OrderFoods.showMenu(); } public static void showMenu() { Menu menu = new Menu(); menu.showsingleFoods(); menu.showsetMeal(); int flag = 1; double total = 0; //点餐结束的总价 double total1 = 0; double total2 = 0; double total3 = 0; double total4 = 0; double total5 = 0; while(flag != 0) { Scanner sc = new Scanner(System.in); System.out.println("请输入餐类:"); order = sc.nextInt(); System.out.println("请输入餐品:"); kind = sc.nextInt(); System.out.println("请输入餐品个数:"); num = sc.nextInt(); // PrintStream out = System.out; //System.setOut(new PrintStream("order.txt")); switch (order) { case 1: total1 = customer.orderHamburgers(kind, num); break; case 2: total2 = customer.orderFrenchFries(kind, num); break; case 3: total3 = customer.orderChickens(kind, num); break; case 4: total4 = customer.orderDrinkings(kind, num); break; case 5: total5 = customer.orderRices(kind, num); break; default: System.out.println("对不起,您所选择的餐品错误"); } //System.setOut(out); System.out.println("继续点餐? 1——yes 0——no:"); flag = sc.nextInt(); } // System.setOut(new PrintStream("order1.txt")); total = total1 +total2 + total3 + total4 +total5; if (total > 88) { System.out.println("total(discount): "+ 0.8*total); System.out.println("祝您用餐愉快"); } else { System.out.println("total: " +total+"元"); System.out.println("祝您用餐愉快"); } } }

结果截图

总结

1.能力有限,只实现了单品和打折的模块

2.工厂模式的理解还是不透彻

抽象模式的详细介绍://www.cnblogs.com/jenkinschan/p/5712874.html

参考网站:https://www.cnblogs.com/danielleee/p/8567124.html

转载请注明原文地址: https://www.6miu.com/read-4915127.html

最新回复(0)