Content by Category
.NET 1.x
.NET 2.0
.NET 3.0
.NET 3.5
.NET 4.0
.NET 4.5
.NET Assemblies
.NET Framework
.NET Getting Started
Accessibility
ADO.NET
Advertorials
Agile Development
AJAX
Amazon Web Services
Analysis Services
Android
Architecture
Arduino
ASP .NET Web API
ASP.NET
ASP.NET MVC
ASP.NET WebForms
Azure
B2B (Business Integration)
BDD
Big Data
Bing
BizTalk
Book Excerpts
Build and Deploy
Business Intelligence
C#
C++
ClickOnce
Cloud Computing
Code Contracts
CODE Framework Info - non Technical
CODE on the Road!
COM+
Community
Conferences
Continuous Integration
Crystal Reports
CSLA.NET
CSS
Data
Debugger
Design Patterns
Development Process
Display Technologies
Distributed Computing
Document Database
DotNetNuke
DSL
Dynamic Languages
Dynamic Programming
Editorials
Enterprise Services ("COM+")
Entity Framework
Events
Expression Blend
F#
Fox to Fox
Frameworks
Functional Programming
Git
Graphics
HTML 5
Internet Explorer 8.0
Interviews
IOS
iPhone
Iron Ruby
Java
Java Script
JavaScript
jQuery
JSON
Lightswitch
LINQ
Linux
LUA
Mac OS X
MDX
Messaging
Metro
Microsoft Application Blocks
Microsoft Business Rules Framework
Microsoft Dynamics
Microsoft Expression
Microsoft Office
Mobile Development
Mobile PC
Mono
MsBuild
MVVM
MySQL
Network
NHibernate
node.js
NOSQL
Nuget
Object Oriented Development
Objective C
Odata
OLAP
Open Source
Opinion
Opinions
Oracle
ORM
Other Languages
Parallel Programming
Patterns
PHP
Podcasts
Post Mortem
PowerPoint
Print/Output
Prism
Product News
Product Reviews
Project Management
Prolog
Python
Q&A
Rails
Rake
Razor
Reporting Services
REST
RIA Services
Ruby
Ruby on Rails
Scheme
Search
Security
Services
SharePoint
SignalR
Silverlight
SOA
Social Networks
Software & Law
Software Business
Source Control
Speech-Enabled Applications
SQL Server
SQL Server 2000
SQL Server 2005
SQL Server 2008
SQL Server 2012
SQL Server CE/AnyWhere/Mobile/Compact
SSIS
Subversion
Sync Framework
Tablet PC
TDD
Team System
Techniques
Testing and Quality Control
TFS
Tips
TypeScript
UI Design
UML
User Groups
VB Script
VB.NET
Version Control
VFP and .NET
VFP and SQL Server
Virtual Earth
Vista
Visual Basic
Visual Basic 6 (and older)
Visual FoxPro
Visual Studio .NET
Visual Studio 11
Visual Studio 2005
Visual Studio 2008
Visual Studio 2010
Visual Studio 2011
Visual Studio 2012
Visual Studio Tools for Office
VSX
WCF
Web Development (general)
Web Services
WebMatrix
WF
Whitepapers
Windows 7
Windows 8
Windows Azure
Windows Live
Windows Phone 7
Windows Phone SDK
Windows Server
Windows Vista
WinForms
WinRT
Workflow
WPF
XAML
Xiine Documentation
XML
XNA
XSLT



Component One


rssbus
 


Component One

Reader rating:
Article source: CoDe (2002 - May/June)


Article Pages: < Previous - 1 2 3 4  5 


.NET Interface-based Programming (Cont.)

Interface Factoring and Design

Syntax aside, how would you go about designing interfaces? How would you know which methods to allocate to which interface? How many members should each interface have? Answering these questions has little to do with .NET and a lot to do with abstract component-oriented analysis and design. An in-depth discussion of decomposing a system into components and discovering interface methods and properties is beyond the scope of this article. Nonetheless, here is some advice to guide you in your interface design effort.

An interface is a grouping of logically related methods and properties. What constitutes "logically related" is usually domain specific. You can think of interfaces as different facets of the same entity. Once you have identified (after requirements analysis) all the operations and properties the entity supports, you need to allocate them to interfaces. This is called interface factoring. When factoring an interface, always think in terms of reusable elements. Given that the interface is the basic unit of reuse in a component-oriented application, would this particular interface factoring yield interfaces that could be reused by other entities in the system? What facets of the entity could be logically factored out and used by other entities? An example would go a long way to demystify interface factoring. Suppose you are trying to model a dog. The requirements are that a dog be able to bark and fetch and have a veterinarian clinic registration number as well as a property for having received shots. You could define the IDog interface and have different kinds of dogs, such as poodle and German shepherd implement the IDog interface:

public interface IDog
{
  void  Fetch();
  void  Bark();
  ulong VetClinicNumber{ get; set; }
  bool  HasShots{ get; set; }
}
public class Poodle : IDog
{...}
public class GermanShepherd : IDog
{...}  

