Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it possible for protocols to have a default implementation of static factory methods?

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?

like image 759
Zomagk Avatar asked Dec 01 '16 04:12

Zomagk


People also ask

Should factory method be static?

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.

When to use static factory method?

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.

When to use static method in swift?

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.


1 Answers

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.

like image 191
matt Avatar answered Sep 28 '22 05:09

matt