Reputation: 677
The following Swift 4 class sets 7 fields from the 7 parameters passed into the constructor.
Seeing as the only job of this constructor is to assign each of these parameters to the fields, one by one, is there any simpler way of writing the code? There appears to be a huge amount of duplication for no real benefit.
public class FactoryForListOfKnownApp {
private let readerForVersion: ReaderForVersion
private let finderForNameOfApp: FinderForNameOfApp
private let listOfAppName: [AppName]
private let factoryForVersionFromVersion: FactoryForVersionFromVersion
private let finderForAppData: FinderForAppData
private let finderForWebPage: FinderForWebPage
private let factoryForBuilderForKnownApp: FactoryForBuilderForKnownApp
public
init(withReaderForVersion readerForVersion: ReaderForVersion,
andFinderForNameOfApp finderForNameOfApp: FinderForNameOfApp,
andListOfAppName listOfAppName: [AppName],
andFactoryForVersionFromVersion factoryForVersionFromVersion: FactoryForVersionFromVersion,
andFinderForAppData finderForAppData: FinderForAppData,
andFinderForWebPage finderForWebPage: FinderForWebPage,
andFactoryForBuilderForKnownApp factoryForBuilderForKnownApp: FactoryForBuilderForKnownApp) {
self.readerForVersion = readerForVersion
self.finderForNameOfApp = finderForNameOfApp
self.listOfAppName = listOfAppName
self.factoryForVersionFromVersion = factoryForVersionFromVersion
self.finderForAppData = finderForAppData
self.finderForWebPage = finderForWebPage
self.factoryForBuilderForKnownApp = factoryForBuilderForKnownApp
}
public func findAppData(withName name: String) -> AppData {
return finderForAppData.findAppData(called: name)
}
// ...
}
Are there any alternatives to writing code like this?
Or are there any Swift proposals for an alternative way of writing such a class?
For example, something like this using a new annotation @Init:
public
class FactoryForListOfKnownApp {
@Init
private let readerForVersion: ReaderForVersion
@Init
private let finderForNameOfApp: FinderForNameOfApp
@Init
private let listOfAppName: [AppName]
@Init
private let factoryForVersionFromVersion: FactoryForVersionFromVersion
@Init
private let finderForAppData: FinderForAppData
@Init
private let finderForWebPage: FinderForWebPage
@Init
private let factoryForBuilderForKnownApp: FactoryForBuilderForKnownApp
public func findAppData(withName name: String) -> AppData {
return finderForAppData.findAppData(called: name)
}
// ...
}
Many thanks
Upvotes: 4
Views: 563
Reputation: 135578
For classes, there is no better alternative, no. (Leaving aside for the moment code generation with an external tool such as Sourcery). Only structs get a default memberwise initializer.
There was a Swift-Evolution proposal in early 2016 for more flexible memberwise initializers (including for classes). As far as I recall, the consensus in the community was that the proposal was generally the right idea, but at the time it was deferred because other tasks had higher priorities.
It hasn't been revisited since and I don't see any chance of it being accepted in the Swift 5 timeframe (i.e. before September 2018). After that, who knows. Something like it will probably eventually come.
Upvotes: 2