[
  {
    "path": ".gitignore",
    "content": ".idea/"
  },
  {
    "path": "README.md",
    "content": "# design-patterns\n《大话设计模式》中23种设计模式案例的Python版本实现。样例忠于原书，某些地方根据Python特性做了修改，如abstract、private、reflection等。\n\n\n## 读书笔记\n* [创建型模式](http://jennica.space/2016/12/28/design-patterns-creational/)\n* [结构型模式](http://jennica.space/2016/12/30/design-patterns-structural/)\n* [行为型模式](http://jennica.space/2017/01/03/design-patterns-behavioral/)\n\n## C++版\n[design-patterns-cpp](https://github.com/yogykwan/design-patterns-cpp)"
  },
  {
    "path": "abstract_factory.py",
    "content": "import abc\n\n\nclass User:\n    \"\"\"class user\"\"\"\n\n\nclass IUser:\n    __metaclass__ = abc.ABCMeta\n\n    @abc.abstractmethod\n    def insert_user(self, user):\n        \"\"\"insert user\"\"\"\n\n    @abc.abstractmethod\n    def get_user(self):\n        \"\"\"get user\"\"\"\n\n\nclass SqlserverUser(IUser):\n    def insert_user(self, user):\n        print \"Insert user into Sqlserver\"\n\n    def get_user(self):\n        print \"Get user from Sqlserver\"\n\n\nclass AccessUser(IUser):\n    def insert_user(self, user):\n        print \"Insert user into Access\"\n\n    def get_user(self):\n        print \"Get user from Access\"\n\n\nclass Department:\n    \"\"\"class department\"\"\"\n\n\nclass IDepartment:\n    __metaclass__ = abc.ABCMeta\n\n    @abc.abstractmethod\n    def insert_department(self, department):\n        \"\"\"insert department\"\"\"\n\n    def get_department(self):\n        \"\"\"get department\"\"\"\n\n\nclass SqlserverDepartment(IDepartment):\n    def insert_department(self, department):\n        print \"Insert department into Sqlserver\"\n\n    def get_department(self):\n        print \"Get department from Sqlserver\"\n\n\nclass AccessDepartment(IDepartment):\n    def insert_department(self, department):\n        print \"Insert department into Access\"\n\n    def get_department(self):\n        print \"Get department from Access\"\n\n\nclass IFactory:\n    __metaclass__ = abc.ABCMeta\n\n    @abc.abstractmethod\n    def create_user(self):\n        \"\"\"create user\"\"\"\n\n    @abc.abstractmethod\n    def create_department(self):\n        \"\"\"create deparment\"\"\"\n\n\nclass SqlserverFactory(IFactory):\n    def create_user(self):\n        return SqlserverUser()\n\n    def create_department(self):\n        return SqlserverDepartment()\n\n\nclass AccessFactory(IFactory):\n    def create_user(self):\n        return AccessUser()\n\n    def create_department(self):\n        return AccessDepartment()\n\n\nif __name__ == \"__main__\":\n    # use sqlserver to insert/get user/department\n    i_factory = SqlserverFactory()\n    i_user = i_factory.create_user()\n    i_user.insert_user(User())\n    i_user.get_user()\n    i_department = i_factory.create_department()\n    i_department.insert_department(Department())\n    i_department.get_department()\n\n    # use access to insert/get user/department\n    i_factory = AccessFactory()  # just replace SqlserverFactory with AccessFactory\n    i_user = i_factory.create_user()\n    i_user.insert_user(User())\n    i_user.get_user()\n    i_department = i_factory.create_department()\n    i_department.insert_department(Department())\n    i_department.get_department()\n"
  },
  {
    "path": "adapter.py",
    "content": "import abc\n\n\nclass Player:\n    __metaclass__ = abc.ABCMeta\n\n    def __init__(self, n):\n        self.name = n\n\n    @abc.abstractmethod\n    def attack(self):\n        \"\"\"attack\"\"\"\n\n    @abc.abstractmethod\n    def defense(self):\n        \"\"\"defense\"\"\"\n\n\nclass Center(Player):\n    def attack(self):\n        print \"center \" + self.name + \" attack\"\n\n    def defense(self):\n        print \"center \" + self.name + \" defense\"\n\n\nclass ForeignCenter:\n    def __init__(self, n):\n        self.name = n\n\n    def gong(self):\n        print \"foreign center \" + self.name + \" attack\"\n\n    def shou(self):\n        print \"foreign center \" + self.name + \" defense\"\n\n\nclass Translator(Player):\n    def __init__(self, n):\n        Player.__init__(self, n)\n        self.foreign_center = ForeignCenter(n)\n\n    def attack(self):\n        self.foreign_center.gong()\n\n    def defense(self):\n        self.foreign_center.shou()\n\n\nif __name__ == \"__main__\":\n    # center attack/defense\n    center = Center(\"Russell\")\n    center.attack()\n    center.defense()\n\n    # foreign center gong/shou through translator's attack/defense\n    translator = Translator(\"YaoMing\")\n    translator.attack()\n    translator.defense()\n"
  },
  {
    "path": "bridge.py",
    "content": "import abc\n\n\nclass HandsetSoft:\n    __metaclass__ = abc.ABCMeta\n\n    @abc.abstractmethod\n    def run(self):\n        \"\"\"soft run\"\"\"\n\n\nclass HandsetGame(HandsetSoft):\n    def run(self):\n        print \"run game\"\n\n\nclass HandsetAddressList(HandsetSoft):\n    def run(self):\n        print \"run address list\"\n\n\nclass HandsetBrand:\n    __metaclass__ = abc.ABCMeta\n\n    def __init__(self, s):\n        self.soft = s\n\n    @abc.abstractmethod\n    def run(self):\n        \"\"\"run\"\"\"\n\n\nclass HandsetBrandM(HandsetBrand):\n    def run(self):\n        print \"handset brand M : \",\n        self.soft.run()\n\n\nclass HandsetBrandN(HandsetBrand):\n    def run(self):\n        print \"handset brand N : \",\n        self.soft.run()\n\n\nif __name__ == \"__main__\":\n    handset_brand_m = HandsetBrandM(HandsetGame())\n    handset_brand_m.run()\n    handset_brand_m = HandsetBrandM(HandsetAddressList())\n    handset_brand_m.run()\n\n    handset_brand_n = HandsetBrandN(HandsetGame())\n    handset_brand_n.run()\n    handset_brand_n = HandsetBrandN(HandsetAddressList())\n    handset_brand_n.run()\n"
  },
  {
    "path": "builder.py",
    "content": "import abc\n\n\nclass Pen:\n    \"\"\"class pen\"\"\"\n\n\nclass Graphics:\n    \"\"\"class graphics\"\"\"\n\n\nclass PersonBuilder:\n    __metaclass__ = abc.ABCMeta\n\n    def __init__(self, p, g):\n        self.pen = p\n        self.grahics = g\n\n    @abc.abstractmethod\n    def BuildHead(self):\n        \"\"\"build head\"\"\"\n\n    @abc.abstractmethod\n    def BuildBody(self):\n        \"\"\"build body\"\"\"\n\n\nclass PersonThinBuilder(PersonBuilder):\n    def BuildHead(self):\n        print \"build thin head\"\n\n    def BuildBody(self):\n        print \"build thin body\"\n\n\nclass PersonFatBuilder(PersonBuilder):\n    def BuildHead(self):\n        print \"build fat head\"\n\n    def BuildBody(self):\n        print \"build fat body\"\n\n\nclass PersonDirector:\n    def __init__(self, pb):\n        self.person_builder = pb\n\n    def create_person(self):\n        self.person_builder.BuildHead()\n        self.person_builder.BuildBody()\n\n\nif __name__ == \"__main__\":\n    # build thin person\n    person_builder = PersonThinBuilder(Pen(), Graphics())\n    director = PersonDirector(person_builder)\n    director.create_person()\n\n    # build fat person\n    person_builder = PersonFatBuilder(Pen(), Graphics())  # only replace PersonThinBuilder with PersonFatBuilder\n    director = PersonDirector(person_builder)\n    director.create_person()\n"
  },
  {
    "path": "chain_of_responsibility.py",
    "content": "import abc\n\n\nclass Request:\n    def __init__(self, t, n):\n        self.type = t\n        self.number = n\n\n\nclass Manager:\n    __metaclass__ = abc.ABCMeta\n\n    def __init__(self, n):\n        self.name = n\n        self.superior = None\n\n    def set_superior(self, s):\n        self.superior = s\n\n    @abc.abstractmethod\n    def request_applications(self, r):\n        \"\"\"resolve request\"\"\"\n\n\nclass CommonManager(Manager):\n    def request_applications(self, r):\n        if r.type == \"leave application\" and r.number <= 2:\n            print self.name + \" : approve\"\n        else:\n            self.superior.request_applications(r)\n\n\nclass Majordomo(Manager):\n    def request_applications(self, r):\n        if r.type == \"leave application\" and r.number <= 5:\n            print self.name + \" : approve\"\n        else:\n            self.superior.request_applications(r)\n\n\nclass GeneralManager(Manager):\n    def request_applications(self, r):\n        if r.type == \"leave application\":\n            print self.name + \" : approve\"\n        elif r.type == \"salary increase\":\n            if r.number <= 500:\n                print self.name + \" : approve\"\n            else:\n                print self.name + \" : not approve\"\n\n\nif __name__ == \"__main__\":\n    common_manager = CommonManager(\"JingLi\")\n    majordomo = Majordomo(\"ZongJian\")\n    general_manager = GeneralManager(\"ZongJingLi\")\n    common_manager.set_superior(majordomo)\n    majordomo.set_superior(general_manager)\n\n    request = Request(\"leave application\", 4)\n    common_manager.request_applications(request)\n\n    request = Request(\"salary increase\", 1000)\n    common_manager.request_applications(request)\n"
  },
  {
    "path": "command.py",
    "content": "import abc\n\n\nclass Barbecuer(object):\n    def bake_mutton(self):\n        print \"bake mutton\"\n\n    def bake_chicken(self):\n        print \"bake chicken\"\n\n\nclass Command(object):\n    __metaclass__ = abc.ABCMeta\n\n    def __init__(self, r):\n        self.receiver = r\n\n    @abc.abstractmethod\n    def execute_command(self):\n        pass\n\n\nclass BakeMuttonCommand(Command):\n    def execute_command(self):\n        self.receiver.bake_mutton()\n\n\nclass BakeChickenCommand(Command):\n    def execute_command(self):\n        self.receiver.bake_chicken()\n\n\nclass Waiter(object):\n    def __init__(self):\n        self.commands = []\n\n    def set_order(self, o):\n        if isinstance(o, BakeChickenCommand):\n            print \"chicken sold out\"\n        else:\n            print \"add order: \" + type(o).__name__\n            self.commands.append(o)\n\n    def cancel_order(self, o):\n        print \"cancel order: \" + type(o).__name__\n        self.commands.remove(o)\n\n    def notify(self):\n        for command in self.commands:\n            command.execute_command()\n\n\nif __name__ == \"__main__\":\n    barbecuer = Barbecuer()\n    bake_mutton_command = BakeMuttonCommand(barbecuer)\n    bake_chicken_command = BakeChickenCommand(barbecuer)\n    waiter = Waiter()\n    waiter.set_order(bake_mutton_command)\n    waiter.set_order(bake_mutton_command)\n    waiter.set_order(bake_chicken_command)\n    waiter.notify()"
  },
  {
    "path": "composite.py",
    "content": "import abc\n\n\nclass Company:\n    __metaclass__ = abc.ABCMeta\n\n    def __init__(self, n):\n        self.name = n\n\n    @abc.abstractmethod\n    def add(self, c):\n        \"\"\"add\"\"\"\n\n    @abc.abstractmethod\n    def display(self, d):\n        \"\"\"display\"\"\"\n\n    @abc.abstractmethod\n    def line_of_duty(self):\n        \"\"\"duty line\"\"\"\n\n\nclass HrDepartment(Company):\n    def __init__(self, n):\n        Company.__init__(self, n)\n\n    def add(self, c):\n        print \"leaf can't add component\"\n\n    def display(self, d):\n        print \"--\" * d + self.name\n\n    def line_of_duty(self):\n        print self.name + \" : human resources\"\n\n\nclass FinanceDepartment(Company):\n    def __init__(self, n):\n        Company.__init__(self, n)\n\n    def add(self, c):\n        print \"leaf can't add component\"\n\n    def display(self, d):\n        print \"--\" * d + self.name\n\n    def line_of_duty(self):\n        print self.name + \" : finance analysis\"\n\n\nclass ConcreteCompany(Company):\n    def __init__(self, n):\n        Company.__init__(self, n)\n        self.companies = []\n\n    def add(self, c):\n        self.companies.append(c)\n\n    def display(self, d):\n        print \"--\" * d + self.name\n        for company in self.companies:\n            company.display(d + 1)\n\n    def line_of_duty(self):\n        for company in self.companies:\n            company.line_of_duty()\n\n\nif __name__ == \"__main__\":\n    beijing_head_office = ConcreteCompany(\"Beijing Head Office\")\n    beijing_head_office.add(HrDepartment(\"Beijing HR\"))\n    beijing_head_office.add(FinanceDepartment(\"Beijing Finance\"))\n\n    huadong_branch_office = ConcreteCompany(\"Huadong Branch Office\")\n    huadong_branch_office.add(HrDepartment(\"Huadong HR\"))\n    huadong_branch_office.add(FinanceDepartment(\"Huadong Finance\"))\n    beijing_head_office.add(huadong_branch_office)\n\n    nanjing_office = ConcreteCompany(\"Nanjing Office\")\n    nanjing_office.add(HrDepartment(\"Nanjing HR\"))\n    nanjing_office.add(FinanceDepartment(\"Nanjing Finance\"))\n    huadong_branch_office.add(nanjing_office)\n\n    hangzhou_office = ConcreteCompany(\"Hangzhou Office\")\n    hangzhou_office.add(HrDepartment(\"Hangzhou HR\"))\n    hangzhou_office.add(FinanceDepartment(\"Hangzhou Finance\"))\n    huadong_branch_office.add(hangzhou_office)\n\n    beijing_head_office.display(0)\n\n    beijing_head_office.line_of_duty()\n"
  },
  {
    "path": "decorator.py",
    "content": "import abc\n\n\nclass Person:\n    def show(self):\n        print \"person\"\n\n\nclass Finery(Person):\n    def __init__(self, c):\n        self.component = c\n\n    def show(self):\n        \"\"\"finery show\"\"\"\n\n\nclass Tie(Finery):\n    def show(self):\n        print \"tie \",\n        self.component.show()\n\n\nclass Suit(Finery):\n    def show(self):\n        print \"suit \",\n        self.component.show()\n\n\nclass Shoes(Finery):\n    def show(self):\n        print \"shoes \",\n        self.component.show()\n\n\nif __name__ == \"__main__\":\n    person = Person()\n    tie = Tie(person)\n    suit = Suit(tie)\n    shoes = Shoes(suit)\n    shoes.show()\n"
  },
  {
    "path": "facade.py",
    "content": "class Stock1:\n    def buy(self):\n        print \"buy stock1\"\n\n    def sell(self):\n        print \"sell stock1\"\n\n\nclass Stock2:\n    def buy(self):\n        print \"buy stock2\"\n\n    def sell(self):\n        print \"sell stock2\"\n\n\nclass Reality1:\n    def buy(self):\n        print \"buy reality1\"\n\n    def sell(self):\n        print \"sell reality1\"\n\n\nclass Fund:\n    def __init__(self):\n        self.stock1 = Stock1()\n        self.stock2 = Stock2()\n        self.reality1 = Reality1()\n\n    def buy(self):\n        self.stock1.buy()\n        self.stock2.buy()\n        self.reality1.buy()\n\n    def sell(self):\n        self.stock1.sell()\n        self.stock2.sell()\n        self.reality1.sell()\n\n\nif __name__ == \"__main__\":\n    fund = Fund()\n    fund.buy()\n    fund.sell()\n"
  },
  {
    "path": "factory_method.py",
    "content": "import abc\n\n\nclass Leifeng:\n    __metaclass__ = abc.ABCMeta\n\n    @abc.abstractmethod\n    def wash(self):\n        \"\"\"\"wash\"\"\"\n\n    @abc.abstractmethod\n    def sweep(self):\n        \"\"\"sweep\"\"\"\n\n    @abc.abstractmethod\n    def buy_rice(self):\n        \"\"\"buy rice\"\"\"\n\n\nclass Undergraduate(Leifeng):\n    def wash(self):\n        print \"undergraduate wash\"\n\n    def sweep(self):\n        print \"undergraduate sweep\"\n\n    def buy_rice(self):\n        print \"undergraduate buy rice\"\n\n\nclass Volunteer(Leifeng):\n    def wash(self):\n        print \"volunteer wash\"\n\n    def sweep(self):\n        print \"volunteer sweep\"\n\n    def buy_rice(self):\n        print \"volunteer buy rice\"\n\n\nclass IFactory:\n    __metaclass__ = abc.ABCMeta\n\n    @abc.abstractmethod\n    def CreateLeifeng(self):\n        \"\"\"create class leifeng\"\"\"\n\n\nclass UndergraduateFactory(IFactory):\n    def CreateLeifeng(self):\n        return Undergraduate()\n\n\nclass VolunteerFactory(IFactory):\n    def CreateLeifeng(self):\n        return Volunteer()\n\n\nif __name__ == \"__main__\":\n    # create undergraduate to sweep\n    i_factory = UndergraduateFactory()\n    leifeng = i_factory.CreateLeifeng()\n    leifeng.sweep()\n\n    # create volunteer to wash\n    i_factory = VolunteerFactory()  # just replace UndergraduateFactory with VolunteerFactory\n    leifeng = i_factory.CreateLeifeng()\n    leifeng.wash()\n"
  },
  {
    "path": "flyweight.py",
    "content": "import abc\n\n\nclass User:\n    def __init__(self, n):\n        self.name = n\n\n\nclass Website:\n    __metaclass__ = abc.ABCMeta\n\n    @abc.abstractmethod\n    def use(self, u):\n        \"\"\"users use website\"\"\"\n\n\nclass ConcreteWebsite(Website):\n    def __init__(self, wn):\n        self.website_name = wn\n\n    def use(self, u):\n        print u.name + \" use \" + self.website_name\n\n\nclass WebsiteFactory:\n    flyweights = {}\n\n    def get_website_category(self, n):\n        if self.flyweights.has_key(n) is False:\n            self.flyweights[n] = ConcreteWebsite(n)\n        return self.flyweights[n]\n\n    def get_website_count(self):\n        print len(self.flyweights.keys())\n\n\nif __name__ == \"__main__\":\n    website_factory = WebsiteFactory()\n    alice = User(\"Alice\")\n    bob = User(\"Bob\")\n\n    website = website_factory.get_website_category(\"bbs\")\n    website.use(alice)\n    website.use(bob)\n    website_factory.get_website_count()\n\n    website = website_factory.get_website_category(\"blog\")\n    website.use(alice)\n    website.use(bob)\n    website_factory.get_website_count()\n\n    website = website_factory.get_website_category(\"bbs\")\n    website.use(alice)\n    website.use(bob)\n    website_factory.get_website_count()\n"
  },
  {
    "path": "interpreter.py",
    "content": "import abc\n\n\nclass Context(object):\n    def __init__(self, t):\n        self.text = t\n\n\nclass Expression(object):\n    def interpret(self, c):\n        text = c.text.split(' ')\n        key = text[0]\n        value = float(text[1])\n        c.text = ' '.join(text[2:])\n        self.execute(key, value)\n\n    @abc.abstractmethod\n    def execute(self, k, v):\n        pass\n\n\nclass Scale(Expression):\n    def execute(self, k, v):\n        scale_dic = {1: 'bass', 2: 'alto', 3: 'treble'}\n        print scale_dic[v] + \" \",\n\n\nclass Note(Expression):\n    def execute(self, k, v):\n        print k + \" \",\n\n\nclass ExpressionFactory(object):\n    @staticmethod\n    def create_expression(t):\n        type = \"Scale\" if t == 'O' else \"Note\"\n        obj = globals()[type]()\n        return obj\n\n\nif __name__ == \"__main__\":\n    context = Context(\"O 2 E 0.5 G 0.5 A 3\")\n    while len(context.text):\n        expression = ExpressionFactory.create_expression(context.text[0])\n        expression.interpret(context)\n\n"
  },
  {
    "path": "iterator.py",
    "content": "import abc\n\n\nclass Aggregate:\n    __metaclass__ = abc.ABCMeta\n\n    @abc.abstractmethod\n    def create_iterator(self):\n        \"\"\"create iterator\"\"\"\n\n\nclass List(Aggregate):\n    def __init__(self):\n        self.items = []\n\n    def create_iterator(self):\n        return ListIterator(self)\n\n    def count(self):\n        return len(self.items)\n\n    def __setitem__(self, key, value):\n        if key >= len(self.items):\n            self.items.append(value)\n        else:\n            self.items[key] = value\n\n    def __getitem__(self, i):\n        return self.items[i]\n\n\nclass Iterator:\n    __metaclass__ = abc.ABCMeta\n\n    @abc.abstractmethod\n    def first_item(self):\n        \"\"\"\"\"\"\n\n    @abc.abstractmethod\n    def next_item(self):\n        \"\"\"\"\"\"\n\n    @abc.abstractmethod\n    def is_done(self):\n        \"\"\"\"\"\"\n\n    @abc.abstractmethod\n    def current_item(self):\n        \"\"\"\"\"\"\n\nclass ListIterator(Iterator):\n    def __init__(self, a):\n        self.current = 0\n        self.aggregate = a\n\n    def first_item(self):\n        return self.aggregate[0]\n\n    def next_item(self):\n        result = None\n        self.current += 1\n        if self.current < self.aggregate.count():\n            result = self.aggregate[self.current]\n        return result\n\n    def is_done(self):\n        return self.current >= self.aggregate.count()\n\n    def current_item(self):\n        return self.aggregate[self.current]\n\n\nif __name__ == \"__main__\":\n    list = List()\n    list[0] = 1\n    list[1] = 2\n    list[2] = 3\n    list_iterator = list.create_iterator()\n    print list_iterator.first_item()\n    print list_iterator.current_item()\n    print list_iterator.next_item()\n    print list_iterator.next_item()\n    print list_iterator.is_done()\n    print list_iterator.next_item()\n    print list_iterator.is_done()\n\n\n\n"
  },
  {
    "path": "mediator.py",
    "content": "import abc\n\n\nclass Country(object):\n    __metaclass__ = abc.ABCMeta\n\n    def __init__(self, un):\n        self.un = un\n\n    def declare(self, m):\n        self.un.declare(self, m)\n\n    @abc.abstractmethod\n    def get_message(self, m):\n        pass\n\n\nclass Usa(Country):\n    def get_message(self, m):\n        print \"USA gets: \\\"\" + m + \"\\\"\"\n\n\nclass Iraq(Country):\n    def get_message(self, m):\n        print \"Iraq gets: \\\"\" + m + \"\\\"\"\n\n\nclass UnitedNations:\n    __metaclass__ = abc.ABCMeta\n\n    @abc.abstractmethod\n    def declare(self, c, m):\n        pass\n\n\nclass SecurityCouncil(UnitedNations):\n    def __init__(self):\n        self.usa = None\n        self.iraq = None\n\n    def declare(self, c, m):\n        if c == self.usa:\n            self.iraq.get_message(m)\n        elif c == self.iraq:\n            self.usa.get_message(m)\n        else:\n            print \"err: SecurityCouncil/declare\"\n\n\nif __name__ == \"__main__\":\n    security_council = SecurityCouncil()\n    usa = Usa(security_council)\n    iraq = Iraq(security_council)\n    security_council.usa = usa\n    security_council.iraq = iraq\n    usa.declare(\"Stop nuclear weapons\")\n    iraq.declare(\"No nuclear here\")"
  },
  {
    "path": "memento.py",
    "content": "class StateMemento(object):\n    def __init__(self, h, m):\n        self.hp = h\n        self.mp = m\n\n\nclass GameRole(object):\n    def __init__(self):\n        self.hp = 100\n        self.mp = 100\n\n    def fight(self):\n        self.hp = 0\n        self.mp = 0\n\n    def create_memento(self):\n        return StateMemento(self.hp, self.mp)\n\n    def recovery_state(self, m):\n        self.hp = m.hp\n        self.mp = m.mp\n\n    def state_display(self):\n        print str(self.hp) + \" \" + str(self.mp)\n\n\nclass StateCaretaker(object):\n    def __init__(self, m):\n        self.__memento = m  # .__memento ==> ._StateCaretaker__memento (Name Mangling)\n\n    def get_memento(self):\n        return self.__memento\n\n\nif __name__ == \"__main__\":\n    game_role = GameRole()\n    state_caretaker = StateCaretaker(game_role.create_memento())\n    game_role.state_display()\n\n    game_role.fight()\n    game_role.state_display()\n\n    game_role.recovery_state(state_caretaker.get_memento())\n    game_role.state_display()"
  },
  {
    "path": "observer.py",
    "content": "import abc\n\n\nclass Observer:\n    __metaclass__ = abc.ABCMeta\n\n    def __init__(self, n, nr):\n        self.name = n\n        self.notifier = nr\n\n    @abc.abstractmethod\n    def update(self):\n        \"\"\"updated by notifier\"\"\"\n\n\nclass NbaObserver(Observer):\n    def update(self):\n        print self.name + \", \" + self.notifier.state + \", close NBA\"\n\n\nclass StockObserver(Observer):\n    def update(self):\n        print self.name + \", \" + self.notifier.state + \", close stock\"\n\n\nclass Notifier:\n    def __init__(self):\n        self.observers = []\n        self.state = \"\"\n\n    def attach(self, o):\n        self.observers.append(o)\n\n    def detach(self, o):\n        self.observers.remove(o)\n\n    def notify(self):\n        for observer in self.observers:\n            observer.update()\n\n\nclass Boss(Notifier):\n    pass\n\n\nclass Secretary(Notifier):\n    pass\n\n\nif __name__ == \"__main__\":\n    boss = Boss()\n    nba_observer = NbaObserver(\"Bob\", boss)\n    boss.attach(nba_observer)\n    stock_observer = StockObserver(\"Alice\", boss)\n    boss.attach(stock_observer)\n    boss.state = \"boss's back himself\"\n    boss.notify()\n"
  },
  {
    "path": "prototype.py",
    "content": "import copy\n\n\nclass WorkExperience:\n    def __init__(self):\n        self.company = \"\"\n        self.time_area = \"\"\n\n\nclass Resume:\n    def __init__(self, n):\n        self.name = n\n        self.work_experience = WorkExperience()\n\n    def set_personal_info(self, s, a):\n        self.sex = s\n        self.age = a\n\n    def set_work_experience(self, c, ta):\n        self.work_experience.company = c\n        self.work_experience.time_area = ta\n\n    def print_resume(self):\n        print self.name + \", \" + self.sex + \", \" + self.age + \", \" \\\n              + self.work_experience.company + \" : \" + self.work_experience.time_area\n\n    def clone(self):\n        new_resume = copy.deepcopy(self)\n        new_resume.work_experience = copy.deepcopy(self.work_experience)\n        return new_resume\n\n\nif __name__ == \"__main__\":\n    resume1 = Resume(\"Bob\")\n    resume1.set_personal_info(\"M\", \"24\")\n    resume1.set_work_experience(\"Google\", \"2015\")\n    resume2 = resume1\n    resume2.set_personal_info(\"F\", \"22\")\n    resume2.set_work_experience(\"Twitter\", \"2015\")\n    resume1.print_resume()\n    resume2.print_resume()\n\n    resume1 = Resume(\"Bob\")\n    resume1.set_personal_info(\"M\", \"24\")\n    resume1.set_work_experience(\"Google\", \"2015\")\n    resume2 = copy.copy(resume1)\n    resume2.set_personal_info(\"F\", \"22\")\n    resume2.set_work_experience(\"Twitter\", \"2015\")\n    resume1.print_resume()\n    resume2.print_resume()\n\n    resume1 = Resume(\"Bob\")\n    resume1.set_personal_info(\"M\", \"24\")\n    resume1.set_work_experience(\"Google\", \"2015\")\n    resume2 = copy.deepcopy(resume1)\n    resume2.set_personal_info(\"F\", \"22\")\n    resume2.set_work_experience(\"Twitter\", \"2015\")\n    resume1.print_resume()\n    resume2.print_resume()\n\n    resume1 = Resume(\"Bob\")\n    resume1.set_personal_info(\"M\", \"24\")\n    resume1.set_work_experience(\"Google\", \"2015\")\n    resume2 = resume1.clone()\n    resume2.set_personal_info(\"F\", \"22\")\n    resume2.set_work_experience(\"Twitter\", \"2015\")\n    resume1.print_resume()\n    resume2.print_resume()\n"
  },
  {
    "path": "proxy.py",
    "content": "import abc\n\n\nclass GiveGift:\n    __metaclass__ = abc.ABCMeta\n\n    @abc.abstractmethod\n    def __init__(self, sg):\n        \"\"\"init\"\"\"\n\n    @abc.abstractmethod\n    def give_dolls(self):\n        \"\"\"give dolls\"\"\"\n\n    @abc.abstractmethod\n    def give_flowers(self):\n        \"\"\"give flowers\"\"\"\n\n\nclass SchoolGirl:\n    def __init__(self, n):\n        self.name = n\n\n\nclass Pursuit(GiveGift):\n    def __init__(self, sg):\n        GiveGift.__init__(self, sg)\n        self.school_girl = sg\n\n    def give_dolls(self):\n        print \"give \" + self.school_girl.name + \" dolls\"\n\n    def give_flowers(self):\n        print \"give \" + self.school_girl.name + \" flowers\"\n\n\nclass Proxy(GiveGift):\n    def __init__(self, sg):\n        GiveGift.__init__(self, sg)\n        self.pursuit = Pursuit(sg)\n\n    def give_dolls(self):\n        self.pursuit.give_dolls()\n\n    def give_flowers(self):\n        self.pursuit.give_flowers()\n\n\nif __name__ == \"__main__\":\n    school_girl = SchoolGirl(\"Alice\")\n    proxy = Proxy(school_girl)\n    proxy.give_flowers()\n    proxy.give_dolls()\n"
  },
  {
    "path": "singleton.py",
    "content": "import threading\n\n\nclass Singleton(object):\n    instance = None\n    lock = threading.RLock()\n\n    @classmethod\n    def __new__(cls):\n        if cls.instance is None:\n            cls.lock.acquire()\n            if cls.instance is None:\n                cls.instance = super(Singleton, cls).__new__(cls)\n            cls.lock.release()\n        return cls.instance\n\n\nif __name__ == \"__main__\":\n    instance1 = Singleton()\n    instance2 = Singleton()\n    print id(instance1) == id(instance2)\n"
  },
  {
    "path": "state.py",
    "content": "import abc\n\n\nclass Work:\n    def __init__(self, h, f):\n        self.hour = h\n        self.finished = f\n        self.state = WorkingState()\n\n    def set_state(self, s):\n        self.state = s\n\n    def write_program(self):\n        self.state.write_program(self)\n\n\nclass State:\n    __metaclass__ = abc.ABCMeta\n\n    @abc.abstractmethod\n    def write_program(self, w):\n        \"\"\"write program according to workstate\"\"\"\n\n\nclass RestState(State):\n    def write_program(self, w):\n        print str(w.hour) + \" : return to rest\"\n\n\nclass SleepingState(State):\n    def write_program(self, w):\n        print str(w.hour)+ \" : sleeping\"\n\n\nclass OvertimeState(State):\n    def write_program(self, w):\n        if w.finished is True:\n            w.set_state(RestState())\n            w.write_program()\n        elif w.hour < 21:\n            print str(w.hour) + \" : overtime\"\n        else:\n            w.set_state(SleepingState())\n            w.write_program()\n\n\nclass WorkingState(State):\n    def write_program(self, w):\n        if w.hour < 17:\n            print str(w.hour) + \" : working\"\n        else:\n            w.set_state(OvertimeState())\n            w.write_program()\n\n\nif __name__ == \"__main__\":\n    work = Work(15, False)\n    work.write_program()\n\n    work = Work(20, False)\n    work.write_program()\n\n    work = Work(22, False)\n    work.write_program()\n\n    work = Work(20, True)\n    work.write_program()"
  },
  {
    "path": "strategy.py",
    "content": "import abc\n\n\nclass CashSuper:\n    __metaclass__ = abc.ABCMeta\n\n    @abc.abstractmethod\n    def accept_cash(self, c):\n        \"\"\"caculate cash\"\"\"\n\n\nclass CashNormal(CashSuper):\n    def accept_cash(self, c):\n        return c\n\n\nclass CashRebate(CashSuper):\n    def __init__(self, r):\n        self.rebate = r\n\n    def accept_cash(self, c):\n        return c * self.rebate\n\n\nclass CashReturn(CashSuper):\n    def __init__(self, c, r):\n        self.condition = c\n        self.money = r\n\n    def accept_cash(self, c):\n        return c - int(c / self.condition) * self.money\n\n\nclass CashContext:\n    def __init__(self, t, s):\n        self.cash = None\n        if t == \"normal\":\n            self.cash = CashNormal()\n        elif t == \"rebate\":\n            self.cash = CashRebate(float(s))\n        elif t == \"return\":\n            args = s.split(' ')\n            self.cash = CashReturn(float(args[0]), float(args[1]))\n\n    def get_result(self, c):\n        return self.cash.accept_cash(c)\n\n\nif __name__ == \"__main__\":\n    cash_context = CashContext(\"normal\", \"\")\n    print cash_context.get_result(1000)\n\n    cash_context = CashContext(\"rebate\", \"0.8\")\n    print cash_context.get_result(1000)\n\n    cash_context = CashContext(\"return\", \"300 100\")\n    print cash_context.get_result(1000)\n"
  },
  {
    "path": "template_method.py",
    "content": "import abc\n\n\nclass ExamPaper(object):\n    __metaclass__ = abc.ABCMeta\n\n    def question1(self):\n        print \"question1: \" + self.answer1()\n\n    @abc.abstractmethod\n    def answer1(self):\n        return \"\"\n\n    def question2(self):\n        print \"question2: \" + self.answer2()\n\n    @abc.abstractmethod\n    def answer2(self):\n        return \"\"\n\n    def question3(self):\n        print \"question3: \" + self.answer3()\n\n    @abc.abstractmethod\n    def answer3(self):\n        return \"\"\n\n\nclass ExamPaperA(ExamPaper):\n    def answer1(self):\n        return \"a\"\n\n    def answer2(self):\n        return \"a\"\n\n    def answer3(self):\n        return \"b\"\n\n\nclass ExamPaperB(ExamPaper):\n    def answer1(self):\n        return \"b\"\n\n    def answer2(self):\n        return \"b\"\n\n    def answer3(self):\n        return \"c\"\n\n\nif __name__ == \"__main__\":\n    test_paper = ExamPaperA()\n    print \"Paper A:\"\n    test_paper.question1()\n    test_paper.question2()\n    test_paper.question3()\n\n    print \"Paper B:\"\n    test_paper = ExamPaperB()\n    test_paper.question1()\n    test_paper.question2()\n    test_paper.question3()\n"
  },
  {
    "path": "visitor.py",
    "content": "import abc\n\n\nclass Action(object):\n    __metaclass__ = abc.ABCMeta\n\n    @abc.abstractmethod\n    def get_man_conclusion(self, p):\n        pass\n\n    @abc.abstractmethod\n    def get_woman_conclusion(self, p):\n        pass\n\n\nclass Success(Action):\n    def get_man_conclusion(self, p):\n        print \"man success\"\n\n    def get_woman_conclusion(self, p):\n        print \"woman success\"\n\n\nclass Failure(Action):\n    def get_man_conclusion(self, p):\n        print \"man failure\"\n\n    def get_woman_conclusion(self, p):\n        print \"woman failure\"\n\n\nclass Person(object):\n    __metaclass__ = abc.ABCMeta\n\n    @abc.abstractmethod\n    def accept(self, a):\n        pass\n\n\nclass Man(Person):\n    def accept(self, a):\n        a.get_man_conclusion(self)\n\n\nclass Woman(Person):\n    def accept(self, a):\n        a.get_woman_conclusion(self)\n\n\nclass ObjectStructure(object):\n    def __init__(self):\n        self.people = []\n\n    def attach(self, p):\n        self.people.append(p)\n\n    def detach(self, p):\n        self.people.remove(p)\n\n    def display(self, a):\n        for person in self.people:\n            person.accept(a)\n\n\nif __name__ == \"__main__\":\n    man = Man()\n    woman = Woman()\n    object_structure = ObjectStructure()\n    object_structure.attach(man)\n    object_structure.attach(woman)\n    object_structure.display(Success())\n    object_structure.display(Failure())\n"
  }
]