Naming Conventions between Software Layers
I used to separate class naming conventions for each kind of software layer like you're asking about. However in the .NET world upon realizing each layer is it's own assembly, and assemblies are often replaceable with assemblies implementing same interface/s, I found the namespace to be the most important/effective change, and dropped class-specific prefixes and suffixes, for the most part.
For example, I used to have Customer
(business) and CustomerDAL
(data access layer)
.. and that has often changed in my recent projects to, respectively ...
Com.Example.ProjectName.Business.Customer
and Com.Example.ProjectName.Data.Customer
with an ICustomer
interface being used between them instead of directly accessing any specific class in the target project.
Class Naming Importance is Changed by Low Cohesion
Usually, by implementing a class suffix or prefix you're trying to prevent against naming conflicts between tightly coupled assemblies.
However it's usually recommended to have loosely coupled assemblies by way of interfaces; a side effect is you don't use the concrete class name directly anymore. Otherwise by using tightly-coupled assemblies you might as well combine them into one assembly because they rely on one another directly and the benefit of separate assemblies is diminished.
Sometimes my software takes a more descriptive approach like Customer and CustomerData classes, and I realize this is using a suffix, but the intention is for natural flow and not to prevent against naming conflicts because my interface sits between them regardless.
In a nutshell, low cohesion renders the question moot of what classes should/could/would be named in any layer of the project relative to one another. And because you already have separate assemblies for business and data responsibilities, you must implicitly want low cohesion to be present. So my answer in context of application design is no class suffix or prefix is objectively better according to the concept of the question.
C# Code Example
For the sake of a useful code example, I'm including the following C# skeleton to show the class naming policy I gravitate toward (or lack of policy might be more accurate).
Note: This example is incomplete in some ways but shows the concept of how class naming doesn't matter between assemblies (even if it's the same class name) because they are separated using interfaces.
Business.dll - Business layer assembly
Reference Shared.dll assembly.
namespace Com.Examle.MyProject.Business {
using Com.Example.MyProject.Shared; // for ICustomer
class Customer {
// Reference obtained to an ICustomer implementation (not shown).
// Composition of the data customer, just for illustration purposes
ICustomer _cust;
// From business, a data access usage example:
public void GetData() {
_cust.SaveToDataSource();
}
}
}
Business is using ICustomer instead of being hard-wired to the Data.dll assembly.
Shared.dll - Shared assembly - Common types are referenced into both business and data assemblies.
// This is the only required link between business and data assemblies.
// Business is shielded from Data concrete class names and vice-versa.
namespace Com.Example.MyProject.Shared {
public interface ICustomer {
void SaveToDataSource();
}
}
Data.dll - Data access layer
Reference Shared.dll assembly.
namespace Com.Example.MyProject.Data {
using Com.Example.MyProject.Shared; // for ICustomer
class Customer : ICustomer { // implement ICustomer - other assemblies can too
public void SaveToDataSource() {
// logic to save data to the data source
}
}
}