I'm solving the following problem using the Mediator design pattern in Swift:
Assume we track the location of all our mobile mechanics. We have noticed that there are times when a mobile mechanic might need assistance from another mechanic or a last minute need for a part that someone else might carry. We want to build a system where mechanics can send requests with the option of defining specific parts needed to all mechanics that are close to their location
I would love some feedback on how I can improve this, more importantly if it remains true to the definition of the Mediator pattern.
Here is the code, the full repo can be found here: Design Patterns in Swift: Mediator
import Foundation
class Mechanic{
let mediator: Mediator
var location: (Int, Int)
var name: String
init (mediator: Mediator, name: String, location: (Int, Int)){
self.mediator = mediator
self.name = name
self.location = location
}
func send(request: Request){
mediator.send(request)
}
func receive(request: Request){
print("\(name) received request from \(request.mechanic.name): \(request.message)")
if let parts = request.parts{
print("request is for parts:")
for part in parts{
print(part.name)
}
}
print("******************")
}
func isCloseTo(mechanic: Mechanic, within distance: Float) -> Bool
{
return hypotf(Float(mechanic.location.0 - location.0), Float(mechanic.location.1 - location.1)) <= distance
}
}
class Part{
var name: String
var price: Double
init (name: String, price: Double){
self.name = name
self.price = price
}
}
class Request {
var message: String
var parts: [Part]?
var mechanic: Mechanic
init(message: String, mechanic: Mechanic, parts: [Part]?)
{
self.message = message
self.parts = parts
self.mechanic = mechanic
}
convenience init(message: String, mechanic: Mechanic){
self.init(message: message, mechanic: mechanic, parts: nil)
}
}
protocol Mediator{
func send(request: Request)
}
class RequestMediator: Mediator{
private let closeDistance: Float = 50.0
private var mechanics: [Mechanic] = []
func addMechanic(mechanic: Mechanic){
mechanics.append(mechanic)
}
func send(request: Request) {
for oneOfTheMechanics in mechanics{
if oneOfTheMechanics !== request.mechanic && request.mechanic.isCloseTo(oneOfTheMechanics, within: closeDistance){
oneOfTheMechanics.receive(request)
}
}
}
}
Here is the main setup and some test cases
import Foundation
var requestManager = RequestMediator()
var steve = Mechanic(mediator: requestManager, name: "Steve Akio", location: (23,12))
var joe = Mechanic(mediator: requestManager, name: "Joe Bob", location: (13,12))
var dave = Mechanic(mediator: requestManager, name: "Dave Far", location: (823,632))
var mike = Mechanic(mediator: requestManager, name: "Mike Nearfar", location: (800,604))
requestManager.addMechanic(steve)
requestManager.addMechanic(joe)
requestManager.addMechanic(dave)
requestManager.addMechanic(mike)
steve.send(Request(message: "I can't find this address anyone close by knows where Rengstorff Ave is?", mechanic: steve))
joe.send(Request(message: "I need some brake pads anyone close by has some?", mechanic: joe, parts: [Part(name: "StopIt Brake Pads", price: 35.25)]))
dave.send(Request(message: "Dang it I spilled all my oil, anyone around here got a spare 5 Quart Jug.. and some filters too", mechanic: dave, parts:[Part(name: "Engine Oil SuperPlus", price: 23.33), Part(name: "Filters", price: 4.99)]))
Here is the output you get with this setup:
Joe Bob received request from Steve Akio: I can't find this address anyone close by knows where Rengstorff Ave is?
******************
Steve Akio received request from Joe Bob: I need some brake pads anyone close by has some?
request is for parts:
StopIt Brake Pads
******************
Mike Nearfar received request from Dave Far: Dang it I spilled all my oil, anyone around here got a spare 5 Quart Jug.. and some filters too
request is for parts:
Engine Oil SuperPlus
Filters
******************
Program ended with exit code: 0