import pdb import datetime import time #----------------------- some common classes ----------------------- class ARobot(): def what_can_i_do(self): Error = ("It must be a mistake, I don't know nothing!") print(Error) raise NotImplementedError(Error) class ChessRobot(ARobot): def __init__(self): self.chess = 'black' def what_can_i_do(self): return "I can play chess~" class CookRobot(ARobot): def __init__(self): self._cook_level = 3 def what_can_i_do(self): return "I can cook~" #----------------------- abstract factory starts ----------------------- class AbstractRobotFactory(): def make_a_robot(self): Error = "I never make anything!" print(Error) raise NotImplementedError(Error) class ChessRobotFactory(AbstractRobotFactory): def make_a_robot(self): return ChessRobot() class CookRobotFactory(AbstractRobotFactory): def make_a_robot(self): return CookRobot() #--- abstract factory ends --- #abstract factory shower def ShowAbstractFactory(): """ This demo shows a abstract robot factory model, which can be instantiated to: chess robot factory, cook robot factory, manufacture robot factory etc. the concrete factories will make different types of robots. """ try: factory = CookRobotFactory() robot = factory.make_a_robot() print(robot.what_can_i_do()) factory = AbstractRobotFactory() robot = factory.make_a_robot() print(robot.what_can_i_do()) except NotImplementedError: print("Abstract class is getting instantiated...") #----------------------- builder starts ----------------------- class BuilderRobotFactory(): def __init__(self): self._builder = None def set_builder(self, builder): self._builder = builder def make_a_robot(self): if self._builder is None: print("I do not know which builder to use yet...") return None else: return self._builder.make() class CookRobotBuilder(): def make(self): return CookRobot() #--- builder ends --- #builder shower def ShowBuilder(): """ This demo shows a robot factory model that uses different builders to build different robots. """ builder = CookRobotBuilder() factory = BuilderRobotFactory() robot = factory.make_a_robot() factory.set_builder(builder) robot = factory.make_a_robot() print(robot.what_can_i_do()) #----------------------- factory starts ----------------------- class CookRobotFactory(): def make_a_robot(self): return CookRobot() #--- factory ends --- #factory shower def ShowFactory(): factory = CookRobotFactory() robot = factory.make_a_robot() print(robot.what_can_i_do()) #----------------------- prototype starts ----------------------- class CloneBot(): def __init__(self, birthday, height, weight, battery_type): self._birthday = birthday self._height = height self._weight = weight self._battery_type = battery_type def clone(self): return CloneBot(birthday = datetime.datetime.now(), height = self._height, weight = self._weight, battery_type = self._battery_type) def report(self): return "Sir! I was made on %s." % self._birthday +\ "I use %s battery." % self._battery_type #--- prototype ends --- #prototype shower def ShowPrototype(): """ This demo shows a cloneable robot that is able to clone itself and returns the replica. Prototype is useful when creating the object(robot) is either expensive or complicated """ robot = CloneBot(birthday = datetime.datetime.now(), height = 170, weight = 200, battery_type = 'AAA') robot1 = robot.clone() time.sleep(1) robot2 = robot.clone() robot1.report() robot2.report() #----------------------- singleton starts ----------------------- def singleton(cls): instances = {} def getinstance(): if cls not in instances: instances[cls] = cls() return instances[cls] return getinstance @singleton class UniBot(): def set_key(self, key): self._key = key def get_key(self): return self._key #--- singleton ends --- #singleton shower def ShowSingleton(): """ This demo shows a robot that only one instance of itself exists. Any number of 'objects' created by UniBot() is just a reference to the first created UniBot. The decorator design is from the example of PEP318 """ robot1 = UniBot() robot2 = UniBot() robot1.set_key("ciao") print(robot2.get_key()) #----------------------- adapter starts ----------------------- class ARobot2(): """ a bit more advanced version of ARobot """ def __init__(self, name, gender): self._name = name self._gender = gender def introduce(self): print("Hello I am %(name)s, %(gender)s" % {'name': self._name, 'gender': self._gender}) class OldRobotAdapter(ARobot2): def __init__(self, robot): self._robot = robot #adapt the old function for new use def introduce(self): print("Hello I am an old robot.\n" + "I have no name and gender, but"), print(self._robot.what_can_i_do()) def get_robot_class(self): return self._robot.__class__ #every thing else the new robot does have will delegated to the old def __getattr__(self, attr): return getattr(self._robot, attr) #--- adapter ends --- #adapter shower def ShowAdapter(): """ This demo shows an adapter that help the 'old' robots pass the basic test to Advanced robots """ robot = ARobot2(name = 'John', gender = 'Male') robot.introduce() old_robot = OldRobotAdapter(ChessRobot()) old_robot.introduce() if old_robot.get_robot_class() is ChessRobot: print("I have %s chess, too!" % old_robot.chess) #----------------------- bridge starts ----------------------- #--- bridge ends --- #bridge shower def ShowBridge(): """ In Python this pattern is well supported, as there is no need to access concrete objects via a parent class pointer Factories are different implelementations, while the 'what_can_i_do' method has different interfaces. """ factory = CookRobotFactory() robot = factory.make_a_robot() print(robot.what_can_i_do()) factory = ChessRobotFactory() robot = factory.make_a_robot() print(robot.what_can_i_do()) #----------------------- composite starts ----------------------- class RobotContainer(): def __init__(self): self._list = list() def combine(self, robot): self._list.append(robot) def what_can_i_do(self): if self._list == []: yield "I can do nothing..." else: for robot in self._list: yield robot.what_can_i_do() class CookCombinerFactory(): def make_a_robot(self): return CookCombinerRobot() class ChessCombinerFactory(): def make_a_robot(self): return ChessCombinerRobot() #--- composite ends --- #composite shower def ShowComposite(): """ This demo shows a robot combiner (yes! like the combiners in Transformers!). Either single robot or a combination of robots behaves with the same interfaces, though the later is stronger =) """ factory = CookRobotFactory() cook_robot = factory.make_a_robot() print(cook_robot.what_can_i_do()) factory = ChessRobotFactory() chess_robot = factory.make_a_robot() print(chess_robot.what_can_i_do()) combiner = RobotContainer() for capability in combiner.what_can_i_do(): print(capability) combiner.combine(cook_robot) for capability in combiner.what_can_i_do(): print(capability) combiner.combine(chess_robot) for capability in combiner.what_can_i_do(): print(capability) #----------------------- decorator starts ----------------------- class Weapon(object): def __init__(self, weapon = None): self._list = list() self._list.append(self) if weapon is not None: self._list.extend(weapon.get_weapon_list()) def get_weapon_list(self): return self._list class ShotGun(Weapon): def __init__(self, weapon = None): self._name = 'ShotGun' super(ShotGun, self).__init__(weapon) def get_weapon_list(self): return super(ShotGun, self).get_weapon_list() class LaserGun(Weapon): def __init__(self, weapon = None): self._name = 'LaserGun' super(LaserGun, self).__init__(weapon) def get_weapon_list(self): return super(LaserGun, self).get_weapon_list() class FightBot(): def __init__(self, weapon = None): self._weapon_list = list() self.name = "FightBot" if weapon is not None: self._weapon_list = weapon.get_weapon_list() def show_off(self): return "come and see my weapons! I have " +\ " and ".join([x._name for x in self._weapon_list]) def go(self): print('YEAH, go and KILL!') #--- decorator ends --- #decorator shower def ShowDecorator(): """ Seems like this pattern is nothing but having a proxy managing a series of components for a series of jobs. This demo shows how a robot can be armed with multiple weapons, by adding them at runtime. """ robot = FightBot(ShotGun(LaserGun())) print(robot.show_off()) #----------------------- facade starts ----------------------- class RobotController(): def __init__(self, robot): self._robot = robot def start_robot(self): print('name: ' + self._robot.name) print(self._robot.show_off()) self._robot.go() #--- facade ends --- #facade shower def ShowFacade(): """ This demo shows a remote controller sending commands to a robot, which will perform a series of operations """ robot = FightBot(ShotGun(LaserGun())) controller = RobotController(robot) controller.start_robot() if __name__ == '__main__': #ShowAbstractFactory() #ShowBuilder() #ShowFactory() #ShowPrototype() #ShowSingleton() #ShowAdapter() #ShowComposite() #ShowDecorator() #ShowBridge() ShowFacade() #print a list of the dp that's been implemented #select a dp and start the demo #eacho dp should be an independent class, correct?
Run
Reset
Share
Import
Link
Embed
Language▼
English
中文
Python Fiddle
Python Cloud IDE
Follow @python_fiddle
Browser Version Not Supported
Due to Python Fiddle's reliance on advanced JavaScript techniques, older browsers might have problems running it correctly. Please download the latest version of your favourite browser.
Chrome 10+
Firefox 4+
Safari 5+
IE 10+
Let me try anyway!
url:
Go
Python Snippet
Stackoverflow Question