MVC and Choosing Patterns
Consider a small program with a user interface. MVC separates data and domain rules, presentation, and input handling. It covers a broader division of roles than the individual object patterns introduced earlier.
Identify three roles
- Model: Owns state and domain rules, which should make sense without a screen.
- View: Presents model state to the user.
- Controller: Receives input, invokes model actions, and coordinates flow.
class Counter:
def __init__(self):
self.value = 0
def increment(self):
if self.value >= 2:
return False
self.value += 1
return True
def show(model):
print(f"Count: {model.value}")
class Controller:
def __init__(self, model):
self.model = model
def on_increment(self):
if self.model.increment():
show(self.model)
else:
print("Limit reached")
controller = Controller(Counter())
for _ in range(3):
controller.on_increment()
The outputs are Count: 1, Count: 2, and Limit reached. The maximum of two belongs to the model, so changing presentation leaves that rule intact. Here the controller calls the view directly. Other MVC implementations use observation or framework machinery; boundaries vary by framework.
Apply patterns to a small project
Begin a reading-list application with straightforward adding, displaying, and saving. Then respond to actual changes:
- Consider Strategy when sorting methods must change.
- Consider Observer when several displays need updates.
- Consider Adapter when an external book API has an incompatible format.
- Consider Command and history when deletion needs undo.
Using more patterns does not guarantee better design. Clear change boundaries and code readers can follow matter more.
Check your understanding
What goes wrong if a maximum-count rule exists only as a disabled button?
Show explanation
Another screen or API can bypass the restriction by calling the model directly. Presentation guides input; the model also enforces core rules. Avoid scattering the same rule across multiple screens.