| By Donald King | Article Rating: |
|
| May 28, 2003 12:00 AM EDT | Reads: |
9,887 |
Software reuse is the pinnacle of success in the object-oriented paradigm. Every development effort strives for it, whether it's shared components, routines, or just reuse of design ideas.
Periodically a scenario comes along where everyone wants to reuse a piece of functionality that should be designed to satisfy a part of the nonfunctional requirements of several problem domains across the enterprise. In this article, I will show you how design using interface inheritance in .NET can help you achieve this goal.
Interfaces in .NET
Interfaces in .NET are very similar to interfaces in Java in that they are a declaration of methods without implementation that, when applied to a class definition, force declaration and implementation of those methods. Unlike class inheritance where child classes take on the behavior of their parents, interface inheritance is more of a statement of expected behavior, with the definition of the behavior left up to the developers implementing the interface's methods in their own classes. To understand the concept a little better, think about a menu in a restaurant. A menu is much like an interface in that you know only a few things about the items that are listed (see Figure 1). For example, you know the name, price, and a perhaps a little about what it is supposed to be. What you do not know is how it is prepared, who is preparing it, and what's being used to accomplish the task (unless, of course, you are at a Japanese restaurant - then you get to see the whole thing!).
Interfaces provide this for other classes so that they know which methods are available from the implementing class. In VB.NET and C#, interfaces are declared simply with the interface keyword, and all methods are public by default.
Public Interface IMyInterface
Function AMethod() As String
End Interface
When a class implements this interface, it will be forced to implement the AMethod method with the same signature.
Public Class MyClass : Implements MyInterface
Public Function AMethod() As
String _Implement IMyInterface.AMethod
'Implementation here
End Function
End Class
Note: In C# it is required that the method name be the exact same as defined in the interface. In VB.NET this is not required; however, unless you have some compelling reason not to name it the same, I suggest that you always do.
Inheritance and Polymorphism
Interfaces provide inheritance through polymorphism much the same way as superclasses. As in a parent/child inheritance hierarchy, a class that implements an interface can be used any place that the interface is expected. In an inheritance hierarchy this can be done because the parent, or superclass, promises less than the child, or subclass, can provide. The child class is guaranteed to have the same public interfaces as the parent and usually more. In this sense we can say that the child class has an "is a" relationship with the parent class. The concepts of interfaces are the same but with a bit of a unique difference. Interfaces normally do not have an "is a" relationship with a class, and it certainly isn't a parent/child relationship. You can think of interfaces as being more of a means by which completely unrelated classes can be associated by a common behavior. One good example is database drivers. Database drivers need to have certain public interfaces to be able to interface with data access libraries like ADO.NET and in turn, to be interfaced with. This commonality between classes sets a sort of standard by which they all are able to interact with a system.
An Example Demanding Interfaces
A great example of using interfaces involves one that can be related to the real world, a post office. Think about how the postal system works: a set of expected properties of a piece of mail have to be present for it to work properly in the system and get delivered to its ultimate destination. For example, a piece of mail must have a destination address and must have proper postage. Without these two things, the mail will be returned to the sender, or if the sender has not provided appropriate return address information, it might go in an undeliverable pile. These types of standards are analagous to interfaces since packages may come in all shapes, sizes, weights, etc. In a software system, objects also vary in types like parcels in a postal system.
The System.Web.Mail Namespace in .NET
Now suppose that you're tasked with building a postal system in .NET for other applications to use. Fortunately, in .NET this is fairly simple using the System.Web.Mail library. This core piece of the .NET Framework provides classes for easily implementing an SMTP (Simple Mail Transport Protocol) mail system. The System.Web.Mail namespace contains two very important classes, called SmtpMail and MailMessage. These two classes alone can get you up and going with mail functionality. The MailMessage represents an e-mail-style message with properties like To, From, Subject, and Body. The SmtpMail class has a single method called Send() that takes either a MailMessage object or each individual attribute as type String. I recommend you use the MailMessage object to construct your messages so you have more encapsulated control over the message as a whole. In addition, the MailMessage object offers additional properties such as carbon copy, priority levels, and mail format. There is also a MailAttachment class, in case you need to be able to attach files to outgoing mail messages. These can be added to a MailMessage via the Attachments collection.
Handling Multiple Class Types
Now I want to show you a scenario in which multiple class types want to use a mail system like the one previously described. The scenario involves an online store needing the ability to send mail notifications to the appropriate people. The sales staff want all receipts mailed to the customer's e-mail address, the stockroom workers want to be able to notify vendors about products when they need to order more for restocking, and accounting wants to be able to receive e-mail when an invoice is received at the company. All of these systems are different and have different types to contend with.
First, you will want to build your mail system (see Listing 1). This will provide the basic functionality you need to send e-mail. Now that you have the basics of your postal system, it is time to provide a way for any type of class to be able to use it. You might be thinking that a MailMessage is the way to accomplish this. The problem is that while we want our classes to be able to use the mail functionality we've built, we don't want them to have to know anything about the System.Web.Mail library. We want to hide the details much the same way we'd hide details about relational data from a set of business objects. Instead, we provide an interface and, though this may sound strange, we'll put the responsibility for mail content back on the classes themselves. Since we have no way of knowing how each class needs to be represented in a mail message, we will leave that up to each individual class to decide. Instead we provide the standard, or interface, with which they need to comply to be sent successfully through the mail system. The next step, you guessed it, will be to define an interface that all classes wishing to use the mail system will have to implement.
The interface IMailable provides the necessary methods.
Public Interface IMailable
Function ToMessage() As String
End Interface
The ToMessage() method is used to return a String representation of how the class wants to be represented in the body of a mail message. The SendMail() method in the PostOffice class of our postal system takes an argument of type IMailable. This means that we can pass in any class that implements the IMailable interface in its place, such as the OrderItem class (see Figure 2).
The OrderItem will be forced to implement the ToMessage() method.
Public Class OrderItem : Implements IMailable
Public Function ToMessage() As
String _Implements IMailable.ToMessage
'Implementation here
End Function
End Class
The argument acts as a sort of placeholder. What the .NET Common Language Runtime will do when the code executes is dynamically resolve to the implementation of the actual class that has been passed as a value to the SendMail() method and execute it. This is how polymorphism works - by allowing the IMailable variable that has been defined in the method signature to take on any forms that implement its methods. The best part is that all of this happens automatically and does not need to be coded.
Putting It All Together
Now we can tie everything together. The included project is the Online Nut Store, which includes two different examples of departments within the organization needing to use the prebuilt post office functionality (see Figure 3). The sales department has the OrderItem class mentioned previously, and the administration department has the RestockOrder class, both of which implement the IMailable interface. When these classes are instantiated, populated, and passed into the SendMail() method of the PostOffice class, they will each be queried for their mail body content through the ToMessage() method they have been forced to implement and then will be on their merry way down the SMTP highway! Whew! Wasn't that exciting? I hope this article has given you a strong understanding of how interfaces in .NET work and how you can use them to allow for system functionality to be written once and used across the enterprise if designed properly.
Published May 28, 2003 Reads 9,887
Copyright © 2003 SYS-CON Media, Inc. — All Rights Reserved.
Syndicated stories and blog feeds, all rights reserved by the author.
More Stories By Donald King
Donald King is the founder of Webforge Software, a Web-applications development and consulting firm located in Topeka, Kansas. Don has extensive experience in object-oriented technologies and Web-based application development.
- Kindle 2 vs Nook
- Wave on Ulitzer: Confessions of a Google Wave Fanboy
- Confessions of a Ulitzer Addict
- Cloud Computing Best Practices
- IBM Hardware Chief, Intel VC Exec Arrested in Insider Trading Scam
- Tactical Cloud Computing Panel at 1st Annual GovIT Expo
- Ulitzer.com Named Exclusive "New Media" Sponsor of Cloud Computing Conference & Expo
- Infrastructure-as-a-Service Will Mature in 2010: Microsoft's David Chou
- GITEX TECHNOLOGY WEEK 2009 Exhibitor Profiles
- Windows 7 – Microsoft’s First Step to the Cloud
- Cloud Computing & Federal IT - What Does the Future Hold?
- Jill Tummler Singer, Deputy CIO of CIA, Keynotes at GovIT Expo
- Kindle 2 vs Nook
- Practical Approaches for Optimizing Website Performance
- The Difference Between Web Hosting and Cloud Computing
- Ajax in RichFaces 3.3, JSF 2 and RichFaces 4
- Contrary Opinion: Why Silverlight is Good for Adobe
- Wave on Ulitzer: Confessions of a Google Wave Fanboy
- Confessions of a Ulitzer Addict
- Cloud Computing Best Practices
- IBM Hardware Chief, Intel VC Exec Arrested in Insider Trading Scam
- Tactical Cloud Computing Panel at 1st Annual GovIT Expo
- Ulitzer.com Named Exclusive "New Media" Sponsor of Cloud Computing Conference & Expo
- WPF Controls by DevExpress
- Google Maps and ASP.NET
- Crystal Reports XI & How It Has Changed
- Converting VB6 to VB.NET, Part I
- Creating Controls for.NET Compact Framework in Visual Studio 2005
- Where Are RIA Technologies Headed in 2008?
- How to Write High-Performance C# Code
- AJAX World RIA Conference & Expo Kicks Off in New York City
- Implementing Tab Navigation with ASP.NET 2.0
- i-Technology Photo Exclusive: Bill Gates & Steve Jobs In "Nerds"
- .NET Archives: Getting Reacquainted with the Father of C#
- i-Technology Viewpoint: "SOA Sucks"
- Programmatically Posting Data to ASP .NET Web Applications




































