一.算法设计思路
这道题,我采用了三种设计模式,分别是工厂方法模式、抽象工厂模式及策略模式。
工厂方法模式:
核心工厂类(Factory)不再负责所有产品的创建,而是将具体创建的工作交给子类(KFCFactory)完成。它只负责给出具体工厂类必须实现的接口。
抽象工厂模式:
消费者点餐时各种类型的食物就是产品族(Hamburger Chicken Drink),而每个产品族都有产品等级(Hamburger_1,Hamburger_2,Hamburger_3)等等。
将工厂类和客户类分开,用户需要某种产品,只需向工厂请求即可。用户无需修改就能接收新产品。
策略模式:
其中,支付方式使用了策略模式来处理。定义支付策略的顶级接口(Pay),而每一种支付方式作为一种策略的实现(Alipay Paypal Wechatpay),而我们的结算服务中持有一个支付策略的引用就可以了。
二.类图
1.工厂方法模式
2.抽象方法模式
3.策略模式
三源代码
抽象食物
package kfc;
/*抽象食物*/
public abstract class AbstractFood {
protected String type;//种类
protected float price;//单价
protected int num;//数量
public float totalprice(){//总价
return this.price*this.num;
}
}
package kfc;
/*输出食物信息*/
public interface Food {
void play();
}
抽象工厂
package kfc;
/*抽象工厂*/
public interface Factory {
public interface factory{
public Hamburger creatHamburger(int num);//汉堡类
public Chicken creatChicken(int num);//鸡肉类
public Drink creatDrink(int num);//饮料类
public Setmeal creatSetmeal(int num);//套餐
}
public Hamburger_1 creatHamburger_1(int numm);//香辣鸡腿堡
public Hamburger_2 creatHamburger_2(int numm);//奥尔良鸡腿堡
public Hamburger_3 creatHamburger_3(int numm);//超级牛肉堡
public Chicken_1 creatChicken_1(int num);//炸鸡腿
public Chicken_2 creatChicken_2(int num);//香辣鸡翅
public Chicken_3 creatChicken_3(int num);//大鸡排
public Drink_1 creatDrink_1(int num);//可乐
public Drink_2 creatDrink_2(int num);//奶茶
public Drink_3 creatDrink_3(int num);//咖啡
public Setmeal_1 creatSetmeal_1(int num);//套餐一
public Setmeal_2 creatSetmeal_2(int num);//套餐二
public Setmeal_3 creatSetmeal_3(int num);//套餐三
}
具体工厂
package kfc;
/*具体工厂*/
public class KFCFactory implements Factory {
public Hamburger_1 creatHamburger_1(int num){//香辣鸡腿堡
return new Hamburger_1(num);
}
public Hamburger_2 creatHamburger_2(int num){//奥尔良鸡腿堡
return new Hamburger_2(num);
}
public Hamburger_3 creatHamburger_3(int num){//超级牛肉堡
return new Hamburger_3(num);
}
public Chicken_1 creatChicken_1(int num){//炸鸡腿
return new Chicken_1(num);
}
public Chicken_2 creatChicken_2(int num){//香辣鸡翅
return new Chicken_2(num);
}
public Chicken_3 creatChicken_3(int num){//大鸡排
return new Chicken_3(num);
}
public Drink_1 creatDrink_1(int num){//可乐
return new Drink_1(num);
}
public Drink_2 creatDrink_2(int num){//奶茶
return new Drink_2(num);
}
public Drink_3 creatDrink_3(int num){//咖啡
return new Drink_3(num);
}
public Setmeal_1 creatSetmeal_1(int num){//套餐一
return new Setmeal_1(num);
}
public Setmeal_2 creatSetmeal_2(int num){//套餐二
return new Setmeal_2(num);
}
public Setmeal_3 creatSetmeal_3(int num){//套餐三
return new Setmeal_3(num);
}
}
汉堡类
package kfc;
/*汉堡类*/
public abstract class Hamburger extends AbstractFood implements Food {
public void play(){
System.out.println("--"+this.type+"单价:"+this.price+"数量:"+this.num+"总价:"+this.totalprice());
}
}
具体汉堡
package kfc;
public class Hamburger_1 extends Hamburger {
public Hamburger_1(int num){
this.type="香辣鸡腿堡";
this.price=15.5f;
this.num=num;
}
}
package kfc;
public class Hamburger_2 extends Hamburger {
public Hamburger_2(int num){
this.type="奥尔良鸡腿堡";
this.price=16f;
this.num=num;
}
}
package kfc;
public class Hamburger_3 extends Hamburger {
public Hamburger_3(int num){
this.type="超级牛肉堡";
this.price=17f;
this.num=num;
}
}
Chicken,Drink和Hamburger同理,在此就不赘述。
客户类
package kfc;
public class Client {//客户类
private Factory factory;//抽象工厂
public Client(Factory factory){
this.factory=factory;
}
/*点餐*/
public float orderHamburger_1(int num){
Hamburger Hamburger_1=factory.creatHamburger_1(num);//奥尔良鸡腿堡
Hamburger_1.play();//输出点餐信息
return Hamburger_1.totalprice();//返回总价
}
public float orderHamburger_2(int num){
Hamburger Hamburger_2=factory.creatHamburger_2(num);//香辣鸡腿堡
Hamburger_2.play();//输出点餐信息
return Hamburger_2.totalprice();//返回总价
}
public float orderHamburger_3(int num){
Hamburger Hamburger_3=factory.creatHamburger_3(num);//超级牛肉堡
Hamburger_3.play();//输出点餐信息
return Hamburger_3.totalprice();//返回总价
}
public float orderChicken_1(int num){
Chicken Chicken_1 =factory.creatChicken_1(num);//炸鸡腿
Chicken_1.play();//输出点餐信息
return Chicken_1.totalprice();//返回总价
}
public float orderChicken_2(int num){
Chicken Chicken_2 =factory.creatChicken_2(num);//香辣鸡翅
Chicken_2.play();//输出点餐信息
return Chicken_2.totalprice();//返回总价
}
public float orderChicken_3(int num){
Chicken Chicken_3 =factory.creatChicken_3(num);//大鸡排
Chicken_3.play();//输出点餐信息
return Chicken_3.totalprice();//返回总价
}
public float orderDrink_1(int num){
Drink Drink_1 =factory.creatDrink_1(num);//可乐
Drink_1.play();//输出点餐信息
return Drink_1.totalprice();//返回总价
}
public float orderDrink_2(int num){
Drink Drink_2 =factory.creatDrink_2(num);//奶茶
Drink_2.play();//输出点餐信息
return Drink_2.totalprice();//返回总价
}
public float orderDrink_3(int num){
Drink Drink_3 =factory.creatDrink_3(num);//咖啡
Drink_3.play();//输出点餐信息
return Drink_3.totalprice();//返回总价
}
public float orderSetmeal_1(int num){
Setmeal Setmeal_1 =factory.creatSetmeal_1(num);//套餐一
Setmeal_1.play();//输出点餐信息
return Setmeal_1.totalprice();//返回总价
}
public float orderSetmeal_2(int num){
Setmeal Setmeal_2 =factory.creatSetmeal_2(num);//套餐二
Setmeal_2.play();//输出点餐信息
return Setmeal_2.totalprice();//返回总价
}
public float orderSetmeal_3(int num){
Setmeal Setmeal_3 =factory.creatSetmeal_3(num);//套餐三
Setmeal_3.play();//输出点餐信息
return Setmeal_3.totalprice();//返回总价
}
}
测试类
package kfc;
import java.util.Scanner;
import java.io.*;
public class Test {
public static void main(String[] args) throws Exception{
FileOutputStream out =new FileOutputStream("out.txt");
Factory factory=new KFCFactory();//定义肯德基类
Client client=new Client(factory);//定义用户
Scanner order=new Scanner(System.in);//点餐
float Hamburger_1=0;
float Hamburger_2=0;
float Hamburger_3=0;
float Chicken_1=0;
float Chicken_2=0;
float Chicken_3=0;
float Drink_1=0;
float Drink_2=0;
float Drink_3=0;
float Setmeal_1=0;
float Setmeal_2=0;
float Setmeal_3=0;
System.out.println(" 欢迎光临肯德基!\n"
+"-------------------------菜单如下-------------------------------\n"
+" 汉堡类: \n"
+"1.香辣鸡腿堡--15.5元 2.奥尔良鸡腿堡--16元 3.超级牛肉堡--17元\n"
+" 鸡肉类: \n"
+"4.炸鸡腿 --12元 5.香辣鸡翅--10元 6.大鸡排--10.5元\n"
+" 饮料类: \n"
+"7.可乐--3元 8.奶茶--4元 9.咖啡--5.5元\n"
+" 套餐类: \n"
+"10.套餐一--31元\n"
+" 1个香辣鸡腿堡+1个炸鸡腿+1个大鸡排+1杯可乐\n"
+"11.套餐二--45元\n"
+" 1个奥尔良鸡腿堡+1个炸鸡腿+1个香辣鸡翅+1杯咖啡\n"
+"12.套餐三--95元\n"
+" 1个超级牛肉堡/香辣鸡腿堡(任点)+1个香辣鸡翅+1个大鸡排++1杯可乐+1杯奶茶/咖啡(任点)\n"
+"-----------------------------------------------------------\n");
while(true){
System.out.println("请选择 订餐序号:");
int m=order.nextInt();
System.out.println("请选择数量:");
int n=order.nextInt();
switch(m){
case 1:
Hamburger_1 =client.orderHamburger_1(n);//香辣鸡腿堡
break;
case 2:
Hamburger_2 =client.orderHamburger_2(n);//奥尔良鸡腿堡
break;
case 3:
Hamburger_3 =client.orderHamburger_3(n);//超级牛肉堡
break;
case 4:
Chicken_1 =client.orderChicken_1(n);//炸鸡腿
break;
case 5:
Chicken_2 =client.orderChicken_2(n);//香辣鸡翅
break;
case 6:
Chicken_3 =client.orderChicken_3(n);//大鸡排
break;
case 7:
Drink_1 =client.orderChicken_1(n);//可乐
break;
case 8:
Drink_2 =client.orderChicken_2(n);//奶茶
break;
case 9:
Drink_3 =client.orderChicken_3(n);//咖啡
break;
case 10:
Setmeal_1 =client.orderSetmeal_1(n);//套餐一
break;
case 11:
Setmeal_2 =client.orderSetmeal_2(n);//套餐二
break;
case 12:
Setmeal_3 =client.orderSetmeal_3(n);//套餐三
break;
}
System.out.println("请选择是否继续点餐!1.是 2.否");
int p =order.nextInt();
if(p!=1){
break;
}
}
float money1=Hamburger_1+Hamburger_2+Hamburger_3;
float money2=Chicken_1+Chicken_2+Chicken_3;
float money3=Drink_1+Drink_2+Drink_3;
float money4=Setmeal_1+Setmeal_2+Setmeal_3;
float money=money1+money2+money3+money4;
System.out.println("您本次消费共计:"+money);
System.out.println("请选择付款方式:");
int q=order.nextInt();
float r =0;
switch(q){
case 1:
PayTemplate p1=new PayTemplate(new Alipay());
p1.doMypay();
r=(float)(money- (money*0.9));
break;
case 2:
PayTemplate p2=new PayTemplate(new Wechatpay());
p2.doMypay();
r=5;
break;
case 3:
PayTemplate p3=new PayTemplate(new Paypal());
p3.doMypay();
r=8;
break;
}
System.out.println("请输入实付金额:");
int t=order.nextInt();
System.out.println("优惠"+r+"元");
float change=t-(money-r);
System.out.println("找零:"+change);
System.out.println("祝您用餐愉快!");
//out.write();
out.close();
}
}
抽象支付方式
package kfc;
public interface Pay {
public void doPay();
}
具体支付方式
package kfc;
public class Wechatpay implements Pay {
public void doPay(){
System.out.println("使用Wechatpay");
System.out.println("领取5元红包");
}
}
package kfc;
public class Paypal implements Pay{
public void doPay(){
System.out.println("使用Paypal");
System.out.println("优惠8元");
}
}
package kfc;
public class Alipay implements Pay {
public void doPay(){
System.out.println("使用Alipay");
System.out.println("打九折");
}
}
环境类
package kfc;
public class PayTemplate {
private Pay pay;
public PayTemplate(Pay pay){
super();
this.pay=pay;
}
public void doMypay(){
pay.doPay();
}
}
四.测试截屏
五.总结
这次作业是花费时间最长的一次,遇到了很多问题而且自己写的还不够完美:
1.选择什么设计模式来使用。刚开始写时,只学了四种模式,所以就选择了其中的两种,两种设计模式一起使用确实困难,很容易搞混,理清思路就花了我很长时间。写程序之前先画了一下类图,由于对设计模式还不熟练,再加上这道题比较复杂,画类图也是一波三折(这里参考了CSDN上前辈们的成果)。
2.对于利用MFC来实现可视化界面,我没能做到。一方面是对VC的知识都不太记得了,另一方面我觉得用Java刚好可以学习相关知识,但GUI还没接触过,为了能按时交作业,就没敢冒险。
3.在最后的支付这块,我起先没有想周全,直接是输入付款金额,找零结束。后讲了策略模式,提示用这个模式,才又返回去修改代码。
4.遗憾的是,我没能实现打印小票这个功能(写入文件),自己参考了很多资料,由于时间有限,没来得及完成。当然,我后续会完善这块。
5.用visio画的类图插入到文档里就乱了,所以将类图另外附上。
我在 CSDN上看了很多例子,有用可视化界面做的,有实现了完善功能的,还有利用了数据库的,这无疑是一道课程设计题。但由于时间有限,而且我自己一个人能力也不高,所以只实现了最基础的一部分。希望自己之后也能用GUI实现可视化界面。