• 作业题目

参考肯德基官网的信息模拟肯德基快餐店的收银系统,合理使用C++或Java或Python结合设计模式(2种以上)至少实现系统的以下功能:

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

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

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

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

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

基本要求:

  1. 程序设计风格良好,控制台界面友好,最多两人一组完成任务。
  2. 实现功能测试代码,确保程序的健壮性。
  3. 画出使用的设计模式图。

提高要求:

  1. 实现可视化界面(使用MFC)。
  2. 实现会员储值卡功能,完成储值卡消费。
  3. 实现当天营业额和餐品销量计算和统计,用数据库记录。
  • 算法设计  
  • 方法工厂模式

本程序利用工厂方法模式实现KFC收银系统的合计、支付和找零功能。类图如下:

KFC收银系统模拟

  • 抽象工厂模式

本程序利用抽象工厂模式实现KFC收银系统的点餐部分,制造各种餐品。类图如下:

KFC收银系统模拟

"""
@文件:KFC收银模拟系统
@说明:KFC收银模拟系统
@时间:2019.5.3
"""
 # 抽象食物类
class Abstract_Food(object):
    name = "食物"
    price = 0
    number = 0
    def Order(self):
        pass
    def message(self):
        pass

# 汉堡类
class Hamburg(Abstract_Food):
    name = "汉堡"
    price = 9
    def Order(self):
        self.number = input("需要几份本餐品:")
    def message(self):
        kfc_list = "餐品:%s    单价:%d    数量:%s    合计:%d" % (self.name, self.price, self.number,
                                                   int(self.price) * int(self.number))
        return kfc_list, int(self.price) * int(self.number)

# 薯条类
class Chip(Abstract_Food):
    name = "薯条"
    price = 6
    def Order(self):
        self.number = input("需要几份本餐品:")
    def message(self):
        kfc_list = "餐品:%s    单价:%d    数量:%s    合计:%d" % (self.name, self.price, self.number,
                                                   int(self.price) * int(self.number))
        return kfc_list, int(self.price) * int(self.number)

# 鸡翅类
class Chicken_Wing(Abstract_Food):
    name = "鸡翅"
    price = 7
    def Order(self):
        self.number = input("需要几份本餐品:")
    def message(self):
        kfc_list = "餐品:%s    单价:%d    数量:%s    合计:%d" % (self.name, self.price, self.number,
                                                   int(self.price) * int(self.number))
        return kfc_list, int(self.price) * int(self.number)

# 鸡米花类
class Chicken(Abstract_Food):
    name = "鸡米花"
    price = 5
    def Order(self):
        self.number = input("需要几份本餐品:")
    def message(self):
        kfc_list = "餐品:%s    单价:%d    数量:%s    合计:%d" % (self.name, self.price, self.number,
                                                   int(self.price) * int(self.number))
        return kfc_list, int(self.price) * int(self.number)

# 饮料类
class Cola(Abstract_Food):
    name = "饮料"
    price = 5
    def Order(self):
        self.number = input("需要几份本餐品:")
    def message(self):
        kfc_list = "餐品:%s    单价:%d    数量:%s    合计:%d" % (self.name, self.price, self.number,
                                                   int(self.price) * int(self.number))
        return kfc_list, int(self.price) * int(self.number)

# 套餐A类
class Set_mealA(Abstract_Food):
    name = "套餐A"
    price = 17
    def Order(self):
        self.number = input("需要几份本餐品:")
    def message(self):
        kfc_list = "餐品:%s    单价:%d    数量:%s    合计:%d" % (self.name, self.price, self.number,
                                                   int(self.price) * int(self.number))
        return kfc_list, int(self.price) * int(self.number)

# 套餐B类
class Set_mealB(Abstract_Food):
    name = "套餐B"
    price = 15
    def Order(self):
        self.number = input("需要几份本餐品:")
    def message(self):
        kfc_list = "餐品:%s    单价:%d    数量:%s    合计:%d" % (self.name, self.price, self.number,
                                                   int(self.price) * int(self.number))
        return kfc_list, int(self.price) * int(self.number)

# 套餐C类
class Set_mealC(Abstract_Food):
    name = "套餐C"
    price = 18
    def Order(self):
        self.number = input("需要几份本餐品:")
    def message(self):
        kfc_list = "餐品:%s    单价:%d    数量:%s    合计:%d" % (self.name, self.price, self.number,
                                                   int(self.price) * int(self.number))
        return kfc_list, int(self.price) * int(self.number)

