Decorator: Wrap Additional Behavior
A string store needs logging. Rather than editing the store or subclassing every storage type, wrap it in another object exposing the same method.
Intercept, then delegate
class MemoryStore:
def __init__(self):
self.items = []
def write(self, text):
self.items.append(text)
class LoggedStore:
def __init__(self, inner):
self.inner = inner
def write(self, text):
print("write:", text)
self.inner.write(text)
store = MemoryStore()
LoggedStore(store).write("hello")
print(store.items)
The program prints write: hello, followed by the stored ['hello']. Both LoggedStore and MemoryStore offer write(text). A caller need not know that a logging layer is present.
Multiple wrappers can add compression and encryption, but order matters: compressing before encryption differs from the reverse. Many layers can also make failures harder to trace.
Distinguish Python’s @ syntax
Python decorators transform functions or classes. They can help implement related wrapping behavior, but the language feature is not identical to the object design pattern. This example uses ordinary object composition.
Check your understanding
If the wrapper exposes save_with_log instead of write, can existing callers use it unchanged?
Show explanation
No. Callers expecting write would break. Decorator adds behavior while preserving the interface and behavioral promises expected by users of the wrapped object.