# 和工厂模式类似，不过这里的结果只是产生不同的类方法
# 设想书店有多种折扣策略，比如“普通会员折扣”、“金牌会员折扣”和“无折扣”。每种折扣策略都是一个具体的策略实现。

from abc import ABC, abstractmethod  

########################################################
# 创建折扣策略接口
########################################################    
class DiscountStrategy(ABC):  
    @abstractmethod  
    def calculate_discount(self, book_price):  
        pass

########################################################
# 创建实现了DiscountStrategy接口的具体折扣策略类
########################################################    
class NoDiscountStrategy(DiscountStrategy):  
    def calculate_discount(self, book_price):  
        return book_price  # 无折扣，原价返回  
  
class RegularMemberDiscountStrategy(DiscountStrategy):  
    def calculate_discount(self, book_price):  
        return book_price * 0.9  # 普通会员9折  
  
class GoldMemberDiscountStrategy(DiscountStrategy):  
    def calculate_discount(self, book_price):  
        return book_price * 0.8  # 金牌会员8折
    
########################################################
# 定义Book类和Bookstore类。Book类包含书籍的信息和价格，Bookstore类则使用折扣策略来计算书籍的折后价
########################################################    
class Book:  
    def __init__(self, title, price):  
        self.title = title  
        self.price = price  
  
class Bookstore:  
    def __init__(self, discount_strategy):  
        self.discount_strategy = discount_strategy  
  
    def set_discount_strategy(self, discount_strategy):  
        self.discount_strategy = discount_strategy  
  
    def calculate_final_price(self, book):  
        discounted_price = self.discount_strategy.calculate_discount(book.price)  
        return discounted_price
    

if __name__ == "__main__":  
    # 创建书籍对象  
    book = Book("The Great Gatsby", 30.0)  
      
    # 创建折扣策略对象  
    no_discount = NoDiscountStrategy()  
    regular_discount = RegularMemberDiscountStrategy()  
    gold_discount = GoldMemberDiscountStrategy()  
      
    # 创建书店对象，并设置不同的折扣策略  
    bookstore = Bookstore(no_discount)  
    print(f"No Discount: The final price of '{book.title}' is {bookstore.calculate_final_price(book)}")  
      
    bookstore.set_discount_strategy(regular_discount)  
    print(f"Regular Member Discount: The final price of '{book.title}' is {bookstore.calculate_final_price(book)}")  
      
    bookstore.set_discount_strategy(gold_discount)  
    print(f"Gold Member Discount: The final price of '{book.title}' is {bookstore.calculate_final_price(book)}")    