Accessing Web Resources using Factory Method Design Pattern in Python
Last Updated :
01 Nov, 2020
A factory is a class for building other objects, where it creates and returns an object based on the passed parameters. Here, the client provides materials to the Factory class, and the Factory class creates and returns the products based on the given material. A Factory is not a design pattern, but it serves as a basis for the Factory Method Design Pattern.
Before getting into the Factory Method design pattern, let's create a Simple Factory. In the below example, the SimpleFactory class has a static method called build_connection() to create objects based on the received parameter.
Python3
import http.client
from ftplib import FTP
class SimpleFactory(object):
@staticmethod
def build_connection(protocol):
if protocol == 'https':
return http.client.HTTPSConnection('www.python.org')
elif protocol == 'ftp':
return FTP('ftp1.at.proftpd.org')
else:
raise RuntimeError('Unknown protocol')
if __name__ == '__main__':
input_protocol = input('Which protocol to use? (https or ftp):')
protocol = SimpleFactory.build_connection(input_protocol)
if input_protocol == 'https':
protocol.request("GET", "/")
resp = protocol.getresponse()
print(resp.status, resp.reason)
elif input_protocol == 'ftp':
resp = protocol.login()
print(resp)
Let's look into the output
Output
Here, you provide the type of protocol as an argument, and the factory class creates and returns the object based on the argument. The point to note is that object creation is not the responsibility of the client.
Factory Method Design Pattern
Factory Method Design Pattern is identical to a simple factory, but its structure is complicated compared to a simple factory structure. It has an abstract class that contains factory methods (to create objects) and operation methods (to work with created objects). And, the concrete classes that create objects are derived from the abstract class.
This pattern helps to define an interface to create an object. Here the classes that implement the interface decide which class to instantiate. Hence, the operation methods in the abstract class need not worry about object creation until the product interface is implemented.
Note: If you are a beginner, I strongly recommend you to go through the Factory Method - Python Design Patterns.
Advantages of the Factory Method Design Pattern
Let's look into the advantages of the Factory Design Pattern. A few of them are:
- It makes code more universal
- It separates interfaces from implementation
- It reduces the complexity of code maintenance.
Accessing Web Resources Using Different Protocol
Let's implement a program for accessing web resources using HTTP or FTP protocol. Here, we will use the site ftp.freebsd.org that allows both HTTP and FTP protocol.
Factory Method Design Pattern
From the above diagram, we can understand that the design has an abstract class called Connector, and two concrete classes – HTTPConnector and FTPConnector. The two concrete classes are derived from the Connector class, and the factory methods in the abstract class use these classes for product creation. Let's look into the code below.
Python3
import abc
import urllib
import urllib.error
import urllib.request
from bs4 import BeautifulSoup
class Connector(metaclass=abc.ABCMeta):
def __init__(self, is_secure):
self.is_secure = is_secure
self.port = self.factory_port()
self.protocol = self.factory_protocol()
@abc.abstractmethod
def crawl(self):
pass
def scan(self, con_domain, con_path):
url = self.protocol + '://'+ con_domain \
+ ':' + str(self.port) + con_path
print(url)
return urllib.request.urlopen(url, timeout=10).read()
@abc.abstractmethod
def factory_protocol(self):
pass
@abc.abstractmethod
def factory_port(self):
pass
class HTTPConnector(Connector):
""" Creates an HTTP Connector """
def factory_protocol(self):
if self.is_secure:
return 'https'
return 'http'
def factory_port(self):
if self.is_secure:
return '443'
return '80'
def crawl(self, data):
""" crawls web content """
filenames = []
soup = BeautifulSoup(data,"html.parser")
links = soup.table.findAll('a')
for link in links:
filenames.append(link['href'])
return '\n'.join(filenames)
class FTPConnector(Connector):
def factory_protocol(self):
return 'ftp'
def factory_port(self):
return '21'
def crawl(self, data):
# converting byte to string
data = str(data, 'utf-8')
lines = data.split('\n')
filenames = []
for line in lines:
extract_line = line.split(None, 8)
if len(extract_line) == 9:
filenames.append(extract_line[-1])
return '\n'.join(filenames)
if __name__ == "__main__":
con_domain = 'ftp.freebsd.org'
con_path = '/pub/FreeBSD/'
con_protocol = input('Choose the protocol \
(0-http, 1-ftp): ')
if con_protocol == '0':
is_secure = input('Use secure connection? (1-yes, 0-no):')
if is_secure == '1':
is_secure = True
else:
is_secure = False
connector = HTTPConnector(is_secure)
else:
is_secure = False
connector = FTPConnector(is_secure)
try:
data = connector.scan(con_domain, con_path)
except urllib.error.URLError as e:
print('Cannot access resource with this method', e)
else:
print(connector.crawl(data))
In this program, we connect to a web page using the HTTP or FTP protocol. The Connector abstract class is designed to establish a connection (scan method), and as well as for crawling the pages (crawl method). In addition to this, it provides two factory methods - factory_protocol and factory_port - to deal with protocol and port address.
Let's look into the output.
OutputSummary
A factory class is used to create other classes, It makes the code more universal. The factory methods in factory classes act as an interface for creating an object, thereby it separates interface from implementation. As a result, classes can implement these interface methods and can decide which class to instantiate.
Similar Reads
Implementing Web Crawler using Abstract Factory Design Pattern in Python
In the Abstract Factory design pattern, every product has an abstract product interface. This approach facilitates the creation of families of related objects that is independent of their factory classes. As a result, you can change the factory at runtime to get a different object  â simplifies the
5 min read
Abstract Factory Method - Python Design Patterns
Abstract Factory Method is a Creational Design pattern that allows you to produce the families of related objects without specifying their concrete classes. Using the abstract factory method, we have the easiest ways to produce a similar type of many objects. It provides a way to encapsulate a group
4 min read
Factory Method - Python Design Patterns
Factory Method is a Creational Design Pattern that allows an interface or a class to create an object, but lets subclasses decide which class or object to instantiate. Using the Factory method, we have the best ways to create an object. Here, objects are created without exposing the logic to the cli
4 min read
Facade Method Design Pattern in Python
The Facade Method Design Pattern in Python simplifies complex systems by providing a unified interface to a set of interfaces in a subsystem. This pattern helps in reducing the dependencies between clients and the intricate system, making the code more modular and easier to understand. By implementi
7 min read
Singleton Method - Python Design Patterns
Prerequisite: Singleton Design pattern | IntroductionWhat is Singleton Method in PythonSingleton Method is a type of Creational Design pattern and is one of the simplest design patterns available to us. It is a way to provide one and only one object of a particular type. It involves only one class t
5 min read
Mediator Method - Python Design Pattern
Mediator Method is a Behavioral Design Pattern that allows us to reduce the unordered dependencies between the objects. In a mediator environment, objects take the help of mediator objects to communicate with each other. It reduces coupling by reducing the dependencies between communicating objects.
3 min read
Chain of Responsibility - Python Design Patterns
Chain of Responsibility method is Behavioral design pattern and it is the object-oriented version of if ... elif ... elif ... else and make us capable to rearrange the condition-action blocks dynamically at the run-time. It allows us to pass the requests along the chain of handlers. The processing i
4 min read
Visitor Method - Python Design Patterns
Visitor Method is a Behavioral Design Pattern which allows us to separate the algorithm from an object structure on which it operates. It helps us to add new features to an existing class hierarchy dynamically without changing it. All the behavioral patterns proved as the best methods to handle the
4 min read
Implementing Weather Forecast using Facade Design Pattern in Python
Facade Design Patterns are design patterns in Python that provide a simple interface to a complex subsystem. When we look into the world around us, we can always find facade design patterns. An automobile is the best example: you don't need to understand how the engine functions. To operate the engi
3 min read
Implementing News Parser using Template Method Design Pattern in Python
While defining algorithms, programmers often neglect the importance of grouping the same methods of different algorithms. Normally, they define algorithms from start to end and repeat the same methods in every algorithm. This practice leads to code duplication and difficulties in code maintenance â
4 min read