Understanding Interface-Based Programming - Designing and Factoring Interfaces
(Page 2 of 5 )
Syntax aside, how do you go about designing interfaces? How do 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 how to decompose a system into components and how to discover interface methods and properties is beyond the scope of this book. Nonetheless, this section offers a few pieces of advice to guide you in your interface-design effort.
Interface Factoring
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 a requirements analysis) all the operations and properties the entity supports, you need to allocate them to interfaces. This is called interface factoring. When you factor an interface, always think in terms of reusable elements. In a component-oriented application, the basic unit of reuse is the interface. Would this particular interface factoring yield interfaces that other entities in the system can reuse? What facets of the entity can logically be factored out and used by other entities?
Suppose you wish to model a dog. The requirements are that the dog be able to bark and fetch and that it have a veterinary clinic registration number and a property for having received shots. You can define theIDoginterface and have different kinds of dogs, such asPoodle andGermanShepherd, implement theIDog interface:
public interface IDog
{
void Fetch();
void Bark();
long VetClinicNumber{get;set;}
bool HasShots{get;set;}
}
public class Poodle : IDog
{...}
public class GermanShepherd : IDog
{...}
However, such a composition of theIDoginterface isn’t well-factored. Even though all the interface members are things a dog should support,FetchandBarkare more logically related to each other than toVetClinicNumberandHasShots.Fetch()andBark() involve one facet of the dog, as a living, active entity, whileVetClinicNumberandHasShotsinvolve a different facet, one that relates it as a record of a pet in a veterinary clinic. A better approach is to factor out theVetClinicNumberandHasShotsproperties to a separate interface calledIPet:
public interface IPet
{
long VetClinicNumber{ get; set; }
bool HasShots{ get; set; }
}
public interface IDog
{
void Fetch();
void Bark();
}
Because the pet facet is independent of the canine facet, other entities (such as cats) can reuse theIPetinterface and support it:
public interface IPet
{
long 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 factoring, in turn, allows you to decouple the clinic-management aspect of the application from the actual pet type (be it dogs or cats). Factoring operations and properties into separate interfaces is usually done when there is a weak logical relation between methods. However, identical operations are sometimes 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 feed their offspring. Logically, shedding is just a dog operation, as is barking, and is also just a cat operation, as is purring. In such cases, you can factor the interfaces into a 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();
}
Next: Factoring Metrics >>
More .NET Articles
More By O'Reilly Media
|
This article is excerpted from chapter three of Programming .NET Components, Second Edition, written by Juval Lowy (O'Reilly, 2006; ISBN: 0596007620). Check it out today at your favorite bookstore. Buy this book now.
|
|