Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file added design-patterns/Command-Python/command.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
89 changes: 89 additions & 0 deletions design-patterns/Command-Python/command.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
class Screen(object):
def __init__(self, text=''):
self.text = text
self.clip_board = ''

def cut(self, start=0, end=0):
self.clip_board = self.text[start:end]
self.text = self.text[:start] + self.text[end:]

def paste(self, offset=0):
self.text = self.text[:offset] + self.clip_board + self.text[offset:]

def clear_clipboard(self):
self.clip_board = ''

def length(self):
return len(self.text)

def __str__(self):
return self.text

# Screen command interface
class ScreenCommand(object):
def __init__(self, screen):
self.screen = screen
self.previous_state = screen.text

def execute(self):
pass

def undo(self):
pass

# Concrete commands
class CutCommand(ScreenCommand):
def __init__(self, screen, start=0, end=0):
super().__init__(screen)
self.start = start
self.end = end

def execute(self):
self.screen.cut(start=self.start, end=self.end)

def undo(self):
self.screen.clear_clipboard()
self.screen.text = self.previous_state

class PasteCommand(ScreenCommand):
def __init__(self, screen, offset=0):
super().__init__(screen)
self.offset = offset

def execute(self):
self.screen.paste(offset= self.offset)

def undo(self):
self.screen.clear_clipboard()
self.screen.text = self.previous_state

# Invoker
class ScreenInvoker(object):
def __init__(self):
self.history = []

def store_and_execute(self, command):
command.execute()
self.history.append(command)

def undo_last(self):
if self.history:
self.history.pop().undo()

if __name__ == '__main__':
screen = Screen('Design Patterns!')
print("Original Text: ",screen)
cut = CutCommand(screen, start=7, end=15 )
client = ScreenInvoker()
client.store_and_execute(cut)
print("After Cut : ",screen)

paste = PasteCommand(screen, offset=0)
client.store_and_execute(paste)
print("After Paste : ",screen)

client.undo_last()
print("Undo Once : ",screen)

client.undo_last()
print("Undo Twice : ",screen)
17 changes: 17 additions & 0 deletions design-patterns/Command-Python/readme.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# Command Method

The main goal of this design pattern is to decouple the object that invokes the operation from the other object that knows how to perform it.
This can be done by encapsulating the command from the client as an object.This transformation lets you parameterize methods with different requests, delay or queue a request’s execution The command object knows about a receiver object that manages its internal state when the command is executed. Finally the invoker objects are used to execute the commands.

![UML diagram for Command Pattern](command.png "UML class diagram of Command")

# Command Method Example :-
In the given example the command pattern is used to track the history of various operations performed on a digital clipboard by the client.Here receiver object is a screen which have the attributes screen and clipboard. Various operations like cut,paste,clear_cliboard and length of the text can be performed on the clipboard. The screen(receiver) manages the internal state of the object which seperates from the ScreenInvoker object which invokes various commands from the client. In this way the invoker object is decoupled from the receiver object which performs the underlying functionality. The screen comand interface is used to parameterize methods to execute,delay or undo a command.

# Command Design Pattern Output:

Original Text: Design Patterns!
After Cut : Design !
After Paste : PatternsDesign !
Undo Once : Design !
Undo Twice : Design Patterns!
Binary file added design-patterns/Iterator-Python/iterator.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
111 changes: 111 additions & 0 deletions design-patterns/Iterator-Python/iterator.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
class OddNumbers(object):
"An iterable object."

def __init__(self, maximum):
self.maximum = maximum

def __iter__(self):
return OddIterator(self)

class EvenNumbers(object):
"An iterable object."

def __init__(self, maximum):
self.maximum = maximum

def __iter__(self):
return EvenIterator(self)

class FibnocciNumbers(object):
"An iterable object."

def __init__(self, maximum):
self.maximum = maximum

def __iter__(self):
return FibnocciIterator(self)



class OddIterator(object):
"An iterator."

def __init__(self, container):
self.container = container
self.n = -1

def __next__(self):
self.n += 2
if self.n > self.container.maximum:
raise StopIteration
return self.n

def __iter__(self):
return self

class EvenIterator(object):
"An iterator."

def __init__(self, container):
self.container = container
self.n = 0

def __next__(self):
self.n += 2
if self.n > self.container.maximum:
raise StopIteration
return self.n

def __iter__(self):
return self

class FibnocciIterator(object):
"An iterator."

def __init__(self, container):
self.container = container
self.a = 0
self.b = 1

def __next__(self):
self.a ,self.b = self.b,self.a + self.b
if self.a > self.container.maximum or self.b > self.container.maximum:
raise StopIteration
return self.b

def __iter__(self):
return self

def spanish_count_to(count):
""" Built in iterator implementation"""

numbers_in_Spanish = ["uno, dos, tres, cuatro, cinco, seis, siete, ocho, nueve, diez"]

#built-in iterator
#Creates a tuple such as (1, "uno")
iterator = zip(range(count), numbers_in_Spanish)

#Iterate through our iterable list
#Extract the Spanish numbers
#Put them in a generator called number
for position, number in iterator:

#Returns a 'generator' containing numbers in Spanish
yield number

numbers = OddNumbers(12)
even = EvenNumbers(16)
fib = FibnocciNumbers(40)


print("Fibnocci Iterator :",list(fib))
print("Odd Iterator :",list(numbers))
print("Even Iterator(> 4) : ",set(n for n in even if n > 4))

for num in spanish_count_to(3):
print("Spanish Numbers Iterator : [{}]".format(num))





30 changes: 30 additions & 0 deletions design-patterns/Iterator-Python/readme.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
# Iterator

