Through inheritance, we can make our ServicesFactory into a ServicesFactoryType and then ensure that, instead of conforming to ServicesFactoryType, both iOSServicesFactory and macOSServicesFactory inherit from ServicesFactory.
All common services can then be implemented on ServicesFactory, instead of repeatedly on each ServicesFactoryType implementation, as follows:
class ServicesFactory: ServicesFactoryType {
static let shared: ServicesFactoryType = {
/* same implementation */
}()
internal init() {}
func getPushService() -> PushNotificationService {
fatalError("abstract method, implement in subclasses")
}
func getUserLocationService() -> UserLocationService {
return CommonUserLocationService()
}
}
Now, ServicesFactory is a properly abstract class, as it implements all methods from ServicesFactoryType and provides a default implementation for getUserLocationServices().
We also need to update our specific implementations in order to inherit from ServicesFactory, and change from struct to class, as structs don't let you inherit, but only conform to protocols:
class macOSServicesFactory: ServicesFactory {
override func getPushService() -> PushNotificationService { /* */ }
}
class iOSServicesFactory: ServicesFactory {
override func getPushService() -> PushNotificationService { /* */ }
}
And we're done!
You'll notice that this solution is very object-oriented, and leveraging inheritance is not very Swifty. Let's see how we can use protocols to achieve a similar result.