Add more type hints
diff --git a/patterns/behavioral/publish_subscribe.py b/patterns/behavioral/publish_subscribe.py
index 760d8e7b..40aefd2e 100644
--- a/patterns/behavioral/publish_subscribe.py
+++ b/patterns/behavioral/publish_subscribe.py
@@ -5,21 +5,24 @@
 """
 
 
+from __future__ import annotations
+
+
 class Provider:
-    def __init__(self):
+    def __init__(self) -> None:
         self.msg_queue = []
         self.subscribers = {}
 
-    def notify(self, msg):
+    def notify(self, msg: str) -> None:
         self.msg_queue.append(msg)
 
-    def subscribe(self, msg, subscriber):
+    def subscribe(self, msg: str, subscriber: Subscriber) -> None:
         self.subscribers.setdefault(msg, []).append(subscriber)
 
-    def unsubscribe(self, msg, subscriber):
+    def unsubscribe(self, msg: str, subscriber: Subscriber) -> None:
         self.subscribers[msg].remove(subscriber)
 
-    def update(self):
+    def update(self) -> None:
         for msg in self.msg_queue:
             for sub in self.subscribers.get(msg, []):
                 sub.run(msg)
@@ -27,25 +30,25 @@ def update(self):
 
 
 class Publisher:
-    def __init__(self, msg_center):
+    def __init__(self, msg_center: Provider) -> None:
         self.provider = msg_center
 
-    def publish(self, msg):
+    def publish(self, msg: str) -> None:
         self.provider.notify(msg)
 
 
 class Subscriber:
-    def __init__(self, name, msg_center):
+    def __init__(self, name: str, msg_center: Provider) -> None:
         self.name = name
         self.provider = msg_center
 
-    def subscribe(self, msg):
+    def subscribe(self, msg: str) -> None:
         self.provider.subscribe(msg, self)
 
-    def unsubscribe(self, msg):
+    def unsubscribe(self, msg: str) -> None:
         self.provider.unsubscribe(msg, self)
 
-    def run(self, msg):
+    def run(self, msg: str) -> None:
         print(f"{self.name} got {msg}")
 
 
diff --git a/patterns/behavioral/state.py b/patterns/behavioral/state.py
index 423b749e..db4d9468 100644
--- a/patterns/behavioral/state.py
+++ b/patterns/behavioral/state.py
@@ -8,12 +8,13 @@
 Implements state transitions by invoking methods from the pattern's superclass.
 """
 
+from __future__ import annotations
 
-class State:
 
+class State:
     """Base state. This is to share functionality"""
 
-    def scan(self):
+    def scan(self) -> None:
         """Scan the dial to the next station"""
         self.pos += 1
         if self.pos == len(self.stations):
@@ -22,43 +23,42 @@ def scan(self):
 
 
 class AmState(State):
-    def __init__(self, radio):
+    def __init__(self, radio: Radio) -> None:
         self.radio = radio
         self.stations = ["1250", "1380", "1510"]
         self.pos = 0
         self.name = "AM"
 
-    def toggle_amfm(self):
+    def toggle_amfm(self) -> None:
         print("Switching to FM")
         self.radio.state = self.radio.fmstate
 
 
 class FmState(State):
-    def __init__(self, radio):
+    def __init__(self, radio: Radio) -> None:
         self.radio = radio
         self.stations = ["81.3", "89.1", "103.9"]
         self.pos = 0
         self.name = "FM"
 
-    def toggle_amfm(self):
+    def toggle_amfm(self) -> None:
         print("Switching to AM")
         self.radio.state = self.radio.amstate
 
 
 class Radio:
-
     """A radio.     It has a scan button, and an AM/FM toggle switch."""
 
-    def __init__(self):
+    def __init__(self) -> None:
         """We have an AM state and an FM state"""
         self.amstate = AmState(self)
         self.fmstate = FmState(self)
         self.state = self.amstate
 
-    def toggle_amfm(self):
+    def toggle_amfm(self) -> None:
         self.state.toggle_amfm()
 
-    def scan(self):
+    def scan(self) -> None:
         self.state.scan()
 
 
diff --git a/patterns/creational/borg.py b/patterns/creational/borg.py
index ab364f61..de36a23f 100644
--- a/patterns/creational/borg.py
+++ b/patterns/creational/borg.py
@@ -38,12 +38,12 @@
 class Borg:
     _shared_state: Dict[str, str] = {}
 
-    def __init__(self):
+    def __init__(self) -> None:
         self.__dict__ = self._shared_state
 
 
 class YourBorg(Borg):
-    def __init__(self, state=None):
+    def __init__(self, state: str = None) -> None:
         super().__init__()
         if state:
             self.state = state