"""
The main goal of this pattern is to provide a way to access the elements of an aggregate objects(list,stack,tree) sequentially
without exposing its underlying representation and put it in an iterator object.
We can add more than one traversing method(eg- Both DFS and BFS for trees) for the same aggregate object through iterator design pattern.
Using this design pattern we can traverse through any underlying datastructure used to represent objects.
Iterator pattern is not only about traversing through a collection, we can provide different kind of iterators based on our requirements.
One of the fundamental features is that it should allow a client to iterate through a collection, without any knowledge about the implementation of that collection.

![UML diagram for Iterator Pattern](iterator.png "UML class diagram of Iterator")

# Example:-
The example lists some of the iterators used to traverse respective aggregate objects.
In the example Fibnocci numbers,odd numbers,spanish numbers are aggregating objects. Fibnocci iterator,odd iterator and spanish_count_to iterators are the concrete iterators that traverse through the list of integers and also implement the iterator interface.
In this way different iterators can be used for different pursposes to traverse through the same underlying object.
In python-
__iter__ method takes a container object as its argument and returns a new iterator object.(Fibnocci iterator,spanish number iterator.. in this case)
__next__ method takes the iterator as its argument and each time it is called, returns the next integer from the container.
Along with these "maximum" atrribute is used to limit the scope of the iterator. In this way the iterators created from the respective aggregate objects are used to traverse elements without the need for the client to know the underlying functionality.



# Iterator design pattern Output:

Fibnocci Iterator : [1, 2, 3, 5, 8, 13, 21, 34]
Odd Iterator : [1, 3, 5, 7, 9, 11]
Even Iterator(> 4) : {6, 8, 10, 12, 14, 16}
Spanish Numbers Iterator : [uno, dos, tres, cuatro, cinco, seis, siete, ocho, nueve, diez]

18 changes: 18 additions & 0 deletions design-patterns/State-Python/readme.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# State Design Pattern

State Pattern allow an object to alter its behavior when its internal state changes.
The object will appear to change its class.The state pattern is used in computer programming to encapsulate varying behavior for the same object, based on its internal state.It also follows - adding new states should not affect the behavior of existing states.
The State pattern lets you reduce code duplication by extracting common code into abstract base classes.
Cons- Applying the pattern can be draining memory if a state machine has only a few states or rarely changes.

![UML diagram for State Pattern](state.png "UML class diagram of State")

# Example:-
In this example, the State pattern lets the virtual machine change its state differently, depending on if the state requested to switch is present in allowed list.VirtualMachine_State is the interface for encapsulating the behavior associated with a particular state of the virtual machine. All the other subclasses like shut_down,hibernate,power_on implement a behavior associated with a state of the VM. The VirtualMachine_ class is present to change the current state of the virtual machine object based on the different states(shut_down,hibernate,power_on) passed to it.

# State Design Pattern Output:
Present State: Shut_down -> State is changed to - Power_On
Present State: Power_On -> State is changed to - Sleep_Mode
Present State: Sleep_Mode -> State change to hibernate not possible.
Present State: Sleep_Mode -> State is changed to - Power_On
Present State: Power_On -> State is changed to - Shut_down
Binary file added design-patterns/State-Python/state.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
50 changes: 50 additions & 0 deletions design-patterns/State-Python/state.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
# Base state class
class VirtualMachine_State(object):
name = 'state'
allowed = []

def switch(self, state):
""" Switch to new state """
if state.name in self.allowed:
print('Present State: %s -> State is changed to - %s' %(self, state.name))
self.__class__ = state
else:
print('Present State: %s -> State change to %s not possible.'
%(self, state.name))

def __str__(self):
return self.name

class Shut_down(VirtualMachine_State):
name = 'Shut_down'
allowed = ['Power_On']

class Power_On(VirtualMachine_State):
name = 'Power_On'
allowed = ['Shut_down', 'Sleep_Mode', 'hibernate']

class Sleep_Mode(VirtualMachine_State):
name = 'Sleep_Mode'
allowed = ['Power_On']

class Hibernate(VirtualMachine_State):
name = 'hibernate'
allowed = ['Power_On']

class VirtualMachine_(object):
def __init__(self):
self.state = Shut_down()

def change(self, state):
self.state.switch(state)

if __name__ == '__main__':

c = VirtualMachine_()
c.change(Power_On)

c.change(Sleep_Mode)
c.change(Hibernate)

c.change(Power_On)
c.change(Shut_down)
27 changes: 27 additions & 0 deletions design-patterns/Template-Python/readme.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
# Template Method

Template method defines the structure of an algorithm in an operation, deferring some
steps to subclasses. It lets subclasses redefine certain steps of an algorithm
without changing the algorithm's structure.
When to use
* To implement the similar parts of an algorithm once and leave it up to subclasses to implement the behavior that can vary from class to class.
* when common behavior among subclasses should be factored and localizedin a common class.
* To control subclasses extensions and avoid code duplication.

![UML diagram for template Pattern](template.png "UML class diagram of Template")

# Example :-
This pattern is used for storing various forms of data on the cloud. If the storage capacity is full for respective data, it can'nt be saved. All the forms of data(Movie,game.etc) are stored on the server and accessed the same way(common functionalities) but these data are saved on cloud based on storage space. Since the variation of storage space is checked in the later stages and data is saved and accessed the same way for all items,so template design pattern is used here. Here cloud storage is the abstract template class, Store_Movie and Store_Game are the concrete classes that override the abstract class but not change its structure.

# Template design pattern Output:

Requesting to save Data on cloud.....
1. Saved Game on remote server.
2. Ready to Play.
***********************************
Requesting to save Data on cloud.....
1. Saved Music Album on remote server
2. Ready to Play Album.
***********************************
Requesting to save Data on cloud.....
Not enough space to save.Purchase more storage space!
Binary file added design-patterns/Template-Python/template.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading