Consider a protocol that have a factory method:
public protocol Frobnicator {
func frobnicate()
static func makeRightFrobnicator() -> Frobnicator
}
private class SomeFrobnicatorImplementation: Frobnicator { ... }
private class AnotherFrobnicatorImplementation: Frobnicator { ... }
public extension Frobnicator {
static func makeRightFrobnicator() -> Frobnicator {
if something {
return SomeFrobnicatorImplementation()
} else {
return AnotherFrobnicatorImplementation()
}
}
}
I want to be able to construct different implementors at different times. The implementors themselves are private to the module, whereas the protocol is public to use in the client code.
When I try the code similar to that above, I get “Static member makeRightFrobnicator
cannot be used on protocol metatype Frobnicator.Protocol
.”
Is there any way around it, or should I just use a free function?
Specifically with the Factory pattern, no, there is no requirement that the factory methods be static. The essence of the pattern is that you have one object which is responsible for creating instances of another class.
A static factory method is a public static method on the object that returns a new instance of the object. These type of methods share the same benefits as the traditional factory method design pattern. This is especially useful for value objects that don't have a separate interface and implementation class.
A static method is of class type (associated with class rather than object), so we are able to access them using class names. Note: Similarly, we can also create static methods inside a struct. static methods inside a struct are of struct type, so we use the struct name to access them.
The static function implementation is legal:
protocol P {
static func f() -> P
init()
}
extension P {
static func f() -> P {return self.init()}
}
But you'll notice that in order to get it to compile, I had to guarantee to the compiler that I have in hand a legal way to make a P so as to able to return one.
The issue in your code is the attempt to return a specific adopter of your protocol, like a SomeFrobnicatorImplementation. A protocol is agnostic as to who adopts it. To put it another way, you cannot guarantee within the protocol definition that SomeFrobnicatorImplementation will in fact be an adopter of this protocol. Thus, that part of your code is illegal.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With