There are a lot of questions out there that are similar, but I'm having a hard time finding something that explains exactly what I'm looking for
I have multiple Services
, which handle a generic Data
type. They currently all subclass an semi-"abstract" class, DataService
This is because all of these Services
have the same stored properties:
class DataService<T: Data> {
let id: String
let eventDataProviders: [EventDataProvider]
private let storedDataProviders: [StoredDataProvider]
and their init
are the same as well:
init(id: String, eventDataProviders: [EventDataProvider], storedDataProviders: [StoredDataProvider]) {
self.id = id
self.storedDataProviders = storedDataProviders
self.eventDataProviders = eventDataProviders
self.setupStoredDataProviders()
self.setupEventDataProviders()
}
the setup
methods are also the same
The difference between these classes is how they handle data, currently defined in an "abstract" function
func eventReceivedHandler() -> ((T) -> Void) {
fatalError("DataService does not have eventReceivedHandler defined")
}
Most resources recommend Protocols and Protocol Extensions. Which I would prefer as well, but I think the two things that make that difficult are:
Trying to reduce duplicate code by keeping the stored property declarations in one place, and by sharing an
init
The generic type on the class, it doesn't seem straight-forward to maintain that through a protocol
But the problem with this current solution is
- The "abstract" class is exposed, when we don't want anybody to actually instantiate an instance
- The
eventReceivedHandler
isn't compiler-enforced
Is there a correct solution here? I thought this architecture may be common enough, but I've really been struggling finding anything around online, my search queries contain too many overused terms