### 抽象工厂接口
class KFC_Factory_interface(object):
    def creat_hamburg(self):
        pass
    def creat_chip(self):
        pass
    def creat_Chicken_wing(self):
        pass
    def creat_chicken(self):
        pass
    def creat_cola(self):
        pass
    def creat_A(self):
        pass
    def creat_B(self):
        pass
    def creat_C(self):
        pass

### 抽象工厂实现类
class KFC_Factory(KFC_Factory_interface):
    def creat_hamburg(self):                 # 生产汉堡
        return Hamburg()
    def creat_chip(self):                    # 生产薯条
        return Chip()
    def creat_Chicken_wing(self):            # 生产鸡翅
        return Chicken_Wing()
    def creat_chicken(self):                 # 生产鸡米花
        return Chicken()
    def creat_cola(self):                    # 生产饮料
        return Cola()
    def creat_A(self):                       # 生产A套餐
        return Set_mealA()
    def creat_B(self):                       # 生产B套餐
        return Set_mealB()
    def creat_C(self):                       # 生产C套餐
        return Set_mealC()

# 写入文件(小票)
def w_file(sum_information,sum,cash,back):
    openfile = open("KFC.txt", 'w')                           # 文件打开
    openfile.write("              餐品账单              \n")  # 文件写入……
    openfile.write("   ------------------------------   \n")
    for u in range(0, len(sum_information)):
        openfile.write(sum_information[u] + "\n")
    openfile.write("合计:%d" % sum + "\n")
    openfile.write("支付:%s" % cash + "\n")
    openfile.write("找零:%d" % back + "\n")
    openfile.close()                                         # 文件关闭

class AboutMoney(object):
    def Summation(self, sum_money, sum=0):
        for t in range(0, len(sum_money)):
            sum = sum + sum_money[t]
        return sum

    def Payment(self):
        cash = input("请支付:")
        return int(cash)

    def Back(self, cash, sum):
        back = cash - sum
        return back

class Money_Factory(AboutMoney):
    def creat_Aboutmoney(self):
        pass

# 合计
class Summation_cal(AboutMoney):
    pass

# 支付
class Payment_cal(AboutMoney):
    pass

# 找零
class Back_cal(AboutMoney):
    pass

# 合计业务工厂
class Sum_Factory(Money_Factory):
    def creat_Aboutmoney(self):
        return Summation_cal()

# 支付业务工厂
class Pay_Factory(Money_Factory):
    def creat_Aboutmoney(self):
        return Payment_cal()

# 找零业务工厂
class Bac_Factory(Money_Factory):
    def creat_Aboutmoney(self):
        return Back_cal()

if __name__ == "__main__":
    flag = "q"
    sum = 0
    cash = 0
    back_money = 0
    sum_money = []
    sum_information = []
    print("      欢迎进入KFC点餐系统    ")
    print("      有以下餐品为您提供      ")
    print("------------------------------")
    print("  汉堡 9¥/个   薯条 6¥/份  ")
    print("  鸡翅 7¥/对   鸡米花 5¥/份")
    print("  饮料 5¥/杯   套餐A 17¥/份")
    print("  套餐B 15¥/份 套餐C 18¥/份")
    while flag == "q":
        food = input("请点餐(结束点餐请选择q):")
        accomplishment = ""
        if food == "汉堡":
            accomplishment = KFC_Factory()
            person = accomplishment.creat_hamburg()
            person.Order()
            information1, money1 = person.message()
            sum_information.append(information1)
            sum_money.append(money1)
        elif food == "薯条":
            accomplishment = KFC_Factory()
            person = accomplishment.creat_chip()
            person.Order()
            information2, money2 = person.message()
            sum_information.append(information2)
            sum_money.append(money2)
        elif food == "鸡翅":
            accomplishment = KFC_Factory()
            person = accomplishment.creat_Chicken_wing()
            person.Order()
            information3, money3 = person.message()
            sum_information.append(information3)
            sum_money.append(money3)
        elif food == "鸡米花":
            accomplishment = KFC_Factory()
            person = accomplishment.creat_chicken()
            person.Order()
            information4, money4 = person.message()
            sum_information.append(information4)
            sum_money.append(money4)
        elif food == "饮料":
            accomplishment = KFC_Factory()
            person = accomplishment.creat_cola()
            person.Order()
            information5, money5 = person.message()
            sum_information.append(information5)
            sum_money.append(money5)
        elif food == "套餐A":
            accomplishment = KFC_Factory()
            person = accomplishment.creat_A()
            person.Order()
            information6, money6 = person.message()
            sum_information.append(information6)
            sum_money.append(money6)
        elif food == "套餐B":
            accomplishment = KFC_Factory()
            person = accomplishment.creat_B()
            person.Order()
            information7, money7 = person.message()
            sum_information.append(information7)
            sum_money.append(money7)
        elif food == "套餐C":
            accomplishment = KFC_Factory()
            person = accomplishment.creat_C()
            person.Order()
            information8, money8 = person.message()
            sum_information.append(information8)
            sum_money.append(money8)
        elif food == "q":
            flag = "x"
        else:
            print("无本餐品提供!!!")
    print("账单如下:")
    for u in range(0, len(sum_information)):
        print(sum_information[u])
    summation = Sum_Factory()
    payment = Pay_Factory()
    back = Bac_Factory()
    sum = summation.Summation(sum_money, sum)
    preference = input("是否使用优惠券?")
    if preference == "是":
        sum = int(sum * 0.8)
    else:
        sum = sum
    print("合计:%d" % sum)
    cash = payment.Payment()
    back_money = back.Back(cash, sum)
    print("找零:%d" % back_money)
    w_file(sum_information, sum, cash, back_money)
  • 调试、测试及运行

