A
Anders Borum
Hello,
(this question has been on my mind for some time now, so I'm just trying to
describe the problem the best I can and hopefully get the discussion
started.)
I'm looking for suggestions, feedback and advice regarding naming schemes in
public APIs where collissions between business objects (BOs) and types in
the BCL are frequent. I'm working on a API (for a CMS) that provides all the
well-known tiers (data, repository etc.), including a few UI tiers, that
extend types in ASP.NET (e.g. Page, MasterPage, UserControl).
As far as I'm concerned, recommendations and best practices suggest naming
business objects (or entities in general) according to their primary
function or usage (e.g. User, Role, Page). When APIs that co-exist in the
same domain, there is a desire to use the same name for an entity. If the
developer wants to use these APIs at the same time, he is forced to either
fully qualify all type references (which is bloated and unreadable) or alias
namespaces (also leads to less readable code).
After much thinking back and forth, this situation lead me (with much
resistance) to prefix my public business objects with "Cms" (look at
SharePoint, they went with "SP" are prefix for all public types). I'm
uncertain, whether this is the right decision because it feels both right,
so to speak;
Easy as in "it's easy to distinguish objects in the CMS API from similar
types in the BCL" and wrong as in "prefixing feels bloated and less clean".
Here are a few examples from two assemblies in the API.
[SphereWorks.Cms.Data].Page (reside in seperate assembly)
[SphereWorks.Cms.Publishing.Model].CmsPage (reside in seperate assembly,
describes a hierarchical node in a navigable tree)
[SphereWorks.Cms.Data].User
[SphereWorks.Cms.Publishing.Model].CmsUser
and in the UI department:
[SphereWorks.Cms.Web.UI].CmsWebPage (subclasses System.Web.UI.Page,
represents a templated control)
...
As you can see from above, the term "Page" perfectly describes an entity or
business object in each domain, yet they share the same name. A developer is
typically going to work with several similar types at the same time;
// override method in CmsWebPage (subclasses System.Web.UI.Page)
protected override void OnLoad(EventArgs e)
{
CmsHttpContext context = CmsHttpContext.Current;
CmsPage page = context.State.Page;
Page template = this.Page;
new ControlLoader(context).Load(page, template);
}
using namespace aliasing, the following scenario is possible:
// override method in CmsWebPage (subclasses System.Web.UI.Page)
protected override void OnLoad(EventArgs e)
{
Model.HttpContext context = Model.HttpContext.Current;
Model.Page page = context.State.Page;
Page template = this.Page;
new ControlLoader(context).Load(page, template);
}
Highest priority should be "look and feel" of the API to the developer; it
feels painful to force the developer to alias namespaces each time they want
to interact with the API because of collissions.
(Now that I'm feature complete, I'm refactoring the entire API for unit
testing and I guess that the introduction of "I" (as in IUser, IPage,
IContext etc.) is going to let the developer work against the interfaces
instead of the concrete business objects.
As mentioned before, the SharePoint team decided to go with the "SP" prefix,
which at first seemed unnatural, but with years of experience from this API
(unfortunately ..), it seems quite natural and it also makes it easy to
share info with other developers ("just get the SPWeb and .." or "yes, the
SPFile object supports ..").
(thanks in advance)
With regards
Anders Borum / SphereWorks
Microsoft Certified Professional (.NET MCP)
(this question has been on my mind for some time now, so I'm just trying to
describe the problem the best I can and hopefully get the discussion
started.)
I'm looking for suggestions, feedback and advice regarding naming schemes in
public APIs where collissions between business objects (BOs) and types in
the BCL are frequent. I'm working on a API (for a CMS) that provides all the
well-known tiers (data, repository etc.), including a few UI tiers, that
extend types in ASP.NET (e.g. Page, MasterPage, UserControl).
As far as I'm concerned, recommendations and best practices suggest naming
business objects (or entities in general) according to their primary
function or usage (e.g. User, Role, Page). When APIs that co-exist in the
same domain, there is a desire to use the same name for an entity. If the
developer wants to use these APIs at the same time, he is forced to either
fully qualify all type references (which is bloated and unreadable) or alias
namespaces (also leads to less readable code).
After much thinking back and forth, this situation lead me (with much
resistance) to prefix my public business objects with "Cms" (look at
SharePoint, they went with "SP" are prefix for all public types). I'm
uncertain, whether this is the right decision because it feels both right,
so to speak;
Easy as in "it's easy to distinguish objects in the CMS API from similar
types in the BCL" and wrong as in "prefixing feels bloated and less clean".
Here are a few examples from two assemblies in the API.
[SphereWorks.Cms.Data].Page (reside in seperate assembly)
[SphereWorks.Cms.Publishing.Model].CmsPage (reside in seperate assembly,
describes a hierarchical node in a navigable tree)
[SphereWorks.Cms.Data].User
[SphereWorks.Cms.Publishing.Model].CmsUser
and in the UI department:
[SphereWorks.Cms.Web.UI].CmsWebPage (subclasses System.Web.UI.Page,
represents a templated control)
...
As you can see from above, the term "Page" perfectly describes an entity or
business object in each domain, yet they share the same name. A developer is
typically going to work with several similar types at the same time;
// override method in CmsWebPage (subclasses System.Web.UI.Page)
protected override void OnLoad(EventArgs e)
{
CmsHttpContext context = CmsHttpContext.Current;
CmsPage page = context.State.Page;
Page template = this.Page;
new ControlLoader(context).Load(page, template);
}
using namespace aliasing, the following scenario is possible:
// override method in CmsWebPage (subclasses System.Web.UI.Page)
protected override void OnLoad(EventArgs e)
{
Model.HttpContext context = Model.HttpContext.Current;
Model.Page page = context.State.Page;
Page template = this.Page;
new ControlLoader(context).Load(page, template);
}
Highest priority should be "look and feel" of the API to the developer; it
feels painful to force the developer to alias namespaces each time they want
to interact with the API because of collissions.
(Now that I'm feature complete, I'm refactoring the entire API for unit
testing and I guess that the introduction of "I" (as in IUser, IPage,
IContext etc.) is going to let the developer work against the interfaces
instead of the concrete business objects.
As mentioned before, the SharePoint team decided to go with the "SP" prefix,
which at first seemed unnatural, but with years of experience from this API
(unfortunately ..), it seems quite natural and it also makes it easy to
share info with other developers ("just get the SPWeb and .." or "yes, the
SPFile object supports ..").
(thanks in advance)
With regards
Anders Borum / SphereWorks
Microsoft Certified Professional (.NET MCP)