However, such a composition of the IDog interface is not well factored. The reason is that even though all of the interface members are things a dog should support, Fetch and Bark are more logically related to each other than to VetClinicNumber and HasShots. Fetch() and Bark() are one facet of the dog as a living active entity, while VetClinicNumber and HasShots are a different facet of the dog?a facet that relates to it as a record of a pet in a veterinarian clinic. A better approach is to factor out the VetClinicNumber and HasShots properties into a separate interface called IPet:

public interface IPet
{
  ulong VetClinicNumber{ get; set; }
  bool  HasShots{ get; set; }
}
public interface IDog
{
  void  Fetch();
  void  Bark();

Because the pet facet is independent of the canine facet, you could have other entities (such as cats) reuse the IPet interface and support it:

public interface IPet
{
  ulong VetClinicNumber{ get; set; }
  bool  HasShots{ get; set; }
}
public interface IDog
{
  void  Fetch();
  void  Bark();
}
public interface ICat
{
  void  Purr();
  void  CatchMouse();
}

public class Poodle : IDog,IPet
{...}
public class Siamese  : ICat, IPet
{...}

This enables you to decouple the clinic management aspect of the application from the actual pet types (be it dogs or cats). Factoring out operations and properties into separate interfaces is usually done when there is a weak logical relation between methods. However, sometimes, identical operations are found in several unrelated interfaces, and these operations are logically related to their respective interfaces. For example, both cats and dogs need to shed fur and lactate their offspring. Logically, shedding is just as much a dog operation as barking, and shedding is just as much a cat operation as purring. In such cases, you can factor interfaces into hierarchy of interfaces instead of separate interfaces:

public interface IMammal
{
  void ShedFur();
  void Lactate();
}
public interface IDog : IMammal
{
  void  Fetch();
  void  Bark();
}
public interface ICat : IMammal
{
  void  Purr();
  void  CatchMouse();
}

Interface Factoring Metrics

As you can see, proper interface factoring results in more specialized, loosely coupled, fine-tuned and reusable interfaces and, subsequently, systems. In general, interface factoring results in interfaces with fewer members. However, when designing a system, you need to balance out two counter forces: if you have too many granular interfaces, the overall cost of interacting with all these interfaces will be prohibiting. On the other hand, if you have only a few complex, poorly factored interfaces, the cost of interacting with these interfaces will be prohibiting. Because these interface-factoring issues are independent of the component technology used, I can draw from my own and others' experiences of factoring and architecting large-scale COM applications and share a few rules of thumb and metrics I have collected about interface factoring.

An interface with just one member is possible, but is it something to avoid. Because an interface is a facet of an entity, that facet must be pretty dull if you can express it with just one method or property. Examine that single method: is it using too many parameters? Is it too coarse and would it be more useful if factored into several methods? Should you factor this method or property into an already existing interface?

The optimal number of interface members (in my opinion and experience) is a range, between three and five, which means that this is the range you should aim toward. If you design an interface with more members, say six to nine members, you are still doing relatively well, but try and look at the members to see which of them can be consolidated, since it is quite possible to over-factor methods and properties. If you have an interface with 12 or more methods, you should definitely find ways of factoring the members into either separate interfaces or a hierarchy of interfaces. Your coding standards should set some upper limit of interface members that should never be exceeded regardless of the circumstances. A possible upper number is 20.

Another rule of thumb is to design in a useful ratio of methods, properties and events as interface members. Interfaces allow clients to invoke abstract operations, without caring about actual implementation details. Properties are known as just-enough-encapsulation. It is much better to expose a member variable as a property than to give direct access to it because then you can encapsulate the business logic of setting and reading that variable value in the object, instead of spreading it all over the clients. A better approach would be not to bother clients with properties at all. Clients should invoke methods and let the object worry about how to manage its state.

As a result, interfaces should have more methods than properties, as a ratio of at least 2:1. The one exception is interfaces that do nothing except define properties. Such interfaces should have properties only and no methods. I don't think that defining events as interface members is a good idea, and you should avoid it as much as possible. Leave it up to the object to decide if it needs an event member variable or not.

Juval Lowy

&


Interfaces and Web Services

Even though the Web Services standard supports defining interfaces (called 'ports' in the standard), by default, Visual Studio.NET native web services support is method based. You can work around this limitation and roll a simple solution that will allow you to expose and consume interface-based web services using Visual Studio.NET.

For more information, see my article"Develop Interface-Based .NET Web Services", Visual Studio Magazine, October 2001



Article Pages: < Previous - 1 2 3 4  5 

Page 1: .NET Interface-based Programming
Page 2: Defining and Using Interfaces
Page 3: Separation of Interface from Implementation
Page 4: Interface Methods Collusion
Page 5: Interface Factoring and Design

How would you rate the quality of this article?
1 2 3 4 5
Poor      Outstanding

Tell us why you rated the content this way. (optional)

Average rating:
4.6 out of 5

5 people have rated this article.

Hacker Halted

      Component One

 

Learn Now