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:

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:

Varje leverantör vill erbjuda en enkel åtkomst till sina respektive system, i vilka du kan:

Din uppgift är tudelad:

  1. Designa en klass för åtkomst till varje leverantör. De ska alla vara lite olika.
  2. 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.