Interface Definition and Factoring Design Considerations
Interfaces can be useful tools when used properly. But when used improperly, they can be cumbersome, or even become hindrances to efficient programming. The following section will provide recommendations for the best design and use of interfaces.
Caution An interface once defined and accepted must remain invariant, to protect applications written to use it. Do not change interfaces once you have published them.
Interface Invariance
When you create an interface, you are creating a definition that can never change after the interface definition has been released. This interface invariance is an important principle of component design, because it protects existing systems that have been written to use the interface.
When an interface is clearly in need of enhancement, a new interface should be created. This interface might be named by appending a "2" onto the original interface name, to show its relationship to the existing interface.
Generating new interfaces too frequently can bulk up your components with unused interface implementations. Well-designed interfaces tend to be small and independent of each other, reducing the potential for performance problems.
Factoring Interfaces
The process of determining what properties and methods belong on an interface is called factoring.
In general, you should group a few closely related functions in an interface. Too many functions make the interface unwieldy, while dividing the parts of a feature too finely results in extra overhead and diminished ease of use. For example, the following code calls methods on two different interfaces of the BusinessAccount class:
' Visual Basic
Public Sub MergeAccounts (ByVal act1 As _
BusinessAccount, ByVal act2 As BusinessAccount)
Dim pac As IAccount = act1
Dim company As ICustomer = act1
act1.Merge(act2)
company.ChangeAddress()
pac.PostInterest
End Sub
// C#
public void MergeAccounts(BusinessAccount account1,
BusinessAccount account2)
{
IAccount account = account1;
ICustomer customer = account1;
account1.Merge(account2);
customer.ChangeAddress();
account.PostInterest();
}
It is much harder to go wrong in designing interfaces than in creating large inheritance trees. If you start small, you can have parts of a system running relatively quickly. The ability to evolve the system by adding interfaces allows you to gain the advantages object-oriented programming was intended to provide.
Note The capital "I" in front of interface names is a convention. It is not strictly necessary to follow this convention. However, it provides an easy way to distinguish between interfaces and the classes that implement them.