In factory design mode, the client can request an object without knowing where the object came from, that is, which class class is used to generate the object. The idea behind the factory is to simplify the creation of objects. It is based on a centralized function and is easier to track which objects are created than when the client itself is directly creating objects based on class instantiation. By decoupling the code that creates the object from the code that uses the object, the factory can reduce the complexity of application maintenance.
A factory usually has two forms: a factory method , which is a method (or a function) that returns different objects for different input parameters; The second is an abstract factory , which is a set of factory methods that create a series of related objects.
1. Factory Method
In the factory method pattern, we execute a single function, passing in a parameter (providing information indicating what we want), but do not require any details about how the object is implemented and where the object comes from.
1.1 Cases
The following example uses the factory method to parse two popular human-readable file formats: XML and JSON. We use two libraries (Xml.etree.ElementTree and JSON) with the Python hairstyle version to work with XML and JSON, as follows:
Import Xml.etree.ElementTree as Etree Import JSON
The following is the complete code for the Factory method implementation (factory_method.py).
#!/usr/bin/env python#-*-coding:utf-8-*-#@Date: 2018/7/13 15:34#@Author: Yaheng Wang ([email protected])#@Link: Http://www.wy2160640.github.io#@Version: 1.0ImportXml.etree.ElementTree as EtreeImportJSONImportioclassJsonconnector:def __init__(self, filepath): Self.data={} with Io.open (filepath, mode='R', encoding='Utf-8') as F:self.data=json.load (f) @propertydefParsed_data (self):returnSelf.dataclassXmlconnector:def __init__(self, filepath): Self.tree=etree.parse (filepath) @propertydefParsed_data (self):returnSelf.treedefconnection_factory (filepath):ifFilepath.endswith ('JSON'): Connector=JsonconnectorelifFilepath.endswith ('XML'): Connector=XmlconnectorElse: RaiseValueError ('cannot connect to {}'. Format (filepath))returnConnector (filepath)defconnect_to (filepath): Factory=NoneTry: Factory=connection_factory (filepath)exceptValueError as ve:Print(VE)returnFactorydefMain (): Sqlite_factory= Connect_to ('data/person.sq3') Print() xml_factory= Connect_to ('Data/person.xml') Xml_data=Xml_factory.parsed_data Liars= Xml_data.findall (".//{}[{}= ' {} ']". Format (' Person','LastName','Liar')) Print('found: {} persons'. Format (len (Liars))) forLiarinchLiars:Print('First name: {}'. Format (Liar.find ('FirstName') . Text))Print('Last name: {}'. Format (Liar.find ('LastName') . Text)) forPinchLiar.find ('phonenumbers'): Print('phone number ({})'. Format (p.attrib['type']), P.text)Print() json_factory= Connect_to ('Data/donut.json') Json_data=Json_factory.parsed_dataPrint('found: {} donuts'. Format (len (json_data))) forDonutinchJson_data:Print('name: {}'. Format (donut['name'])) Print('Price : ${}'. Format (donut['Ppu'])) forTinchdonut['Topping']: Print('topping: {} {}'. Format (t['ID'], t['type']))if __name__=='__main__': Main ()
2. Abstract Factory
Abstract Factory design patterns are a generalization of abstract methods. In summary, an abstract factory is (logically) a set of factory methods in which each factory method is responsible for producing different kinds of objects.
2.1 Cases
Abstract factories have an advantage, which is often invisible from the user's point of view when using factory methods, which is that abstract factories can change user behavior dynamically (at runtime) by altering the active factory method. A classic example is the ability to change the look and feel of an app while using it, without having to terminate the app and then restart it.
Imagine that we are creating a game, or want to include a mini-game in the app that lets users entertain and entertain. We want to include at least two games, one for kids and one for adults. At run time, based on user input, decide which game to create and run. The game creation section is maintained by an abstract factory.
The complete code for the Abstract Factory implementation (abstract_factory.py) is as follows:
#!/usr/bin/env python#-*-coding:utf-8-*-# @Date: 2018/7/14 15:13# @Author: Yaheng Wang ([email protected]) # @Link: http://www.wy2160640.github.io# @Version: 1.0class frog:def __init__ (self, name): Self.name = Name def __str__ (self): return self.name def interact_with (self, Obstacle): Print (' {} The Frog encounters {} and {}! '. Format (self, Obstacle, obstacle.action ())) class Bug:def __str__ (self): return ' a Bug ' def action (self): Return ' eats it ' class frogworld:def __init__ (self, name): Print (self) self.player_name = name Def __STR__: Return ' \n\n\t------Frog World------' def make_character (self): return Frog (Self.player_ Name) def make_obstacle (self): return Bug () class Wizard:def __init__ (self, name): Self.name = Name def __str__ (self): return self.name def interact_with (self, Obstacle): Print (' {} The Wizard battles Agai NST {} and {}!‘. Format (self, Obstacle, obstacle.action ())) class Ork:def __str__ (self): Return ' a evil Ork ' def action (self) : Return ' kills it ' class Wizardworld:def __init__ (self, name): Print (self) self.player_name = Nam E def __str__ (self): return ' \n\n\t------Wizard World------' Def make_character (self): Return Wizard (Self.player_name) def make_obstacle (self): return Ork () class Gameenvironment:def __init__ (self, Factory): Self.hero = Factory.make_character () self.obstacle = Factory.make_obstacle () def play (self): self.h Ero.interact_with (self.obstacle) def validate_age (name): Try:age = Raw_input (' Welcome {}. How old was you?\n '. Format (name)) Age = Int. except ValueError as Err:print ("age {} is invalid, plea Se try again ... ". Format (age) return (False, age) the Def Main (): name = Raw_input (" Hello. ") What ' s your name?\n ") Valid_input = False While isn't valid_input:valid_input, age = Validate_age (name) game = Frogworld if age < else Wizardworld enviroment = Gameenvironment (game (name)) Enviroment.play () if __name__ = = ' __main__ ': Main ()
3. Summary
Both modes can be used for the following scenarios: (a) When you want to track the creation of an object, (b) to decouple the creation and use of the object, (c) to optimize the performance and resource consumption of the application.
The implementation of the factory design method pattern is a single function that does not belong to any class and is responsible for the creation of a single kind of object (a shape, a connection point, or other object). As an example, we implemented a factory approach that provides the ability to access XML and JSON files.
The implementation of the abstract factory design pattern is a number of factory methods that belong to a single class that are used to create a series of related objects (parts of a car, a game environment, or other objects). As an example of an abstract factory implementation, we have completed a mini-game that demonstrates how to use multiple related factories in a single class.
(Go from Python-proficient design mode) to the creation mode of Python design mode--1. Factory mode