There is very little difference between magic and art. It’s an act to create something from nothing.
The template method pattern is a behavioral design pattern that defines the program skeleton of an algorithm in a method, called template method, which defers some steps to subclasses. – Wiki
protocol MagicRecipe { var isDarkMagic: Bool { get } func makeMagic() func addSpecialIngredience() func testMagic() } //: create the template for making the Magic Recipe. All whiteMagic needs to be tested before being released. extension MagicRecipe { final func makeMagic(){ print("Starting the magic-making process...") addSpecialIngredience() if !isDarkMagic { testMagic() } let magicType = isDarkMagic ? "Dark Magic" : "White Magic" print("A new \(magicType) is created! \n") } } //: The magic recipe for getting love class MagicRecipeForLove: MagicRecipe { var isDarkMagic: Bool var name: String var description: String { return name } init(isDarkMagic: Bool = false, name: String){ self.isDarkMagic = isDarkMagic self.name = name print("Creating the magic: \(name)") } func addSpecialIngredience() { let ingredience = isDarkMagic ? "black diamond" : "red diamond" print("Adding \(ingredience) as special ingredience") } func testMagic() { print("testMagicing \(name)") } } //: Sleep Magic is always bad (dark magic) class MagicRecipeForSleep: MagicRecipe { var isDarkMagic: Bool { return true } var name: String var description: String { return name } init(name: String){ self.name = name print("Creating the magic: \(name)") } func addSpecialIngredience() { print("Adding tears from the black witch as special ingredience") } func testMagic() { print("testMagicing \(name)") } } let l1 = MagicRecipeForLove(name: "Long Lasting Love") l1.makeMagic() let l2 = MagicRecipeForLove(isDarkMagic: true, name: "Crazy Stupid Love") l2.makeMagic() let s1 = MagicRecipeForSleep(name: "Sleeping in Emptiness") s1.makeMagic() let s2 = MagicRecipeForSleep(name: "Sleeping and Dreaming") s2.makeMagic()