Design Patterns in Python
Design Patterns in Python
Rahul Verma
Chetan Giridhar
Brought to you by: Testing Perspective – www.testingperspective.com
Design Patterns in Python
http://creativecommons.org/licenses/by-nc-nd/3.0/
www.testingperspective.com
Cover Image
Renjith Krishnan /FreeDigitalPhotos.net
http://www.freedigitalphotos.net/images/view_photog.php?photogid=721
2 www.testingperspective.com
Design Patterns in Python
Chetan Giridhar
Chetan Giridhar has 5 years experience of working in software services industry,
service, product companies and research organization. He runs the website –
TechnoBeans technobeans.wordpress.com where he shares his knowledge w.r.t.
day-to-day usage of programming for testers.
Chetan has a strong background in C++, Java, Perl and Python. He has developed
tools and libraries for users and community developers that could be easily
downloaded from Chetan @ sourceforge. He has written on wide variety of subjects
in the field of security, code reviews and agile methodologies for testing magazines
including TestingExperience and AgileRecord. He has given lectures on Python
Programming at Indian Institute of Astrophysics.
3 www.testingperspective.com
Design Patterns in Python
Table of Contents
COPYRIGHT INFORMATION.......................................................................................................................... 2
ABOUT THE AUTHORS .................................................................................................................................. 3
FOREWARD ................................................................................................................................................... 6
PREFACE ........................................................................................................................................................ 7
Why Write This Book ......................................................................................................................... 7
What is a design pattern? ............................................................................................................... 7
Context of Design Patterns in Python ........................................................................................ 8
Design Pattern Classifications ....................................................................................................... 8
Who This Book is For ........................................................................................................................ 8
What this book covers ...................................................................................................................... 8
Pre-Requisites ...................................................................................................................................... 9
Online Version ..................................................................................................................................... 9
Feedback................................................................................................................................................ 9
MODEL-VIEW-CONTROLLER PATTERN....................................................................................................... 10
Controller ......................................................................................................................................... 11
Model ................................................................................................................................................. 11
View ................................................................................................................................................... 11
A Sample Python Implementation ............................................................................................. 12
Example Description ................................................................................................................... 12
Database .......................................................................................................................................... 12
Python Code ................................................................................................................................... 12
Explanation ..................................................................................................................................... 14
COMMAND PATTERN ................................................................................................................................. 15
A Sample Python Implementation ............................................................................................. 16
Example description .................................................................................................................... 16
Python Code ................................................................................................................................... 16
4 www.testingperspective.com
Design Patterns in Python
5 www.testingperspective.com
Design Patterns in Python
Foreword
Vipul Kocher
Shri Ramkrishna Paramhans, one of the greatest mystics of this age and Guru
of Swami Vivekananda, used to narrate a story that went like this…
“There was a Ghost who was very lonely. It is said that when a person dies an
accidental death on Tuesday or Saturday becomes a Ghost. Whenever that Ghost
saw an accidental death he would rush there hoping he would find a friend.
However, every time he was disappointed because all of them went to respective
places without even one becoming a Ghost.”
While He said it referring to difficulty of finding people with spiritual bent of mind, I
take the liberty of using this story for my own interests.
I got drawn to Object Oriented Design world in 1996 despite my job role being that
of system tester. I started my career as a developer and that probably was the
reason or probably my love for abstract. Whatever be the reason, I got drawn to
the world of Grady Booch,Rumbaugh, Shlaer and Mellor, Coad and Yourdon etc.
Then Gang of Four happened. I got blown away by the book Design Patterns –
Elements of Reusable Object-Oriented Software. Since then I kept looking for
testers who shared same love as me for design patterns. Alas! None was to be
found. That is, until I met Rahul Verma and Chetan Giridhar.
I used to wonder when automation framework developers would start talking about
the framework as a designer/architect rather than just as a user. Will they ever
take automation project as a development project? Will they ever apply design
patterns to the automation framework?
In the present book I hope to see this dream of mine fulfilled. While the book aims
to talk of design patterns in Python, I hope to see the examples and explanations
from the point of view of a tester who wants to create a framework utilizing sound
architecture and design patterns.
Patterns have begun to occupy a large portion of my thought process for almost
two years now; the process having begun in 1999 with my first attempt at testing
patterns by the name Q-patterns or Questioning-Patterns. I sincerely hope to see
one piece of the pattern puzzle falling in place with this book.
I hope you enjoy the journey that this book promises to take you through. Vipul Kocher
Vipul Kocher
Co-President, PureTesting
6 www.testingperspective.com
Design Patterns in Python
Preface
“Testers are poor coders.” – We here that more often than one would think. There
is a prominent shade of truth in this statement as testers mostly code to ―get the
work done‖, at times using scripting languages which are vendor specific, just
tweaking a recorded script. The quality of code written is rarely a concern and most
of the times, the time and effort needed to do good coding is not allocated to test
automation efforts.
The above scenario changes drastically when one needs to develop one‘s own
testing framework, extend an existing one or contribute new code to an existing
one. To retain the generic property of the framework and to build scalable
frameworks, testers need to develop better coding skills.
We, the authors of this book, are testers. We are in no way experts in the matter of
design patterns or Python. We are learners. We like object oriented programming.
We like Python language. We want to be better coders. We have attempted to write
this book in very simple language, picking up simple examples to demonstrate a
given pattern and being as precise as possible. This is done to provide a text so
that the concept of design patterns can reach to those who are not used to formal
programming practices. We hope that this would encourage other testers to pick up
this subject in the interest better design of test automation.
As per Wikipedia:
In the object oriented world, design patterns tell us how, in the context of a certain
problem, we should structure the classes and objects. They do not translate directly
into the solution; rather have to be adapted to suit the problem context.
With knowledge of design patterns, you can talk in ―pattern language‖, because a
lot of known design patterns have been documented. In discussions, one could ask,
7 www.testingperspective.com
Design Patterns in Python
Design patterns should not be confused with frameworks and libraries. Design
patterns are not implementations, though implementations might choose to use
them.
If you are a beginner to learning Python or design patterns, this book can prove to
be a very easy-to-understand introductory text.
If you are a tester, in addition to the above this book would also be helpful in
learning contexts in which design patterns can be used in the test automation
world.
8 www.testingperspective.com
Design Patterns in Python
This is an initial version of the book covering the following 7 design patterns:
By the time we publish next version of this book with a target of 20 patterns, the
content would be organized into classification-wise grouping of chapters.
Pre-Requisites
Online Version
http://dpip.testingperspective.com/
This version is a more updated version of this ebook at any given point of time in
terms of corrections and updated content. We plan to release updated version of
this offline PDF version at regular intervals to keep up with the updated content in
online version.
Feedback
There would be mistakes. Some of them would be directly visible and some of them
could be more subtle. Please write back to us so that we can correct the same.
You can use the contact form at Testing Perspective website to do so or write to us
at feedback@testingperspective.com.
9 www.testingperspective.com
Design Patterns in Python
DP# 1
The Model-View-Controller Pattern
Introduction
As per Wikipedia:
In simple words:
10 www.testingperspective.com
Design Patterns in Python
View deals with how the fetched data is presented to the user
Controller
Controller can be considered as a middle man between user and processing (Model)
& formatting (View) logic. It is an entry point for all the user requests or inputs to
the application. The controller accepts the user inputs, parses them and decides
which type of Model and View should be invoked. Accordingly, it invokes the chosen
Model and then the chosen View to provide to the user what he/she/it requested.
Model
Model represents the business processing logic of the application. This component
would be an encapsulated version of the application logic. Model is also responsible
for working with the databases and performing operations like Insertion, Update
and Deletion. Every model is meant to provide a certain kind of data to the
controller, when invoked. Further, a single model can return different variants of
the same kind of data based on which method of the Model gets called. What
exactly gets returned to the controller, could be controlled by passing arguments to
a given method of the model.
View
View, also referred as presentation layer, is responsible for displaying the results
obtained by the controller from the model component in a way that user wants
11 www.testingperspective.com
Design Patterns in Python
them to see or a pre-determined format. The format in which the data can be
visible to users can be of any ‗type‘ like HTML or XML. It is responsibility of the
controller to choose a view to display data to the user. Type of view could be
chosen based on the model chosen, user configuration etc.
Let‘s consider a case of a test management system that queries for a list of defects.
Here are two typical scenarios that work with any test management system.
If the user queries for a particular defect, the test management system displays
the summary of the defect to the user in a prescribed format.
If the user searches for a component it shows list of all defects logged against
that component.
Database
Let‘s consider a SQLite DB with the name ‗TMS‘ and a table defects.
TMS.[defects]
ID Component Summary
Python Code
# Filename: mvc.py
import sqlite3
import types
class DefectModel:
def getDefectList(self, component):
query = '''select ID from defects where Component = '%s' ''' %component
defectlist = self._dbselect(query)
list = []
for row in defectlist:
list.append(row[0])
12 www.testingperspective.com
Design Patterns in Python
return list
class DefectView:
def summary(self, summary, defectid):
print "#### Defect Summary for defect# %d####\n%s" % (defectid,summary)
class Controller:
def __init__(self):
pass
import mvc
controller = mvc.Controller()
13 www.testingperspective.com
Design Patterns in Python
print controller.getDefectSummary(2)
Explanation
1. Controller would first get the query from the user. It would know that the query
is for viewing defects. Accordingly it would choose DefectModel.
2. If the query is for a particular defect, Controller calls getSummary() method of
DefectModel, passing the defect id as the argument, for returning the summary
of the defect. Then the Controller calls summary() method of DefectView and
displays the response to the user.
3. If the user query consists of a component name, , Controller calls
getDefectList() method of DefectModel, passing the component name as the
argument, for returning the defect list for the given component. Then the
Controller calls defectList() method of DefectView and displays the response to
the user.
14 www.testingperspective.com
Design Patterns in Python
DP# 2
Command Pattern
Introduction
As per Wikipedia:
Command pattern is one of the design patterns that are categorized under
‗Observer‘ design pattern. In command pattern the object is encapsulated in the
form of a command, i.e., the object contains all the information that is useful to
invoke a method anytime user needs. To give an example, let say we have a user
interface where in the background of the interface would turn into RED if the button
on the user interface named ‗RED‖ is clicked. Now the user is unaware what classes
or methods the interface would call to make the background turn RED, but the
command user sends (by clicking on ‗RED‘ button) would ensure the background is
turned RED. Thus command pattern gives the client (or the user) to use the
interface without the information of the actual actions being performed, without
affecting the client program.
The key to implementing this pattern is that the Invoker object should be kept
away from specifics of what exactly happens when its methods are executed. This
way, the same Invoker object can be used to send commands to objects with
similar interfaces.
15 www.testingperspective.com
Design Patterns in Python
Command Pattern is associated with three components, the client, the invoker, and
the receiver. Let‘s take a look at all the three components.
Client: the Client represents the one that instantiates the encapsulated object.
Invoker: the invoker is responsible for deciding when the method is to be
invoked or called.
Receiver: the receiver is that part of the code that contains the instructions to
execute when a corresponding command is given.
Example description
Python Code
class Switch:
""" The INVOKER class"""
self.__flipDownCommand = flipDownCmd
def flipUp(self):
self.__flipUpCommand.execute()
def flipDown(self):
self.__flipDownCommand.execute()
class Light:
"""The RECEIVER Class"""
def turnOn(self):
print "The light is on"
def turnOff(self):
print "The light is off"
class Command:
"""The Command Abstract class"""
def __init__(self):
pass
#Make changes
def execute(self):
#OVERRIDE
pass
class FlipUpCommand(Command):
"""The Command class for turning on the light"""
def __init__(self,light):
self.__light = light
def execute(self):
self.__light.turnOn()
class FlipDownCommand(Command):
"""The Command class for turning off the light"""
def __init__(self,light):
Command.__init__(self)
self.__light = light
def execute(self):
self.__light.turnOff()
class LightSwitch:
""" The Client Class"""
17 www.testingperspective.com
Design Patterns in Python
def __init__(self):
self.__lamp = Light()
self.__switchUp = FlipUpCommand(self.__lamp)
self.__switchDown = FlipDownCommand(self.__lamp)
self.__switch = Switch(self.__switchUp,self.__switchDown)
def switch(self,cmd):
cmd = cmd.strip().upper()
try:
if cmd == "ON":
self.__switch.flipUp()
elif cmd == "OFF":
self.__switch.flipDown()
else:
print "Argument \"ON\" or \"OFF\" is required."
except Exception, msg:
print "Exception occured: %s" % msg
lightSwitch = LightSwitch()
18 www.testingperspective.com
Design Patterns in Python
DP# 3
Observer Pattern
Introduction
As per Wikipedia:
19 www.testingperspective.com
Design Patterns in Python
To summarize, Subscriber objects can register and unregister with the Publisher
object. So whenever an event, that drives the Publisher's notification method,
occurs, the Publisher notifies the Subscriber objects. The notifications would only be
passed to the objects that are registered with the Subject at the time of occurrence
of the event.
Let's take the example of a TechForum on which technical posts are published by
different users. The users might subscribe to receive notifications when any of the
other users publishes a new post. To see this in the light of objects, we could have
a ‗TechForum‘ object and we can have another list of objects called ‗User‘ objects
that are registered to the ‗TechForum‘ object, that can observe for any new posts
on the ‗TechForum‘. Along with the new post notification, the title of the post is
sent.
Python Code
class Publisher:
def __init__(self):
#MAke it uninheritable
pass
def register(self):
#OVERRIDE
pass
def unregister(self):
#OVERRIDE
pass
def notifyAll(self):
#OVERRIDE
pass
class TechForum(Publisher):
def __init__(self):
self._listOfUsers = []
self.postname = None
20 www.testingperspective.com
Design Patterns in Python
def notifyAll(self):
for objects in self._listOfUsers:
objects.notify(self.postname)
class Subscriber:
def __init__(self):
#make it uninheritable
pass
def notify(self):
#OVERRIDE
pass
class User1(Subscriber):
def notify(self,postname):
print 'User1 notfied of a new post %s' % postname
class User2(Subscriber):
def notify(self, postname):
print 'User2 notfied of a new post %s' % postname
class SisterSites(Subscriber):
def __init__(self):
self._sisterWebsites = ["Site1","Site2","Site3"]
def notify(self, postname):
for site in self._sisterWebsites:
# Send updates by any means
print "Sent nofication to site: %s" % site
if __name__ == "__main__":
techForum = TechForum()
user1 = User1()
user2 = User2()
21 www.testingperspective.com
Design Patterns in Python
sites = SisterSites()
techForum.register(user1)
techForum.register(user2)
techForum.register(sites)
techForum.unregister(user2)
22 www.testingperspective.com
Design Patterns in Python
DP# 4
Facade Pattern
Introduction
As per Wikipedia:
Façade pattern falls under the hood of Structural Design Patterns. Façade is nothing
but an interface that hides the inside details and complexities of a system and
provides a simplified ―front end‖ to the client. With façade pattern, client can work
with the interface easily and get the job done without being worried of the complex
operations being done by the system.
Because of the above reason, Facade pattern is not about ―encapsulating‖ the sub-
system, rather about providing a simplified interface for a chosen functionality
23 www.testingperspective.com
Design Patterns in Python
The pattern can be better explained with a block diagram (based on Facade pattern
example from Wikipedia.)
1. In this block diagram, we have three classes representing the CPU, the Memory
and the HardDrive of a computer. CPU Class has methods called as jump() and
execute(). Memory Class has a method load() and HardDrive Class has read()
method.
2. We have a Facade, the Class Computer, that is exposed to the Client with the
help of the start() method.
3. When the Client intends to start the Computer System, it calls the start()
method of Class Computer by calling Computer.start().
In start(), CPU, Memory and HardDrive classes are instantiated. Then the load()
method of Class Memory is called where it gets the BOOT_ADDRESS and calls the
read() method of HardDrive Class from it gets the BOOT_SECTOR and
SECTOR_SIZE of the HardDrive. start() then calls the jump() method of CPU Class
with the BOOT_ADDRESS and then calls the execute() method.
Thus the client is not aware of the complex operations happening in the background
when the computer is started. It only has a facade exposed to it from where it
could start the computer easily without bothering about the inner details or
complexities.
24 www.testingperspective.com
Design Patterns in Python
Let‘s consider the case of a Test Automation Framework. Tests that need to be run
for a particular build are written in the form of classes namely, ‗TC1, TC2…TCn‘.
Each of these classes contains a method called ‗run()‘ that gets called to execute
the test.
Now when the user of the automation framework intends to run the tests for a
build, as a client, s/he needs to create an object of ‗TestRunner‘ class and call the
‗runAll‘ method. 'runAll' method would inturn create objects of all the Test Classes
and call their 'run' method., thereby executing all tests.
Python Code
#Complex Parts
import time
class TC1:
def run(self):
print "###### In Test 1 ######"
time.sleep(1)
print "Setting up"
time.sleep(1)
print "Running test"
time.sleep(1)
print "Tearing down"
time.sleep(1)
print "Test Finished\n"
class TC2:
def run(self):
print "###### In Test 2 ######"
time.sleep(1)
print "Setting up"
time.sleep(1)
25 www.testingperspective.com
Design Patterns in Python
class TC3:
def run(self):
print "###### In Test 3 ######"
time.sleep(1)
print "Setting up"
time.sleep(1)
print "Running test"
time.sleep(1)
print "Tearing down"
time.sleep(1)
print "Test Finished\n"
#Facade
class TestRunner:
def __init__(self):
self.tc1 = TC1()
self.tc2 = TC2()
self.tc3 = TC3()
def runAll(self):
self.tc1.run()
self.tc2.run()
self.tc3.run()
#Client
if __name__ == '__main__':
testrunner = TestRunner()
testrunner.runAll()
26 www.testingperspective.com
Design Patterns in Python
DP# 5
Mediator Pattern
Introduction
As per Wikipedia:
27 www.testingperspective.com
Design Patterns in Python
1. Class TC is responsible for running the tests with the help of setup(), execute()
and tearDown() methods.
2. Class Reporter calls its prepare() method while the test category starts getting
executed and calls its report() method when the test category finishes its
execution. This helps in text based reporting of the tests that are run by the
framework.
3. Class DB stores the execution status of the test category by first calling the
insert() method while the test category is in setup(), and then calls the update()
method once the test category has finished execution. In this way, at any given
point of time, the test execution status is available for framework user to query
from the database.
4. TestManager Class is the one that co-ordinates for test category execution
(Class TC) and fetching the reports (Class Reporter) and getting the test
execution status in database (Class DB) with the help of prepareReporting() and
publishReport() methods.
5. Methods setTM(), setTC(), setReporter() and setDB() are used so that the
classes could register with each other and can communicate easily.
Building the analogy with the Mediator pattern, the TestManager class is a Mediator
between Class TC, Class Reporter and Class DB, the Colleagues in the system.
Let's have a look at a sample python code which would make the concept more
clear.
Python Code
import time
class TC:
def __init__(self):
self._tm = tm
self._bProblem = 0
def setup(self):
print "Setting up the Test"
28 www.testingperspective.com
Design Patterns in Python
time.sleep(1)
self._tm.prepareReporting()
def execute(self):
if not self._bProblem:
print "Executing the test"
time.sleep(1)
else:
print "Problem in setup. Test not executed."
def tearDown(self):
if not self._bProblem:
print "Tearing down"
time.sleep(1)
self._tm.publishReport()
else:
print "Test not executed. No tear down required."
def setTM(self,TM):
self._tm = tm
class Reporter:
def __init__(self):
self._tm = None
def prepare(self):
print "Reporter Class is preparing to report the results"
time.sleep(1)
def report(self):
print "Reporting the results of Test"
time.sleep(1)
def setTM(self,TM):
self._tm = tm
class DB:
def __init__(self):
self._tm = None
def insert(self):
print "Inserting the execution begin status in the Database"
time.sleep(1)
29 www.testingperspective.com
Design Patterns in Python
def update(self):
print "Updating the test results in Database"
time.sleep(1)
def setTM(self,TM):
self._tm = tm
class TestManager:
def __init__(self):
self._reporter = None
self._db = None
self._tc = None
def prepareReporting(self):
rvalue = self._db.insert()
if rvalue == -1:
self._tc.setProblem(1)
self._reporter.prepare()
def publishReport(self):
self._db.update()
rvalue = self._reporter.report()
def setTC(self,tc):
self._tc = tc
if __name__ == '__main__':
reporter = Reporter()
db = DB()
tm = TestManager()
tm.setReporter(reporter)
tm.setDB(db)
reporter.setTM(tm)
db.setTM(tm)
30 www.testingperspective.com
Design Patterns in Python
In the above Python Code, the user of the framework first creates instances of
Class Reporter, Class DB and Class TestManager and registers these classes with
each other with the help of setReporter(), setDB() and setTM() methods.
When the test category starts execution, the TestManager Class and the TC
Class register with each other. TC Class first calls the setup() method which in
turn requests the TestManager Class (the Mediator) to be prepared for reporting
of the test execution results using the prepareReporting() method.
prepareReporting() method of the TestManager, the Mediator Class,
communicates with the other Colleagues (Class Reporter and Class DB) in the
system by calling the prepare() and insert() methods.
execute() method of Class TC is responsible for running the tests.
When the test execution is getting finished, tearDown() method of Class TC is
called, which in turn calls the publishReport() method of the Mediator (Class
TestManager) which communicates with the Colleagues (Class Reporter and
Class DB) for preparing the report and getting the execution status in the
database (by calling the prepare() and update() methods respectively).
Also, during insert(), if communication between Class TC (Colleague) and Class
TestManager (Mediator) fails, the next step in test execution is conveyed of this
failure.
31 www.testingperspective.com
Design Patterns in Python
DP# 6
Factory Pattern
Introduction
As per Wikipedia:
Factory pattern involves creating a super class which provides an abstract interface
to create objects of a particular type, but instead of taking a decision on which
objects get created it defers this creation decision to its subclasses. To support this
there is a creation class hierarchy for the objects which the factory class attempts
create and return.
Factory pattern is used in cases when based on a ―type‖ got as an input at run-
time, the corresponding object has to be created. In such situations, implementing
code based on Factory pattern can result in scalable and maintainable code i.e. to
add a new type, one need not modify existing classes; it involves just addition of
new subclasses that correspond to this new type.
A class does not know what kind of object it must create on a user‘s request
You want to build an extensible association between this creater class and
classes corresponding to objects that it is supposed to create.
32 www.testingperspective.com
Design Patterns in Python
1. We have a base class called Person that has methods for getting the name and
the gender and has two sub-classes namely Male and Female that print the
salutation message and a Factory Class.
2. Factory Class has a method named 'getPerson' that takes two arguments 'name'
and 'gender' of a person.
3. The Client instantiates the Factory Class and calls the getPerson method with
name and gender as arguments.
During run-time, based on the gender, that is passed by the Client, the Factory
creates an object of the class pertaining to that gender. Hence the Factory Class at
run-time decides which object it needs to create.
Python Code
class Person:
def __init__(self):
self.name = None
self.gender = None
def getName(self):
return self.name
def getGender(self):
return self.gender
class Male(Person):
def __init__(self, name):
print "Hello Mr." + name
class Female(Person):
def __init__(self, name):
print "Hello Miss." + name
class Factory:
def getPerson(self, name, gender):
if gender == 'M':
return Male(name)
if gender == 'F':
return Female(name)
33 www.testingperspective.com
Design Patterns in Python
if __name__ == '__main__':
factory = Factory()
person = factory.getPerson("Chetan", "M")
34 www.testingperspective.com
Design Patterns in Python
DP# 7
Proxy Pattern
Introduction
As per Wikipedia:
1. Creation of object for a Real Subject Class is costly in terms of resources and a
simple object creation by Proxy Class can be a cheaper option.
35 www.testingperspective.com
Design Patterns in Python
2. A need arises that an object must be protected from direct use by its clients.
3. There is a need that an object creation for the Real Subject Class can be delayed
to a point when it is actually required.
Website where the Cache Proxy can cache certain set of frequently requested
web pages to cater to clients requests. This helps in avoiding many requests
getting hit on the server and improves performance.
The message box which gives the status of a file copy operation giving the
progress in terms of percentage completion.
Opening a large file in a word processor leads to a message saying ―Please wait
while the software opens the document…‖
Based on the example from Prof. Kiran, let us consider a case of a regular office
situation where, in order to speak to a Sales Manager of a company, the Client
makes a call first to the receptionist of the sales manager office and then the
Receptionist passes the call to the manager. In this case, Sales Manager would be
the Subject to whom the Client wants to speak to and the Receptionist would be the
Proxy that shields the Subject from talking directly to the Clients.
Expanding this example, we could consider 'Sales Manager' as the Real Subject and
create a common Subject Class referred to as 'Managers' from which 'Sales
Manager' and the 'Receptionist' can be derived.
Python Code
import time
class Manager(object):
def work(self):
pass
def talk(self):
pass
class SalesManager(Manager):
def work(self):
print "Sales Manager working..."
36 www.testingperspective.com
Design Patterns in Python
def talk(self):
print "Sales Manager ready to talk"
class Proxy(Manager):
def __init__(self):
self.busy = 'No'
self.sales = None
if '__name__' == '__main__':
p = Proxy()
p.work()
In the above code snippet, the Client has to speak to the Sales Manager. In order
to do that it first communicates to the Proxy Class. Proxy, which is the Receptionist
in this case, will check if the Subject (in this case the Sales Manager) is busy or
not. Depending on the busy status it either passes the call to the Sales Manager or
says the Sales Manager is busy. This way the Subject's object creation is delayed
until it's actually required and moreover the Subject is shielded from direct usage
by the Client.
37 www.testingperspective.com
Design Patterns in Python
Wikipedia – www.wikipedia.org
38 www.testingperspective.com