There is a dancing festival every year. Gods, Fairies and some other VIPs are in the guest list. There are also some unwelecomed walk-ins. Each of the guest type would have different host to receive and host them, except the walk-ins would have no hosts.
The chain of responsibility pattern is used to process varied requests, each of which may be dealt with by a different handler.
enum GuestType {
case VIP
case God
case Fairy
case Unwelcomed
}
struct Guest {
let guestType : GuestType
let name : String
}
class Host {
var nextHost : Host ?
required init (){}
func host ( guest : Guest , handled : Bool = false ) -> Bool {
if nextHost != nil {
return nextHost ! . host ( guest , handled : handled )
} else if ! handled {
print ( "End of the chain. No host available for \(guest.name) \n " )
}
return handled
}
class func createChain () -> Host ? {
let host = VIPHost ()
host . nextHost = GodHost ()
host . nextHost ? . nextHost = FairyHost ()
return host
}
}
class FairyHost : Host {
override func host ( guest : Guest , var handled : Bool ) -> Bool {
if guest . guestType == . Fairy {
print ( "\(guest.name) is handled by FairyHost \n " )
handled = true
}
return super . host ( guest , handled : handled )
}
}
class GodHost : Host {
override func host ( guest : Guest , var handled : Bool ) -> Bool {
if guest . guestType == . God {
print ( "\(guest.name) is handled by GodHost \n " )
handled = true
}
return super . host ( guest , handled : handled )
}
}
class VIPHost : Host {
var totalGuests = 0
var vipGuests = 0
override func host ( guest : Guest , var handled : Bool ) -> Bool {
totalGuests ++
if guest . guestType == . VIP {
print ( "\(guest.name) is handled by VIPHost" )
handled = true
vipGuests ++
print ( "Currently \(vipGuests) VIP out of \(totalGuests) guests \n " )
}
return super . host ( guest , handled : handled )
}
}
//: Testing
let guests = [ Guest ( guestType : . Fairy , name : "Tinkle Fairy" ),
Guest ( guestType : . God , name : "God of Thunder" ),
Guest ( guestType : . VIP , name : "VIP Tor" ),
Guest ( guestType : . Unwelcomed , name : "Satan" ),
Guest ( guestType : . VIP , name : "VIP Helen" )]
if let hostChain = Host . createChain () {
for guest in guests {
hostChain . host ( guest )
}
}