+1 for factory initializers on classes. -0.5 for factory initializers on protocols.
I believe there is a strong pairing between Dependency Inversion (from SOLID principals, that you should depend on abstractions like protocols instead of concretions like a particular class) and dependency injection (that your implementation should be given the instances of the abstraction you need rather than creating concrete classes on its own) By having your code depend on a factory initializer at runtime to get its abstractions, you are limited in your ability to adapt the code to other scenarios such as testing. You may for instance need to put your factory initializer on your protocol into a ‘testing mode’ in order to perform unit testing on your code. Or in other words, while its already possible to have factory methods and factory functions, I worry that factory initializers will result in APIs being unknowingly designed toward a higher degree of coupling in their code. Having factory initializers provides a greater degree of “blessing” in API design to (what I at least consider to be) an anti-pattern. -DW > On Mar 22, 2016, at 4:42 AM, Patrick Pijnappel via swift-evolution > <[email protected]> wrote: > > Definitely a +1 here on interest for this proposal, have run into this > several times. > > On Tue, Mar 22, 2016 at 5:16 PM, Riley Testut via swift-evolution > <[email protected] <mailto:[email protected]>> wrote: > Hey all! > > Very sorry, restored my MacBook at the beginning of the calendar year, and > forgot to re-subscribe to Swift-Evolution 😄. Once I realized this, I decided > to hold off on pushing this forward till after Swift 2.2, and now that it's > been released, I'd love to make moves on this! > > So, is there still an interest in the proposal? If so, I'll write up a new > proposal with everyone's feedback, and then post it here for more discussion. > I think this would very valuable (and would certainly help a bunch in my > current app), but want to see where everyone stands! > > Riley Testut > > On Feb 8, 2016, at 11:26 AM, Charles Srstka <[email protected] > <mailto:[email protected]>> wrote: > > >> On Dec 17, 2015, at 3:41 PM, Riley Testut via swift-evolution > >> <[email protected] <mailto:[email protected]>> wrote: > >> > >> Recently, I proposed the idea of adding the ability to implement the > >> "class cluster" pattern from Cocoa (Touch) in Swift. However, as we > >> discussed it and came up with different approaches, it evolved into a > >> functionality that I believe is far more beneficial to Swift, and > >> subsequently should be the focus of its own proposal. So here is the > >> improved (pre-)proposal: > >> > >> # Factory Initializers > >> > >> The "factory" pattern is common in many languages, including Objective-C. > >> Essentially, instead of initializing a type directly, a method is called > >> that returns an instance of the appropriate type determined by the input > >> parameters. Functionally this works well, but ultimately it forces the > >> client of the API to remember to call the factory method instead, rather > >> than the type's initializer. This might seem like a minor gripe, but given > >> that we want Swift to be as approachable as possible to new developers, I > >> think we can do better in this regard. > >> > >> Rather than have a separate factory method, I propose we build the factory > >> pattern right into Swift, by way of specialized “factory initializers”. > >> The exact syntax was proposed by Philippe Hausler from the previous > >> thread, and I think it is an excellent solution: > >> > >> class AbstractBase { > >> public factory init(type: InformationToSwitchOn) { > >> return ConcreteImplementation(type) > >> } > >> } > >> > >> class ConcreteImplementation : AbstractBase { > >> > >> } > >> > >> Why exactly would this be useful in practice? In my own development, I’ve > >> come across a few places where this would especially be relevant: > >> > >> ## Class Cluster/Abstract Classes > >> This was the reasoning behind the original proposal, and I still think it > >> would be a very valid use case. The public superclass would declare all > >> the public methods, and could delegate off the specific implementations to > >> the private subclasses. Alternatively, this method could be used as an > >> easy way to handle backwards-compatibility: rather than litter the code > >> with branches depending on the OS version, simply return the > >> OS-appropriate subclass from the factory initializer. Very useful. > >> > >> ## Protocol Initializers > >> Proposed by Brent Royal-Gordon, we could use factory initializers with > >> protocol extensions to return the appropriate instance conforming to a > >> protocol for the given needs. Similar to the class cluster/abstract class > >> method, but can work with structs too. This would be closer to the factory > >> method pattern, since you don’t need to know exactly what type is > >> returned, just the protocol it conforms to. > >> > >> ## Initializing Storyboard-backed View Controller > >> This is more specific to Apple Frameworks, but having factory initializers > >> could definitely help here. Currently, view controllers associated with a > >> storyboard must be initialized from the client through a factory method on > >> the storyboard instance (storyboard. > >> instantiateViewControllerWithIdentifier()). This works when the entire > >> flow of the app is storyboard based, but when a single storyboard is used > >> to configure a one-off view controller, having to initialize through the > >> storyboard is essentially use of private implementation details; it > >> shouldn’t matter whether the VC was designed in code or storyboards, > >> ultimately a single initializer should “do the right thing” (just as it > >> does when using XIBs directly). A factory initializer for a View > >> Controller subclass could handle the loading of the storyboard and > >> returning the appropriate view controller. > >> > >> Here are some comments from the previous thread that I believe are still > >> relevant: > >> > >> > >>> On Dec 9, 2015, at 1:06 PM, Philippe Hausler <[email protected] > >>> <mailto:[email protected]>> wrote: > >>> > >>> I can definitely attest that in implementing Foundation we could have > >>> much more idiomatic swift and much more similar behavior to the way > >>> Foundation on Darwin actually works if we had factory initializers. > >> > >> > >>> On Dec 7, 2015, at 5:24 PM, Brent Royal-Gordon <[email protected] > >>> <mailto:[email protected]>> wrote: > >>> > >>> A `protocol init` in a protocol extension creates an initializer which is > >>> *not* applied to types conforming to the protocol. Instead, it is > >>> actually an initializer on the protocol itself. `self` is the protocol > >>> metatype, not an instance of anything. The provided implementation should > >>> `return` an instance conforming to (and implicitly casted to) the > >>> protocol. Just like any other initializer, a `protocol init` can be > >>> failable or throwing. > >>> > >>> Unlike other initializers, Swift usually won’t be able to tell at compile > >>> time which concrete type will be returned by a protocol init(), reducing > >>> opportunities to statically bind methods and perform other optimization > >>> tricks. Frankly, though, that’s just the cost of doing business. If you > >>> want to select a type dynamically, you’re going to lose the ability to > >>> aggressively optimize calls to the resulting instance. > >> > >> > >> I’d love to hear everyone’s thoughts on this! > >> > >> Best, > >> Riley Testut > >> _______________________________________________ > >> swift-evolution mailing list > >> [email protected] <mailto:[email protected]> > >> https://lists.swift.org/mailman/listinfo/swift-evolution > >> <https://lists.swift.org/mailman/listinfo/swift-evolution> > > > > Was any proposal for this ever written up? It would be really useful to > > have, and it appeared to have the support of several Apple staff members. > > > > Charles > > > _______________________________________________ > swift-evolution mailing list > [email protected] <mailto:[email protected]> > https://lists.swift.org/mailman/listinfo/swift-evolution > <https://lists.swift.org/mailman/listinfo/swift-evolution> > > _______________________________________________ > swift-evolution mailing list > [email protected] > https://lists.swift.org/mailman/listinfo/swift-evolution
_______________________________________________ swift-evolution mailing list [email protected] https://lists.swift.org/mailman/listinfo/swift-evolution
