BP1 - Gun (Iterator) - Design Pattern From Simple Things
There are bullets that need to be fired one by one in a specific order. You need a tool to set it up neatly and easily upgrade later.
Gun (Iterator) is a behavioral design pattern: 🖤🖤🖤🖤🤍
IteratorandIterableoften confused me, so I renamed them.Gunrepresents Iterator,Bulletsrepresents Iterable.
What is Gun and Bullets?
Bullets(Iterable) is a group of bullets.def __iter__()helps us arrange bullets and other accessories to turn them into a gun.
Gun(Iterator) is an object that can fire bullet one by one.def __next__()help us fire the bullets.
Why use Gun?
It makes shooting more manageable, more professional. Your gun can integrate other tools such as a compass, binoculars, and silencer…!
Question: Just throw the bullet to the target, the gun seems to just make it fancy!
Answer: It is more useful when you need to use plugins or customize many features with your gun.
When to use Gun?
Question: When I need to use Gun?
Answer: When you need to fire the bullets!
Input:
- Having many bullets:
1stBullet2ndBullet3rdBullet
# nothing here
Expected Output:
- Firing bullets in expected order by:
- Getting a
Normal Gun- First Shoot will fire
1stBullet - Then
2ndBullet, 3rdBullet
- First Shoot will fire
- Getting a
LIFO Gun- First Shoot will fire
3rdBullet - Then
2ndBullet, 1stBullet
- First Shoot will fire
- Getting a
⬅️ Normal Gun 🔫:
🎯First Shoot: 1stBullet
🎯The Rest: 2ndBullet-3rdBullet
🔄 LIFO Gun 🔫:
🎯First Shoot: 3rdBullet
🎯The Rest: 2ndBullet-1stBullet
How to implement Gun?
Non-Gun implementation:
if __name__ == "__main__":
bullets = []
# Input 1: Having many bullets:
bullets.append("1stBullet")
bullets.append("2ndBullet")
bullets.append("3rdBullet")
gun = iter(bullets)
first_fired_bullet = next(gun)
remaining_bullets = "-".join(gun)
# Expected Output 1: Firing bullets in expected order by: Normal Gun
print(
f"⬅️ Normal Gun 🔫:\n🎯First Shoot: {first_fired_bullet} \n🎯The Rest: {remaining_bullets}"
)
lifo_gun = iter(bullets[::-1])
first_fired_bullet = next(lifo_gun)
remaining_bullets = "-".join(lifo_gun)
# Expected Output 2: Firing bullets in expected order by: LIFO Gun
print(
f"🔄 LIFO Gun 🔫:\n🎯First Shoot: {first_fired_bullet} \n🎯The Rest: {remaining_bullets}"
)
Gun implementation:
from collections.abc import Iterable, Iterator
class Bullets(Iterable):
def __init__(self, bullets=None):
self._bullets = bullets or []
# to_normal_gun
def __iter__(self):
return Gun(self._bullets)
def to_lifo_gun(self):
return Gun(self._bullets, reverse=True)
def load(self, bullet):
self._bullets.append(bullet)
class Gun(Iterator):
_position = None
_reverse = False
def __init__(self, bullets, reverse=False):
self._bullets = bullets
self._reverse = reverse
self._position = -1 if reverse else 0
def __next__(self):
try:
value = self._bullets[self._position]
self._position += -1 if self._reverse else 1
except IndexError:
raise StopIteration()
return value
if __name__ == "__main__":
bullets = Bullets()
# Input 1: Having many bullets:
bullets.load("1stBullet")
bullets.load("2ndBullet")
bullets.load("3rdBullet")
gun = iter(bullets)
first_fired_bullet = next(gun)
remaining_bullets = "-".join(gun)
# Expected Output 1: Firing bullets in expected order by: Normal Gun
print(
f"⬅️ Normal Gun 🔫:\n🎯First Shoot: {first_fired_bullet} \n🎯The Rest: {remaining_bullets}"
)
lifo_gun = bullets.to_lifo_gun()
first_fired_bullet = next(lifo_gun)
remaining_bullets = "-".join(lifo_gun)
# Expected Output 2: Firing bullets in expected order by: LIFO Gun
print(
f"🔄 LIFO Gun 🔫:\n🎯First Shoot: {first_fired_bullet} \n🎯The Rest: {remaining_bullets}"
)
Related posts
-
Verify vs Cert: The Python Requests Handbook
Understanding SSL/TLS in Python Requests: The 'verify' and 'cert' arguments explained with interactive animations.
-
SP7 - Proxy - Learn Design Pattern From Simple Things
The boss blocks social media so employees stay focused. That's exactly how the Proxy pattern works — controlling access between objects.
-
SP6 - Object Pool - Learn Design Pattern From Simple Things
Manufacturing planes is expensive, but raw parts are reused from a pool. That's the Object Pool pattern — reduce creation cost with smart reuse.
-
SP5 - Facade - Learn Design Pattern From Simple Things
Many departments, one entrance. The Facade pattern simplifies complex systems by exposing only what you need. Learn it from simple everyday things.