调试

KFC收银系统模拟

KFC收银系统模拟

点餐:汉堡 抽象工厂开始生产汉堡

KFC收银系统模拟

清单制造函数

KFC收银系统模拟

合计(summation)、支付(payment)、找零(back)对象创建,三个业务工厂开始运作

KFC收银系统模拟

合计功能实现:两个汉堡合计(sum)18元

KFC收银系统模拟

优惠券使用:8折。18元打折:14元

KFC收银系统模拟

支付功能实现:支付20元

KFC收银系统模拟

找零功能实现:支付20元,合计14元,找零6元

测试

KFC收银系统模拟

测试如上:点餐为:汉堡2份,套餐A1份,鸡米花1份,饮料2份

合计为40元,支付50元,找零10元。

点选餐单中没有的餐品会出现提示(无本餐品提供)

小票打印如下:

KFC收银系统模拟

 

  • 经验总结

本程序采用了两种设计模式完成:工厂方法模式和抽象工厂模式。各个餐品选用抽象工厂模式生产,结算和找零业务则利用工厂方法模式完成。

工厂方法模式:定义一个用于创建对象的接口,让子类决定实例化哪一个类,工厂方法使一个类的实例化延时到其子类。

优点:

 子类提供挂钩。基类为工厂方法提供缺省实现,子类可以重写新的实现,也可以继承父类的实现。-- 加一层间接性,增加了灵活性

屏蔽产品类。产品类的实现如何变化,调用者都不需要关心,只需关心产品的接口,只要接口保持不变,系统中的上层模块就不会发生变化。

典型的解耦框架。高层模块只需要知道产品的抽象类,其他的实现类都不需要关心,符合迪米特法则,符合依赖倒置原则,符合里氏替换原则。

多态性:客户代码可以做到与特定应用无关,适用于任何实体类。

缺点:

不易于维护,假如某个具体产品类需要进行一定的修改,很可能需要修改对应的工厂类。当同时需要修改多个产品类的时候,对工厂类的修改会变得相当麻烦。

抽象工厂模式:提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们的类。

优点: 

抽象工厂模式主要在于应对“新系列”的需求变化。分离了具体的类,抽象工厂模式帮助你控制一个应用创建的对象的类,因为一个工厂封装创建产品对象的责任和过程。它将客户和类的实现分离,客户通过他们的抽象接口操纵实例,产品的类名也在具体工厂的实现中被分离,它们不出现在客户代码中。它使得易于交换产品系列。一个具体工厂类在一个应用中仅出现一次——即在它初始化的时候。这使得改变一个应用的具体工厂变得很容易。它只需改变具体的工厂即可使用不同的产品配置,这是因为一个抽象工厂创建了一个完整的产品系列,所以整个产品系列会立刻改变。它有利于产品的一致性。当一个系列的产品对象被设计成一起工作时,一个应用一次只能使用同一个系列中的对象,这一点很重要,而抽象工厂很容易实现这一点。抽象工厂模式有助于这样的团队的分工,降低了模块间的耦合性,提高了团队开发效率。

 

缺点:

抽象工厂模式在于难于应付“新对象”的需求变动。难以支持新种类的产品。难以扩展抽象工厂以生产新种类的产品。这是因为抽象工厂几乎确定了可以被创建的产品集合,支持新种类的产品就需要扩展该工厂接口,这将涉及抽象工厂类及其所有子类的改变。

相关文章: