Laboration 7
Under dagens laboration tittar vi vidare på designmönster.
Uppgiften
Din uppgift är att applicera några designmönster på diverse problem.
Deluppgift 1: Builder
Hos företaget Dr Frankensteins kennel och workshop kan du individanpassa ditt framtida husdjur. Dr Frankenstein vill förenkla arbetet genom att bygga ett enkelt program som hjälper honom med ihopsättandet av husdjur. Han erbjuder två olika grundarter (katt och hund), som du som kund kan bygga om efter eget huvud. Du kan ange antal huvud, ben och svansar. Dessutom kan du ge ditt stackars djur ett namn och ange kön på det.
Följande filer med klasser är givna:
director.py
from pet import Pet
from builder import PetBuilder
class Director:
def __init__(self):
pass
def order(self) -> Pet:
species = ""
pet = None
print("Welcome to Dr Frankenstein's kennel and workshop!")
while not (species == "dog" or species == "cat"):
species = input("What kind of pet would you like? (dog/cat)\n")
name = input("A wise choice! What will their name be?\n")
sex = input("That's a good name! Would you like a male or female " + species + "?\n")
legs = input("That makes sense. How many legs would you like it to have?\n")
tails = input("A bold decision! How many tails?\n")
heads = input("Oooh, I like that! How many heads?\n")
print("Well, that's a bit unorthodox. Any way, here's your " + species + ". Enjoy!")
return PetBuilder()\
.a(species)\
.with_name(name)\
.of_sex(sex)\
.with_heads(heads)\
.with_legs(legs)\
.with_tails(tails)\
.build()
director = Director()
pet = director.order()
pet.present()
pet.py
from abc import ABC, abstractmethod
class Pet(ABC):
_nbr_of_legs: int = 0
_nbr_of_heads: int = 0
_nbr_of_tails: int = 0
_name: str = ""
_sex: str = ""
_species: str = ""
def __init__(self):
self._species = "Undefined"
def get_nbr_of_legs(self) -> int:
return self._nbr_of_legs
def set_nbr_of_legs(self, legs: int) -> None:
self._nbr_of_legs = legs
def get_nbr_of_heads(self) -> int:
return self._nbr_of_heads
def set_nbr_of_heads(self, heads: int) -> None:
self._nbr_of_heads = heads
def get_nbr_of_tails(self) -> int:
return self._nbr_of_tails
def set_nbr_of_tails(self, tails: int) -> None:
self._nbr_of_tails = tails
def get_name(self) -> str:
return self._name;
def set_name(self, name: str) -> None:
self._name = name
def get_sex(self) -> str:
return self._sex;
def set_sex(self, sex: str) -> None:
self._sex = sex
def present(self) -> None:
print(self.speak_up())
print("My name is " + self._name + " and I'm a " + self._species)
print("I have " + str(self._nbr_of_heads) + " heads and " + str(self._nbr_of_legs) + " legs.")
print("Also, I have " + str(self._nbr_of_tails) + " tails and I am a " + self._sex)
print("My life is a mess.")
@abstractmethod
def speak_up(self) -> str:
pass
Saknade klasser
Du saknar klasserna PetBuilder, Dog och Cat. Implementera dem. Som en hjälp på vägen kan det vara bra att veta följande:
- PetBuilder behöver, förutom konstruktorn, inte några andra metoder än de som anropas i Director.
- Samtliga metoder i PetBuilder (bortsett från build() och konstruktorn) returnerar en instans av PetBuilder-objektet
- PetBuilder.build() ska returnera ett objekt av typen Pet.
Kör programmet
Kör programmet genom att köra igång Python med director.py som argument:
> python director.py
Deluppgift 2: Façade
Resebyrån Transsylvanienspecialisten erbjuder paketresor till resenärer som inte är så bekväma med rumänska, men tycker att det här med resor till Transsylvanien är häftigt. Företaget har ett flertal olika leverantörer, nämligen:
- Två flygbolag som flyger till Târgu Mureș, Budapest, Cluj-Napoca och Bukarest.
- Det statliga järnvägsbolaget som kör tåg mellan de fyra städerna.
- Ett bussbolag som kör rundturer från Târgu Mureș och Cluj-Napoca till häftiga platser i Transsylvanien.
- Tre suspekta hotell med märkliga ägare.
- Fyra restauranger med risk för matförgiftning.
Varje leverantör vill erbjuda en enkel åtkomst till sina respektive system, i vilka du kan:
- Kontrollera tillgänglighet för ett givet datumintervall.
- Göra en prisförfrågan.
- Göra en bokning.
Din uppgift är tudelad:
- Designa en klass för åtkomst till varje leverantör. De ska alla vara lite olika.
- Du ska designa backenden på ett resebokningssystem åt företaget. Du inser så klart att det här är klyddigt för er frontendutvecklare och vill bygga ett gränsnitt som hen kan arbeta mot. Du använder dig därför av mönstret façade för att abstrahera bort de här konstiga klasserna.
Du väljer själv om du vill göra uppgiften i Python-kod eller i UML.