@@ -52,7 +52,7 @@ def __init__(self, state=None):
             if not hasattr(self, "state"):
                 self.state = "Init"
 
-    def __str__(self):
+    def __str__(self) -> str:
         return self.state
 
 
diff --git a/patterns/creational/builder.py b/patterns/creational/builder.py
index b1f463ee..22383923 100644
--- a/patterns/creational/builder.py
+++ b/patterns/creational/builder.py
@@ -34,7 +34,7 @@ class for a building, where the initializer (__init__ method) specifies the
 
 # Abstract Building
 class Building:
-    def __init__(self):
+    def __init__(self) -> None:
         self.build_floor()
         self.build_size()
 
@@ -44,24 +44,24 @@ def build_floor(self):
     def build_size(self):
         raise NotImplementedError
 
-    def __repr__(self):
+    def __repr__(self) -> str:
         return "Floor: {0.floor} | Size: {0.size}".format(self)
 
 
 # Concrete Buildings
 class House(Building):
-    def build_floor(self):
+    def build_floor(self) -> None:
         self.floor = "One"
 
-    def build_size(self):
+    def build_size(self) -> None:
         self.size = "Big"
 
 
 class Flat(Building):
-    def build_floor(self):
+    def build_floor(self) -> None:
         self.floor = "More than One"
 
-    def build_size(self):
+    def build_size(self) -> None:
         self.size = "Small"
 
 
@@ -72,19 +72,19 @@ def build_size(self):
 
 
 class ComplexBuilding:
-    def __repr__(self):
+    def __repr__(self) -> str:
         return "Floor: {0.floor} | Size: {0.size}".format(self)
 
 
 class ComplexHouse(ComplexBuilding):
-    def build_floor(self):
+    def build_floor(self) -> None:
         self.floor = "One"
 
-    def build_size(self):
+    def build_size(self) -> None:
         self.size = "Big and fancy"
 
 
-def construct_building(cls):
+def construct_building(cls) -> Building:
     building = cls()
     building.build_floor()
     building.build_size()
diff --git a/patterns/fundamental/delegation_pattern.py b/patterns/fundamental/delegation_pattern.py
index bdcefc9d..34e1071f 100644
--- a/patterns/fundamental/delegation_pattern.py
+++ b/patterns/fundamental/delegation_pattern.py
@@ -28,7 +28,7 @@ class Delegator:
     AttributeError: 'Delegate' object has no attribute 'do_anything'
     """
 
-    def __init__(self, delegate: Delegate):
+    def __init__(self, delegate: Delegate) -> None:
         self.delegate = delegate
 
     def __getattr__(self, name: str) -> Any | Callable:
@@ -44,7 +44,7 @@ def wrapper(*args, **kwargs):
 
 
 class Delegate:
-    def __init__(self):
+    def __init__(self) -> None:
         self.p1 = 123
 
     def do_something(self, something: str) -> str:
diff --git a/patterns/other/blackboard.py b/patterns/other/blackboard.py
index 49f8775f..ef48f501 100644
--- a/patterns/other/blackboard.py
+++ b/patterns/other/blackboard.py
@@ -8,13 +8,14 @@
 
 https://en.wikipedia.org/wiki/Blackboard_system
 """
+from __future__ import annotations
 
 import abc
 import random
 
 
 class Blackboard:
-    def __init__(self):
+    def __init__(self) -> None:
         self.experts = []
         self.common_state = {
             "problems": 0,
@@ -23,12 +24,12 @@ def __init__(self):
             "progress": 0,  # percentage, if 100 -> task is finished
         }
 
-    def add_expert(self, expert):
+    def add_expert(self, expert: AbstractExpert) -> None:
         self.experts.append(expert)
 
 
 class Controller:
-    def __init__(self, blackboard):
+    def __init__(self, blackboard: Blackboard) -> None:
         self.blackboard = blackboard
 
     def run_loop(self):
@@ -44,7 +45,7 @@ def run_loop(self):
 
 
 class AbstractExpert(metaclass=abc.ABCMeta):
-    def __init__(self, blackboard):
+    def __init__(self, blackboard: Blackboard) -> None:
         self.blackboard = blackboard
 
     @property
@@ -59,10 +60,10 @@ def contribute(self):
 
 class Student(AbstractExpert):
     @property
-    def is_eager_to_contribute(self):
+    def is_eager_to_contribute(self) -> bool:
         return True
 
-    def contribute(self):
+    def contribute(self) -> None:
         self.blackboard.common_state["problems"] += random.randint(1, 10)
         self.blackboard.common_state["suggestions"] += random.randint(1, 10)
         self.blackboard.common_state["contributions"] += [self.__class__.__name__]
@@ -71,10 +72,10 @@ def contribute(self):
 
 class Scientist(AbstractExpert):
     @property
