Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Factory Design Pattern

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

like image 911
ajknzhol Avatar asked Jan 09 '14 16:01

ajknzhol


People also ask

What is factory design pattern?

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.

What are the types of Factory Pattern?

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.

Why do we use factory design pattern?

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.

What is singleton and factory design pattern?

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.


2 Answers

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]()
like image 148
Elisha Avatar answered Oct 15 '22 02:10

Elisha


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().

like image 35
jonrsharpe Avatar answered Oct 15 '22 03:10

jonrsharpe