NEW: Subscribe to Hacking with Swift+ and accelerate your learning! >>

Correct approach to naming of Entities and Protocols ?

Forums > Swift

Hi all,

I have a question that I’ve struggled to find a sensible answer.

A bit of history ..

When developing an application, my approach (rightly or wrongly) is to separate the logic into a Framework (SquadKit, BingoKit, WorkoutKit etc.)
The reason(s) for this are fairly straight forward ..
.. I like being able to test the logic in isolation
.. I like that it forces me to forget about the UI and any UI assumptions
.. I like that I am free to create the app using a separate UI .. depending on device (iPhone, Watch .. Apple TV .. Command Line Utility)

The problem ..

because I like the logic in a separate framework .. I have introduced a complexity in terms of access modifiers (Public, Internal, Private) for classes, structs, enums, methods, properties.

What I have most trouble with is properties (and properties of Entities in particular)
I prefer not to expose the setter to the consumer of the Framework (i.e. the UI Application)
Within a Module I would typically use the private(set) var nameOfProperty approach
.. however this isn’t an option to me in entities of a framework.

So for a framework, I would much rather return a Protocol describing the interface of an Entity
.. i.e. it’s writable properties, it’s read-only properties and it’s accessible methods

We have been encouraged down the route of naming Protocols according to a behaviour .. however,
.. for example, a Football/Soccer Team Selection framework I wouldn’t want to be passing back and forth something that conforms to ‘Player-able’, ‘Manager-able’, ‘Fixture-able’
.. I want to pass back and forth a ‘Player’, ‘Manager’, ‘Fixture’ (as the consumer would rightfully expect)

Question

So my question is this .. what should I be naming my Entity (assuming it conforms to a commonly known as Protocol) ?
Understandably, we can not have a Protocol called protocol Player and class Player

Idea 1: Use underscoring within the framework (my most likely approach)
e.g.

public protocol Player {
    public var name: String { get }
}

public class _Player: Player {
..
}

Idea 2: Don’t use protocols, but use computed properties instead (not preferred)
e.g.

public class Player {
    private var _name: String

    public var name: String {
        get {
            return _name
        }
}

Idea 3: Don’t use protocols, because you're the only consumer then trust yourself and make everything public 🤪
e.g.

public class Player {
    public var name: String
}

What do you think ?

.. is my thought-process completely wrong ?
.. is my Framework approach too much overkill ?

.. have you got ideas on this ?

   

I think if you are not creating super big and dont plan to use the modules elsewhere then it does not make much sense to spend so much time on this.

As for the protocols question I am usually just using Protocol suffix in cases like these. It may not look very pretty or smart but I believe it is better than having underscored classes.

   

Hi @nemecek-filip

Thank you for your reply.

• Yes, maybe I'm over thinking the need for Framework as Logic , but I do like the structure and discipline it gives me

• In terms of Protocol suffix .. this is something I've struggled with.
I'm not sure that would work for my development approach.
e.g.
As you suggest, the consumer would get a PlayerProtocol as opposed to a Player

framework

public protocol PlayerProtocol {
    public var name: String { get }
}

public class Player: PlayerProtocol {
..
}

consumer of framework

guard let player = squadService.players[indexpath.row] as? PlayerProtocol else { ... }
cell.titleLabel.text = player.name

As a consumer, I would expect to be interacting with a Player (not a PlayerProtocol)

I'm very grateful for your time and replying .. but this wouldn't be good for me.

   

Why not go with PlayerEntity for the framework class and Player for the protocol?

   

Hi @roosterboy,

Yeah, I had previously thought of PlayerImpl .. but it sounds more like other languages, and I'm not feeling that it's very Swift-like. It's basically having a separate name from your interface, so it could be as you suggest PlayerEntity or PlayerImpl, PlayerObj .. or even _Player (which I've seen whilst using the debugger)

I'm also going to have a look at some of Apple's open-source code and maybe see how they do it.
As with anything in coding, there's ten's of ways to do the same thing

Thank you for your reply .. I really do appriciate the discussion
(I wonder if I'd get more ideas on StackOverflow) 🤔

   

For what it's worth, I discovered protocols somewhat by accident recently while trying to figure out how to write a system for a game where combat could take place between two PCs or a PC and a a monster (both of which have nuanced profiles and behaviors that discourage using the same class for both). I went ahead and created a CombatCapable protocol that I used to define the properties and methods combatants would be expected to implement, and then set the variable types for the combatants in my CombatEventManager class to CombatCapable instead of PlayerCharacter or Monster.

As far as naming goes, I went with something that explicitly and concisely explained the purpose served by the Protocol, in a manner resembling any other class name. Looking at other protocols in common use (e.g. UITableViewDelegate...pretty much anything ending in Delegate), that seems to be the way Swift handles it as well.

   

Hacking with Swift is sponsored by Paw

SPONSORED Use Paw to build, test and describe web APIs. Paw has a lightning fast native macOS interface to compose requests, collaborate in real-time on API specs, and generate client code for your applications. You can import and export API definitions.

Discover Paw for Mac

Sponsor Hacking with Swift and reach the world's largest Swift community!

Reply to this topic…

You need to create an account or log in to reply.

All interactions here are governed by our code of conduct.

 
Unknown user

Not logged in

Log in
 

Link copied to your pasteboard.