-    def is_eager_to_contribute(self):
+    def is_eager_to_contribute(self) -> int:
         return random.randint(0, 1)
 
-    def contribute(self):
+    def contribute(self) -> None:
         self.blackboard.common_state["problems"] += random.randint(10, 20)
         self.blackboard.common_state["suggestions"] += random.randint(10, 20)
         self.blackboard.common_state["contributions"] += [self.__class__.__name__]
@@ -83,10 +84,10 @@ def contribute(self):
 
 class Professor(AbstractExpert):
     @property
-    def is_eager_to_contribute(self):
+    def is_eager_to_contribute(self) -> bool:
         return True if self.blackboard.common_state["problems"] > 100 else False
 
-    def contribute(self):
+    def contribute(self) -> None:
         self.blackboard.common_state["problems"] += random.randint(1, 2)
         self.blackboard.common_state["suggestions"] += random.randint(10, 20)
         self.blackboard.common_state["contributions"] += [self.__class__.__name__]
diff --git a/patterns/structural/decorator.py b/patterns/structural/decorator.py
index 01c91b00..a32e2b06 100644
--- a/patterns/structural/decorator.py
+++ b/patterns/structural/decorator.py
@@ -28,30 +28,30 @@
 class TextTag:
     """Represents a base text tag"""
 
-    def __init__(self, text):
+    def __init__(self, text: str) -> None:
         self._text = text
 
-    def render(self):
+    def render(self) -> str:
         return self._text
 
 
 class BoldWrapper(TextTag):
     """Wraps a tag in <b>"""
 
-    def __init__(self, wrapped):
+    def __init__(self, wrapped: TextTag) -> None:
         self._wrapped = wrapped
 
-    def render(self):
+    def render(self) -> str:
         return f"<b>{self._wrapped.render()}</b>"
 
 
 class ItalicWrapper(TextTag):
     """Wraps a tag in <i>"""
 
-    def __init__(self, wrapped):
+    def __init__(self, wrapped: TextTag) -> None:
         self._wrapped = wrapped
 
-    def render(self):
+    def render(self) -> str:
         return f"<i>{self._wrapped.render()}</i>"
 
 
diff --git a/patterns/structural/facade.py b/patterns/structural/facade.py
index 6561c6dc..f7b00be3 100644
--- a/patterns/structural/facade.py
+++ b/patterns/structural/facade.py
@@ -35,13 +35,13 @@ class CPU:
     Simple CPU representation.
     """
 
-    def freeze(self):
+    def freeze(self) -> None:
         print("Freezing processor.")
 
-    def jump(self, position):
+    def jump(self, position: str) -> None:
         print("Jumping to:", position)
 
-    def execute(self):
+    def execute(self) -> None:
         print("Executing.")
 
 
@@ -50,7 +50,7 @@ class Memory:
     Simple memory representation.
     """
 
-    def load(self, position, data):
+    def load(self, position: str, data: str) -> None:
         print(f"Loading from {position} data: '{data}'.")
 
 
@@ -59,7 +59,7 @@ class SolidStateDrive:
     Simple solid state drive representation.
     """
 
-    def read(self, lba, size):
+    def read(self, lba: str, size: str) -> str:
         return f"Some data from sector {lba} with size {size}"
 
 
diff --git a/patterns/structural/front_controller.py b/patterns/structural/front_controller.py
index 4852208d..92f58b21 100644
--- a/patterns/structural/front_controller.py
+++ b/patterns/structural/front_controller.py
@@ -5,23 +5,27 @@
 Provides a centralized entry point that controls and manages request handling.
 """
 
+from __future__ import annotations
+
+from typing import Any
+
 
 class MobileView:
-    def show_index_page(self):
+    def show_index_page(self) -> None:
         print("Displaying mobile index page")
 
 
 class TabletView:
-    def show_index_page(self):
+    def show_index_page(self) -> None:
         print("Displaying tablet index page")
 
 
 class Dispatcher:
-    def __init__(self):
+    def __init__(self) -> None:
         self.mobile_view = MobileView()
         self.tablet_view = TabletView()
 
-    def dispatch(self, request):
+    def dispatch(self, request: Request) -> None:
         """
         This function is used to dispatch the request based on the type of device.
         If it is a mobile, then mobile view will be called and if it is a tablet,
@@ -39,10 +43,10 @@ def dispatch(self, request):
 class RequestController:
     """front controller"""
 
-    def __init__(self):
+    def __init__(self) -> None:
         self.dispatcher = Dispatcher()
 
-    def dispatch_request(self, request):
+    def dispatch_request(self, request: Any) -> None:
         """
         This function takes a request object and sends it to the dispatcher.
         """

Add type hints to multiple design pattern examples

Related to https://github.com/faif/python-patterns/issues/373