Specific Patterns Prep
Overview
There are four design patterns that you’ve likely used and will find useful, so we’re going to focus on those today.
Basic Learning Objectives
Before class, you should be able to:
- Define what the Observer, Iterator, Decorator, and State design patterns are
Advanced Learning Objectives
After class, you should be able to:
- Implement these four patterns in Python
- Explain how code smells, class design principles, and design patterns reinforce each other or possibly conflict
Readings
To achieve the basic learning objectives, read the following:
- Observer Design Pattern - skip the pseudocode, look at the Python example if you want
- Iterator Design Pattern - ditto, Python example
- Decorator Design Pattern - ditto, Python example
- State Design Pattern - ditto, Python
Checks
Submit answers to the following on Moodle. Given the following code snippets that should be refactored, which pattern do you think they need and why? (Note, the TODOs are hints, not things that you should do.)
-
class WeatherStation: def __init__(self): self.temp = 0 self.phone_app = PhoneApp() self.window_display = WindowDisplay() #TODO: Add the rest of the displays def set_temperature(self, temp): self.temp = temp self.phone_app.update(temp) self.window_display.update(temp) #TODO: Add the rest of the displays -
class BookShelf: '''Must store books as a dictionary of lists grouped by genre''' def __init__(self): self.books_by_genre = {"Sci-Fi": ["Dune"], "Tech": ["Clean Code"]} #TODO: add the rest of the books from the library #Client code below shelf = BookShelf() for genre in shelf.books_by_genre: for book in shelf.books_by_genre[genre]: print(book) -
class SimpleCoffee: def get_cost(self): return 2.0 class CoffeeWithMilk(SimpleCoffee): def get_cost(self): return 2.5 class CoffeeWithMilkAndSugar(CoffeeWithMilk): def get_cost(self): return 2.7 #TODO: Add the rest of the extra option subclasses along with all combos -
class VendingMachine: def __init__(self, count): self.count = count self.state = "NO_QUARTER" if count > 0 else "OUT_OF_STOCK" def insert_quarter(self): if self.state == "HAS_QUARTER": print("You can't insert another quarter.") elif self.state == "NO_QUARTER": self.state = "HAS_QUARTER" print("Quarter inserted.") elif self.state == "OUT_OF_STOCK": print("Machine is out of stock.") elif self.state == "SOLD": print("Please wait, we're already giving you a soda.") #TODO: Add those additional states the customer was asking about def turn_crank(self): if self.state == "HAS_QUARTER": print("You turned...") self.state = "SOLD" self.dispense() elif self.state == "NO_QUARTER": print("You turned, but there's no quarter.") #TODO: add the rest of the states, my fingers are tired...