We all know names are important. Probably the most important names are those of projects themselves. Ubiquitous names clearly define a projects’ scope, requirements and domain.
Ubiquitous language
By using the model-based language pervasively and not being satisfied until it flows, we approach a model that is complete and comprehensible, made up of simple elements that combine to express complex ideas.
…
Domain experts should object to terms or structures that are awkward or inadequate to convey domain understanding; developers should watch for ambiguity or inconsistency that will trip up design.
– Eric Evans, author of Domain-Driven Design: Tackling Complexity in the Heart of Software (link)
Choosing a project name
The name of a project should describe the subject that all of repositories it will contain will handle. As such, the it is important to determine the scope of the project so it may be accurately named. Some subjects are broader than others, others are names of domains.
There are two types of projects, those that:
- handle a subject, and those that
- handle a business domain
A project which handles a subject usually has a small domain and is usually a ‘provider’ project for projects handling a business domain. Examples of subject projects are:
- Account
- Ticket
Business domain projects are of a much broader scope. They usually consume ‘provider’ projects. Examples of business domain projects are:
- purchasing
- TicketMaster
A name of a project is normally either a subject (account / ticket / etc.) or a literal name (Purchasing / TicketMaster / etc.)
Choosing a repository name
A repository should always be fulfilling a single responsibility. Taking some of the above project names as examples, let us enrich them now with some repositories.
The project “Account” is a great example. Having this subject as the broad scope project name enables to usage of contained scope repository names, allowing the project to be worked out with multiple independent applications. Check out example project “Account” repository names below.
Example repositories:
- authentication
- symfony-api-authentication-bundle
- symfony-authentication-plugin-bundle
All these names bring something that ‘extends’ the project “Account”. Authentication
sounds like a service that only
authenticates a user. The name symfony-api-authentication-bundle
sounds like a module which is usable in a Symfony
API (or ApiPlatform) project to interface with the authentication application.
If we look at the more generically named project “Purchasing”, we would maybe have the repositories below inside of that project.
Example Purchasing project dependency graph:
- purchasing/website
- Depends on:
- purchasing/api
- Requires:
- account/symfony-authentication-plugin-bundle
- Depends on:
- purchasing/api
- Depends on:
- account/authentication
- Requires:
- account/symfony-api-authentication-bundle
- Depends on:
With this example we can clearly see that Purchasing is a consumer project. It consumes other projects. In this
structure we can see that the website application for Purchasing depends on the purchasing/api
application but it itself
uses the standardized account/symfony-authentication-plugin-bundle
to provide website users a way to login / register / do other account
actions.
With the website depending on the api application, there is a clear vision of separation of concerns. We can also see
that it is the purchasing/api
which has the dependency on account/authentication
, so it is has the need to handle the
requests coming in from the websites. To facilitate these it requires the use of the
account/symfony-api-authentication-bundle
. This service provides a standardized, versioned, service for other
Symfony or ApiPlatform projects to use
Helper projects?
There are projects that start out small and grow in scope over time until they no longer accurately reflect their topics. This is usually the case when an IT department, starting small, starts to develop their own tooling. Projects might get names such as:
- tools
- utils
- core
- shared
All of the above names do not tell you anything about the subject of the code they contain. Usually the repositories contained within these projects are similarly vague. Such names should thus always be avoided. If internal tooling is necessary and is thus developed, there should be a project dedicated to such tooling and each tool should have a properly named repository.
Avoid, remove or refactor generic project (or repository) names.