I am trying to implement Factory Design Pattern and have done this far till now.
import abc
class Button(object):
__metaclass__ = abc.ABCMeta
html = ""
def get_html(self, html):
return self.html
class ButtonFactory():
def create_button(self, type):
baseclass = Button()
targetclass = type.baseclass.capitalize()
return targetclass
button_obj = ButtonFactory()
button = ['image', 'input', 'flash']
for b in button:
print button_obj.create_button(b).get_html()
The output should be the HTML of all your button types.
I get the error like this
AttributeError: 'str' object has no attribute 'baseclass'
I am trying to implement a class which has different variations, such as ImageButton, InputButton and FlashButton. Depending on the place, it may need to create different html for the buttons
The factory design pattern is used when we have a superclass with multiple sub-classes and based on input, we need to return one of the sub-class. This pattern takes out the responsibility of the instantiation of a class from the client program to the factory class.
We also discussed their four different types, i.e., Singleton, Factory Method, Abstract Factory and Builder Pattern, their advantages, examples and when should we use them.
Advantage of Factory Design Pattern Factory Method Pattern allows the sub-classes to choose the type of objects to create. It promotes the loose-coupling by eliminating the need to bind application-specific classes into the code.
The Singleton pattern ensures that only one instance of the class exists and typically provides a well-known, i.e., global point for accessing it. The Factory pattern defines an interface for creating objects (no limitation on how many) and usually abstracts the control of which class to instantiate.
You are trying to call baseclass
attribute of str
, which does not exist, because b
gets string values (one of ['image', 'input', 'flash']
).
If you want to create an object according to a string representing its name, you can use the globals()
dictionary, which holds a mapping between variable names and their values.
class Button(object):
html = ""
def get_html(self):
return self.html
class Image(Button):
html = "<img></img>"
class Input(Button):
html = "<input></input>"
class Flash(Button):
html = "<obj></obj>"
class ButtonFactory():
def create_button(self, typ):
targetclass = typ.capitalize()
return globals()[targetclass]()
button_obj = ButtonFactory()
button = ['image', 'input', 'flash']
for b in button:
print button_obj.create_button(b).get_html()
EDIT:
Using globals()
or locals()
is also not a good practice so, if you can, it is better to create a mapping between the relevant objects and their names, like this:
button_objects = {'image':Image,'flash':Flash,'input':Input}
and replace create_button
with:
def create_button(self, typ):
return button_objects[typ]()
Here is where your error comes from:
button = ['image', 'input', 'flash'] # button contains strings
for b in button: # b is a string
create_button(b) # argument 'type' is a string
type.baseclass... # hence the AttributeError
Your list button
needs to contain objects that have the baseclass
attribute, not their names as strings. Also, you shouldn't use type
as a variable name, as it shadows a Python standard library function type()
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With