strategy pattern in Python

1.function based
#!/usr/bin/env python

import types

def method_property(name):
    def getter(self):
        return getattr(self, name)
    def setter(self, value):
        setattr(self, name, types.MethodType(value, self))
    return getter, setter

class Duck(object):
    def __init__(self, fly, quack):
        self.fly = fly
        self.quack = quack

    quack = property(*method_property("_quack"))
    fly = property(*method_property("_fly"))

    def swim(self):
        print "All ducks float, even decoys!"

class MallardDuck(Duck):
    def __init__(self):
        Duck.__init__(self, fly, quack)
        print "I'm a real Mallard Duck"

class ModelDuck(Duck):
    def __init__(self):
        Duck.__init__(self, fly_no_way, squeak_quack)
        print "I'm a Model Duck"

class DecoyDuck(Duck):
    def __init__(self):
        Duck.__init__(self, fly_no_way, mute_quack)
        print "I'm a Decoy Duck"

def fly(self):
    print "I'm flying!!"

def fly_no_way(self):
    print "I can't fly"

def fly_rocket_powered(self):
    print "I'm flying with a rocket!"

def quack(self):
    print "Quack"

def mute_quack(self):
    print "<< Silence >>"

def squeak_quack(self):
    print "Squeak"

if __name__ == "__main__":

    print '#'*80
    print "Mallard Duck"
    print '#'*80
    mallard = MallardDuck()
    mallard.quack()
    mallard.fly()

    print '#'*80
    print "Model Duck"
    print '#'*80
    model = ModelDuck()
    model.fly()
    model.fly = fly_rocket_powered
    model.fly()

    print '#'*80
    print "Decoy Duck"
    print '#'*80
    decoy = DecoyDuck()
    decoy.fly()
    decoy.quack()
2.class based
#!/usr/bin/env python

from abc import ABCMeta, abstractmethod

def subclasshook(required):
    """Generates a subclass hook based on a simple check for attributes."""
    def __subclasshook__(cls, Check):
        rtn = True
        for r in required:
            if not any(r in vars(BaseClass) for BaseClass in Check.__mro__):
                rtn = NotImplemented
        return rtn
    return __subclasshook__

class Duck(object):
    def __init__(self, fly, quack):
        self._fly_behaviour = fly
        self._quack_behaviour = quack

    def fly(self):
        return self._fly_behaviour.fly()

    def quack(self):
        return self._quack_behaviour.quack()

    def swim(self):
        print "All ducks float, even decoys!"

class MallardDuck(Duck):
    def __init__(self):
        Duck.__init__(self, Fly(), Quack())
        print "I'm a real Mallard Duck"

class ModelDuck(Duck):
    def __init__(self):
        Duck.__init__(self, FlyNoWay(), SqueakQuack())
        print "I'm a Model Duck"

class DecoyDuck(Duck):
    def __init__(self):
        Duck.__init__(self, FlyNoWay(), MuteQuack())
        print "I'm a Decoy Duck"

class FlyBehavior:
    __metaclass__ = ABCMeta

    @abstractmethod
    def fly(self):
        pass

    __subclasshook__ = classmethod(subclasshook(["fly"]))

class Fly(FlyBehavior):
    def fly(self):
        print "I'm flying!!"

class FlyNoWay(FlyBehavior):
    def fly(self):
        print "I can't fly"

class FlyRocketPowered(FlyBehavior):
    def fly(self):
        print "I'm flying with a rocket!"

class QuackBehavior:
    __metaclass__ = ABCMeta

    @abstractmethod
    def quack(self):
        pass

    __subclasshook__ = classmethod(subclasshook(["quack"]))

class Quack(QuackBehavior):
    def quack(self):
        print "Quack"

class MuteQuack(QuackBehavior):
    def quack(self):
        print "<< Silence >>"

class SqueakQuack(QuackBehavior):
    def quack(self):
        print "Squeak"

