POP Implementations with multiple files

I am looking at Protocol Oriented Programming with Swift 3.0. I have found that POP offers a great deal of programming flexibility. One area that I have struggled with is the ability to have an implementation (think protocols and extensions on those protocols) where code is spread across more than one file. The issue is around encapsulation.


I want to be free to share details between files that are part of the POP implementation but not expose those details to the outside world. One solution I have looked at is to use Modules. This does work but the level of effort to create and maintain seems high to achieve the access control I am looking for.


Fileprivate was a solution I used to achieve code separation but all code had to be placed in the same file. I attempted to submit a a request in Swift Evolution for a way to have a group access, something like directoryprivate but that set off a barrage of sniper fire that made me an instant casualty. Yes, you can "-1 me" on that experience.


Is there a preferred way to obtain encapsulation across multiple files in Swift without having to resort to creating modules each time?


Thanks in advance,


- Jim

Accepted Answer

I don’t think there’s a Silver Bullet™ solution for you here; it sounds like you are aware of your current options and you just have to decide on which of them best suits your needs.

You might want to pop over to swift-evolution, where there is currently much debate about the future of access control and Swift submodules, both of which might give you better options in the future.

Share and Enjoy

Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"

It may have been cross-fire more than sniper fire. This subject has been discussed a lot over the past couple of years, and if you walked into the discussion after a big furor had just died down, likely no one was happy to see you. 🙂


One approach that I use is to leverage framework boundaries for access control, but only create a single framework. That is, I shove a bunch of unrelated functionality into one framework, and don't worry much about access control within the framework.


This works because I control all of the code in the framework directly. I could violate intended access boundaries within the framework, but I won't because I won't. Then, no one else can mess things up because they have to use the framework from the "outside" with only public access.

I always liked protocols. I kind of worry that people will get fanatical with these things though. I'd like to see a large "everything is a protocol" project that doesn't break up your code into meaningless chunks of do-do.


>I want to be free to share details between files that are part of the POP implementation but not expose those details to the outside world.


Subclassing can achieve this...though that maybe something you are trying to avoid. 😊

Thank you Quinn,


i have been watching the action there. I can understand the concerns. I am hopeful that something good comes out of it.

Thanks Quincey,

I am sue that you are correct about the direction of the fire. Will learn to be more cautious when sticking my head up ...;-).


I have taken the approach you are describing. particular when it comes to creating snap-on extensions. I want some import statement at the top that makes it clear you are bolting on something from the utility belt and where it calls home. I also agree with you about keeping things encapsulated. I have made an attempt to use module maps to create such a framework as you have described. I have not had consistent luck with getting the behavior that I think I should. Module map documentation has not been my kindest friend. Seems like it only makes sense after you have done it ;-). Would you be up for some discussions about what I am attempting to do and look at the results I am getting?


I started a separate thread here.


Thanks - Jim

Thanks *****,


I remember first learning about object-oriented programming (this will show my age) when someone was teaching me Ada at Lockheed Aerospace. :-) Of course the promised Nirvana was polymorphism, encapsulation, and inheritance. They would use the example of the shape class then go onand describe a star class, circle class, and a rectangle class. Then the magic of "..what if they all want to print?" You would see the example of a base class that has a default print function. And of course the star, circle, and rectangle with all override that print statement. Polymorphism(through base class) allows you to mix-and-match all of those types into some sort of collection that only knows that they all have a print function.


The downside of course is "I want the circle, the star, the rectangle, and my Word document to print."


You see the rub. I just want to bolt on a print capability. I don't want have anything else binding my Word doc to a rectangle or anything else.


Protocols (or in C#: interfaces) give you the handle that allows the polymeric side, taking the place of using the base class as the handle. Extensions to protocols (POP) in Swift actually give an implementation (real code) for the print. This last part, in my view, is the magic of it all.


I think the order of battle should be:


Decide if you want a reference type (class based) or a value type (structure based) object to do your work. Things like needing to work with objc or being able to pass ownership of an object onto something else will make you want to look at classes (reference type). If you are going to use classes then you have all of the OOPS stuff as one set of tools in your tool box. The beauty of of POP is it works on both value and reference based objects. It really does not care too much. Not identical to subclasses but another great set of tools.


Just my thoughts - still learning ...

I think I would object to linking polymorphism to inheritance (which you kind of implied but didn't exactly do, so maybe you didn't mean that). Obj-C polymorphism is about the ability to send a message to an object without any particular requirement on the type of the object. The standard Print menu item, for example, relies on the polymorphism of the "print:" IBAction selector to enable printing for the circle, the star, the rectangle and the Word document. In fact, in Obj-C, polymorphism boils down to "run-time dispatch". Swift tends to de-emphasize actual polymorphism by focusing on slightly polymorphic-ish features such as protocols and inheritance, which have significant compile-time limits when compared with Obj-C's free-for-all.


However, what I really want to say is that in Swift, protocols and inheritance are not "just" alternative tools. There's a whole series of difficulties in using inheritance (fragile base classes, multiple inheritance, etc) that have led to a reaction against the desirability of inheritance, at least for some people. To some degree, Swift protocols are intended as a replacement for the inheritance strategy.


Indeed, there is a significant minority in the Swift developer community that wants to throw inheritance out of the language (solving those problems, and also making the rest of the language simpler as a result). So far, that's not really a practical choice, yet there are signs. For example, defaults methods in protocol extensions are a little bit like inheritance from a base class, but not quite, and actually don't interoperate well with class hierarchies.


If these issues interest you, you should probably start following the discussion threads over on swift.org.

Bolting on functionality in some situations is useful and fine I think. But I just think some people hear one presentation and start getting fanatical about these things.


If you are using base classes that are meant to be generic and jumping through the family tree is such a chore to make sense of it all, I'm skeptical that breaking it up into a series of protocols to achieve the same thing would be more desirable. In a very simple case maybe (but then sentence one in this paragraph is irrelevant).

Functionality at the *base* level in many situations are useful to those inheriting only (whether that be through a class or through a protocol). Often that functionality can be essentially meaningless on its own because there simply is not enough context. Hence my previous comment…if everything is a protocol you will break up your code into meaningless chunks of do-do.


If someone really gets out of control with protocols, you may need to inherit from several protocols to make a given protocol have any *real* meaning at all (is that all that different from a base class?). And in that situation you have simply restructured how something is done but it is unlikely that you really made anything better or worse for developers. I would argue that you (not *you* but you know what I mean) are making things worse because you are imposing unnecessary burdens on the app development community by telling them they need to relearn how to write an app every few years.


On the flip side, in designing a series of base classes, you may abstract away some functionality that potentially another class could use and you didn't anticipate it, and there maybe some *duplicate* code. But really, how big of a problem is this? Should there be no Private API either, because sometimes I have to rewrite stuff that I wouldn't if I had access to a private class.


Have you ever thought when making an app that all your problems would be solved if UIView was declared as a protocol instead of a class?


I use protocols in ObjC all the time, but I just want to point out that people shouldn't get carried away. There are plenty of things these brilliant folks are doing and can do to make all our lives better but this to me is not really one of them.

POP Implementations with multiple files
 
 
Q