Mr. Latte


Lesson 4 of 13

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.

Looking for a product partner? Founders, teams, businesses: from problem framing to launch.