I am implementing the visitor pattern in Swift 2.2 for a project at work.
So that I don't have to boil down my source code and to save me some time I will use an example of visitor pattern in swift by Oktawian Chojnacki.
protocol PlanetVisitor {
func visit(planet: PlanetAlderaan)
func visit(planet: PlanetCoruscant)
func visit(planet: PlanetTatooine)
}
protocol Planet {
func accept(visitor: PlanetVisitor)
}
class PlanetAlderaan: Planet {
func accept(visitor: PlanetVisitor) { visitor.visit(self) }
}
class PlanetCoruscant: Planet {
func accept(visitor: PlanetVisitor) { visitor.visit(self) }
}
class PlanetTatooine: Planet {
func accept(visitor: PlanetVisitor) { visitor.visit(self) }
}
class NameVisitor: PlanetVisitor {
var name = ""
func visit(planet: PlanetAlderaan) { name = "Alderaan" }
func visit(planet: PlanetCoruscant) { name = "Coruscant" }
func visit(planet: PlanetTatooine) { name = "Tatooine" }
}
The problem I have been trying to solve is to reduce the boilerplate on each class that derives from Planet
. As you can see they all have same function duplicated func accept(visitor: PlanetVisitor) { visitor.visit(self) }
.
I have tried putting a default implementation on the Planet
protocol and implementing it on a base class and Swift does not seem to allow it due to compile time overload resolution.
Examples:
Default Implementation on Protocol:
extension Planet {
func accept(visitor: PlanetVisitor) { visitor.visit(self) }
}
Base Class:
class PlanetBase: Planet {
func accept(visitor: PlanetVisitor) { visitor.visit(self) }
}
class PlanetAlderaan: PlanetBase {}
class PlanetCoruscant: PlanetBase {}
class PlanetTatooine: PlanetBase {}
Does anyone know of a way that the accept
function could be made generic and applied automatically to each concrete class that derives from Planet
? It is not a critical issue but it is a great puzzle!
Aucun commentaire:
Enregistrer un commentaire