Suppose the following model: You want to create a client-server program.
Where, the client would make no sense without the server.
Is that a good reason to make the client a nested-type of the server?:
struct Server {
....
struct Client {
...
}
}
Also, another advantage I see, you can have so private methods in the server, that the client can access , but no one else can.
However, is this a good reason? Are there any drawbacks to this approach? Someone mentioned testability, that the client is now not testable. Not sure if that's true.
Structuring code is very subjective, personally I just do this when a type is unquestionably directly related to another.
For example if I had a type or extension with an initializer/method that allows choosing something with an enum, I will write that enum in the type to avoid having it show up in unrelated suggestions:
extension String {
enum ColorType { case foreground, background }
enum Color {
case black
case red
case green
case yellow
case blue
case magenta
case cyan
case white
case `default`
}
mutating func color(_ color: Color, _ type: ColorType = .foreground) { ... }
...
}
This makes sense because I can just use String.Color which makes it obvious what kind of Color it is and avoids colliding with other types. (You would have to name it StringColor anyway)
I probably wouldn't put the Client in the Server, because now you will have to initialise it like this: Server.Client() which to me at least feels a little weird in Swift
Client doesn't feel like a part of a Server, they're both equally important and serve no purpose without the other.
What I also started doing recently is "namespace" types by writing them in an empty enum, so MyProject.Server and MyProject.Client
This way you can have a top level protocol named Client and multiple Client implementations of the same name in different namespaces, avoiding naming conventions like "ClientProtocol"
As far as I know there shouldn't be any drawbacks. It's as if you had Client written separately, it just changes how you access the type and its initializers in your code.
I don't see how this would impact tests in any way.