if __name__ == "__main__":

    print '#'*80
    print "Mallard Duck"
    print '#'*80
    mallard = MallardDuck()
    mallard.quack()
    mallard.fly()

    print '#'*80
    print "Model Duck"
    print '#'*80
    model = ModelDuck()
    model.fly()
    model._fly_behaviour = FlyRocketPowered()
    model.fly()

    print '#'*80
    print "Decoy Duck"
    print '#'*80
    decoy = DecoyDuck()
    decoy.fly()
    decoy.quack()



(a) The Book Seller System should have the following functions: - Add book to inventory - Remove book from inventory - Search for book in inventory - Sell book to customer - Calculate the price of a book based on the client's membership level (b) There are three kinds of clients: - VIPMember: gets a 10% discount (0.9 * price) - NormalMember: gets no discount (1 * price) - SuperMember: gets a 20% discount (0.8 * price) (c) The strategy pattern will be used to define the different discount strategies for each type of client. (d) UML class diagram with the strategy pattern: ``` +-------------------------+ +------------------------+ | BookSeller | | MemberStrategy | +-------------------------+ +------------------------+ | - inventory: List<Book> | | +calculatePrice(price) | +-------------------------+ +------------------------+ | +addBook(book: Book) | ^ | +removeBook(book: Book) | | | +searchBook(title: str) | | | +sellBook(client: Member, | | | book: Book) | +------------------------+ +-------------------------+ | VIPMemberStrategy | +------------------------+ | +calculatePrice(price) | +------------------------+ | NormalMemberStrategy | +------------------------+ | +calculatePrice(price) | +------------------------+ | SuperMemberStrategy | +------------------------+ | +calculatePrice(price) | +------------------------+ ``` (e) Code for each class: ```python class Book: def __init__(self, title, author, price): self.title = title self.author = author self.price = price class Member: def __init__(self, name, strategy): self.name = name self.strategy = strategy def setStrategy(self, strategy): self.strategy = strategy class MemberStrategy: def calculatePrice(self, price): pass class VIPMemberStrategy(MemberStrategy): def calculatePrice(self, price): return price * 0.9 class NormalMemberStrategy(MemberStrategy): def calculatePrice(self, price): return price class SuperMemberStrategy(MemberStrategy): def calculatePrice(self, price): return price * 0.8 class BookSeller: def __init__(self): self.inventory = [] def addBook(self, book): self.inventory.append(book) def removeBook(self, book): self.inventory.remove(book) def searchBook(self, title): for book in self.inventory: if book.title == title: return book return None def sellBook(self, client, book): price = book.price price = client.strategy.calculatePrice(price) print("Selling book {} to {} for price: {}".format(book.title, client.name, price)) # Example usage book1 = Book("Harry Potter", "J.K. Rowling", 200) book2 = Book("Lord of the Rings", "J.R.R. Tolkien", 150) vip = Member("Tom", VIPMemberStrategy()) normal = Member("John", NormalMemberStrategy()) super = Member("Mike", SuperMemberStrategy()) seller = BookSeller() seller.addBook(book1) seller.addBook(book2) seller.sellBook(vip, book1) # Selling book Harry Potter to Tom for price: 180.0 seller.sellBook(normal, book2) # Selling book Lord of the Rings to John for price: 150 seller.sellBook(super, book1) # Selling book Harry Potter to Mike for price: 160.0 ``` (f) Test class: ```python class Test: def main(): book1 = Book("Harry Potter", "J.K. Rowling", 200) book2 = Book("Lord of the Rings", "J.R.R. Tolkien", 150) vip = Member("Tom", VIPMemberStrategy()) normal = Member("John", NormalMemberStrategy()) super = Member("Mike", SuperMemberStrategy()) seller = BookSeller() seller.addBook(book1) seller.addBook(book2) seller.sellBook(vip, book1) # Selling book Harry Potter to Tom for price: 180.0 seller.sellBook(normal, book2) # Selling book Lord of the Rings to John for price: 150 seller.sellBook(super, book1) # Selling book Harry Potter to Mike for price: 160.0 Test.main() ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值