Namespace: from the perspective of dependency and the artifact of a project

Prelude

It happened when I was thinking where to put a constant property of the default debug log level in my iOS project. The project contains a host app and an extension. A class, let’s say, AppStatusmanages the information about the application. Meanwhile, the information comes from distinct sources. They can be from files, user defaults, keychains, custom classes of caches … etc; therefore AppStatus by itself encloses quite a few dependencies.

Some pieces of the information need to be accessible by the extension, which means the extension doesn’t need ALL of the information. Furthermore, I didn’t want to use AppStatus directly in the extension. Doing so introduces dependencies related to the pieces of information that the extension doesn’t need at all.

To deal with the problem, I started thinking about how I could organize the constituents of the information. Sure enough, I also want that the extension gets the portion of the information it needs with minimal dependencies.

Trials

In the beginning, I thought about organizing the information by aggregating the constituents into a single namespace App. For instance, the namespace App may contain:

  • App.Configuration
  • App.Property
  • App.Constant

However, the constituents in the namespace have to be compiled as a whole. It’s not reducing any dependency for those who need to use just a portion of App. Moreover, it could make the namespace containing too many things at once, which potentially undermines the maintainability.

One may reduce the dependency for, in this case, the extension using namespaces. One possible way is to declare an empty class or struct with App to hold the namespace and separate the constituents into distinct files. The host app and the extension can then pick the files they need and add them to their own target. Yet it’s essentially identical with defining the constituents separately as independent components. I asked myself: “Is App.Constant inherently better than AppConstant?” My answer was “No.”

It came into my mind that the namespace Appmight finally become too big, with the project’s life cycle moving forward. The word App encloses ALMOST EVERYTHING. After all, the project, by itself, is just an app. The developer, who lately modifies the source code, may deliberately put things into the namespace.

On the other hand, I may abstract the app’s configuration and constants and independent components; therefore the whole thing may go with AppConfiguration, AppConstant … and so on so forth. Each of them manages just a small set of data, meanwhile keeping their size small in contrast to the namespace way.

My decision: in the context of the project

I finally decided to go with the App prefix. I made the decision by considering the artifact of my project: It’s an app.

Sometimes you may encounter something similar when using a framework or library: Component.Error. It’s quite reasonable that the error is in the namespace of Component in case of frameworks or libraries: Such error objects are part of the framework or the library (Also, the error will be little use if it’s NOT part of the framework or library). Also, Error is too easy to be put in the place of name collisions. There are all sorts of Error everywhere, not to mention the great one: Swift.Error.

Unlike libraries or frameworks. My app was designed and implemented to run as an app. It is not intended to be included or imported to other projects as libraries or frameworks are. I prefer to keep the components manageable and maintainable.

Conclusion

Namespaces are somewhat “Swiftier” (Swift has removed lots of prefixes from namings), and it seems that it becomes more common in Swift frameworks and libraries. But prefixes may still be valuable if the abstractions of your components are relatively independent and you want to keep the components small and simple. However, most of the time, it’s just a matter of personal preference.

Cheers!

--

--