Notes and exercises for learning design patterns
Practice using factory methods when a class has several natural ways to create itself.
The focus of this exercise is not choosing between different classes. The focus is naming different construction paths clearly.
You will create a Document class that stores a normalized document:
Document(title: str, body: str)
The final object should always store plain text in body, but callers may provide input in different formats.
Open exercise1.py and complete the Document class.
Implement these class methods:
Document.from_plain_text(title, text)
Document.from_markdown(title, markdown)
Document.from_html(title, html)
Each method should return a Document.
from_plain_textShould:
DocumentExample:
doc = Document.from_plain_text(" Notes ", " Hello world ")
assert doc.title == "Notes"
assert doc.body == "Hello world"
from_markdownShould:
#, ##, and ###**DocumentExample:
doc = Document.from_markdown(
" Notes ",
"# Heading\n\nThis is **important**.",
)
assert doc.title == "Notes"
assert "#" not in doc.body
assert "**" not in doc.body
assert "Heading" in doc.body
assert "important" in doc.body
You do not need to build a real Markdown parser. Keep the conversion simple.
from_htmlShould:
&DocumentExample:
doc = Document.from_html(
" Notes ",
"<h1>Heading</h1><p>Alice & Bob</p>",
)
assert doc.title == "Notes"
assert "<h1>" not in doc.body
assert "Alice & Bob" in doc.body
The skeleton file includes a small run_tests() function. After completing the exercise, this command should pass:
python exercise1.py
The tests check behavior like this:
def test_plain_text_document_creation():
doc = Document.from_plain_text(" Notes ", " Hello world ")
assert doc.title == "Notes"
assert doc.body == "Hello world"
def test_markdown_document_creation():
doc = Document.from_markdown(
" Notes ",
"# Heading\n\nThis is **important**.",
)
assert doc.title == "Notes"
assert "#" not in doc.body
assert "**" not in doc.body
assert "Heading" in doc.body
assert "important" in doc.body
def test_html_document_creation():
doc = Document.from_html(
" Notes ",
"<h1>Heading</h1><p>Alice & Bob</p>",
)
assert doc.title == "Notes"
assert "<h1>" not in doc.body
assert "Alice & Bob" in doc.body
You can add more tests if your implementation handles more Markdown or HTML cases.
Document.from_markdown(...) clearer than Document(...)?Document.create(...) be a good name here? Why or why not?@staticmethod or @classmethod?Factory methods are useful when the same class has several meaningful ways to be created.
In this exercise:
Document.from_plain_text(...)
Document.from_markdown(...)
Document.from_html(...)
all return a Document, but each method explains how the input should be interpreted.
Back to Factory Methods as Named Constructors · Script · Solution