With .NET and the world of Extensible Markup Language (XML) Web services, we have finally reached a point where it has become not only desirable to employ distributed applications but rather simple, as well. The allure of employing Web services in your design has now become irresistible. Web service consumers can now leverage both intranet and Internet-based Web service providers. No longer does each IT department require the need to reinvent the proverbial "custom software wheel." Services can now be easily used instead of produced. However, this allure comes with some serious considerations. Not only do developers require another level of skillset to produce scalable applications, but the same goes for those supporting its infrastructure. Vendors are also getting into the services business and not just those that consider themselves "application service providers." Traditional application vendors , such as the one covered in Chapter 6, are wrapping their products around a standard Web service layer to give customers features that were previously shrink-wrapped, installed locally, or too difficult to provide.
All of this is possible because of XML Web services and the newly released .NET framework. With .NET, building truly distributed business services is as easy as adding an attribute to a method. Alas, this is the benefit and the curse. Technology departments must ready themselves for this invasion. They must be ready not only to take full advantage of this opportunity but also to prepare their infrastructures , their teams , and their perspectives. Many times, as you have seen with the likes of Visual Basic, the easier it is to build applications, the greater the tendency is to produce half-baked applications. Distributed applications are hardly the kind of application any business wants to be poorly designed, especially when the opportunity to leverage the applications services now becomes convenient . With XML Web services and the simplicities of .NET come the added responsibility of producing sound designs. This is true now more than it ever has been.
Exploiting the .NET framework in proper object-oriented fashion is only half the story here. As far as design challenges go, this is only the tip of the iceberg. With .NET, you now have to the power to design services not only from object boundaries but from machine or network boundaries, as well. That's the power that an XML Web service provides the developer. With them, object invocation can now easily cross the network, even if that network is the Internet. As mentioned above, this distributed service-based approach to application architecture brings with it entirely new challenges. Design disciplines are always needed but never so much as now. Now you must account for the fact that the objects you are creating may or may not be local or even controlled by your design. You must now account for the fact that your application design may be distributed across the Internet. Does that mean that classic OO principles are not applicable in a "service-based" world? The answer is absolutely not. However, design philosophies must be adjusted. This is another reason why I wanted to take on this book.
Before I go into what areas of the .NET framework require design forethought, let me first run down why this thing is still a positive thing overall. This "thing" I'm referring to is the new world of CLR and the melee of business-specific Web service applications that will soon follow. Aside from all of the hype and maybe even a little skepticism, .NET and XML Web services really do provide distinct advantages and not just from the perspective of your department's local code-nerd. These services finally provide us with a machine-readable contract framework. By properly leveraging the Web Services Description Language (WSDL) specification into your "distributed wrappers," you can finally allow servers to talk to one another in a standard and type-safe fashion. For smaller server-to-server applications, this is a blessing.
No longer do simple applications require expensive "eBusiness" software to manage communications. Web services can be compared with Web servers, but for machines. No longer do we need to rely on protocol-specific proprietary component models to dictate how services can be provided and consumed. Gone are the days when installing one DLL file for one application on your server trounces another's functionality. This "DLL-hell," as it has been called, truly does finally provide you the protection of long-awaited application isolation in Windows. Application deployment can be as simple as a file copy, although more complex applications may require custom installations using Microsoft Installer. Even more importantly, an update to an SML Web service code does not require shutting down the server! We can finally put down those registry editors and slowly get used to " XCOPY ing" our way to deployment bliss .
Can you really begin to provide those distributed architectures where you "design it, build it, and they will consume it?" Can you do this without bringing down your network while providing hundreds of Web services? How many Web services do you need or should you have? Can you provide business logic through Web services as you provide data through data warehousing? Can you do this without all of the proprietary protocols, firewall issues, and deployment headaches ? Can you do this in a truly object-oriented way without performance problems sometimes associated with sophisticated designs? The answer is a resounding yes, but there are some items you should be aware of. This awareness includes not only the bad elements of .NET applications (there really aren't many) but the positives, as well.
Designers must not only plan how to handle this influx and be prepared for the worst, but they must also understand its importance and take full advantage of what .NET has to offer in order to succeed. You must understand some of the benefits that will save money through simpler deployments, better support, and quicker update turnarounds. But you must also understand the responsibility that goes along with having a trustworthy and secure Web service environment for your customers and, even more importantly, for your own company. Hopefully, in the next few paragraphs I begin to answer all of these questions and provide you with the elements of .NET that you can pattern and repeat.
The .NET Framework and the World of OO
For all intents and purposes, any object-oriented pattern can be now applied to the world of .NET. This includes most of its languages (C#, VB.NET, J#, and yes, even COBOL). To obtain the benefits provided by the CLR, however, you must use one or more language compilers that target the runtime, such as VB.NET, C#, Managed C++, J#, or even one of many third-party compilers, such as an Eiffel. The .NET framework is a multilanguage execution environment; the runtime supports a wide variety of data types and language features. The language compiler you finally select will determine which features you have available. You must design your code using only those features. It's your compiler, not the runtime, that establishes the syntax your code must use and which features are drawn from the CLR. If your application must be completely usable by pieces written in other languages, your application's exported types must expose only language features that are included in the CLS. This is not to say I recommend you use only C# or VB.NET but those will be your primary choices, and you should have a relatively good reason to use other languages. That said, the CLR is one of a kind for even giving you that choice. This is something we as developers really never had, at least not at this level.
The choices have now been expanded ”platform, language, and design heuristics. Regarding design heuristics, the .NET framework is a true object-oriented platform, after all. Any .NET developer now has the option of applying OO material once targeted to the likes of languages such as Java. Fortunately, there is plenty of OO material out there to give those new to .NET an opportunity for learning the basics of object orientation. In fact, I highly recommend becoming at least slightly acquainted with OO and its principles before tackling patterns. Fortunately, patterns are not a new concept, with the "gang of four" (covered later) providing us the foundation that has been built on over the last several years . You should be able to leverage much of the material out there, even if it has been targeted for another platform or even a different language, such as Java. This is one of the niceties of object orientation and of patterns ”their general applicability.
That said, I'm not requiring that anyone have years of OO training before making use of the material in this book. In fact, I do not even require in-depth knowledge of .NET. This is especially true if you are an experienced programmer. For those programmers who have already worked with object-oriented languages before or even slightly object-oriented languages (some call them component-oriented ), you should be able to grasp the content in this book. For those already comfortable with patterns and .NET, you can skip the patterns discussion in this chapter altogether. However, I would recommend reading most of Part I if you are new to any of the following:
So if there is so much material out there on OO and patterns, why does the world need another "patterns" book? I've been asked this question countless times, so I will probably be repeating this answer throughout the following chapters, just to beat it down. With .NET and now the approaching world of XML Web services, we are on the brink of a truly unique development paradigm. Not only does .NET bring with it unique features upon which to leverage, along with its classic OO model, but it also now provides us with several new features. Primarily it now provides us with a simple XML Web services platform upon which to built standard distributed applications. As alluded to in the previous section, this power brings with it the need for design disciplines. Thus, the reason I took on this book. I want to provide those new to OO not only some .NET-friendly implementations but much more. I also want to guide those providing designs that may be taking on some of the new features of .NET; features such as Web services, XML schema generation, and custom attributes, to name a few.
Like OO, it will become very easy to abuse these new features. Most of you have already heard the horror stories of all of the badly designed object-oriented software out there ”software that looked sophisticated on a whiteboard or within a class diagram but actually crawled when executed. Learning OO is much more than grasping implementation inheritance, as those who have already chipped their teeth have found out. It is the culmination of exploiting its benefits without overindulging. Implementation inheritance is not always the answer. Said in another way, not all databases are always fully normalized when they make it to production (for those who speak using an "ERD-tongue"). Many times, an object model must go through some form of "object denormalization" to perform well. For example, this includes eliminating former associations or even breaking some inheritance trees so that they instantiate faster at runtime. Another example is to employ interface inheritance instead of implementation inheritance. Using delegation and aggregation instead of encapsulation or implementation inheritance may also be an alternative. Some OO purists may be rolling over in their graves right now but the fact of the matter is that sometimes pure OO is not always the best solution. Hopefully, in this book I effectively communicate with you these tradeoffs. In the end, it is up to you to decide when it would be appropriate to apply a pattern and at what level.
The patterns and practices I provide in this book are not engraved in stone. Instead, I hope they provoke other design ideas and give you at least a starting point for creating a more robust .NET application. I tried to keep it simple so that you don't have to spend hours deciphering one pattern or idea. I want to give you the seeds of design, not provide you with absolutely all of the plumbing. You may have to support the code, after all. It seems that the more complicated, or should I say "sophisticated," the pattern is, the less it's used. I've seen some great GUI patterns that, when demoed, produced quite a few "oohs" and "aahs" but when it came to implementing them without guidance, the effort was not quite what was intended. Ideas don't have to be complicated to be effective. Those simple yet effective, tactical, and pragmatic design decisions can carry you quite a long way.
Using a pattern or a template best practice is not the panacea of all design cures. However, when applied wisely, patterns and repeatable best practices can save hours in design, even if that design will eventually be remorphed into something much different in production. The point is to begin the design process. It is much easier to begin when you have a proverbial OO tool belt at your disposal. This also applies at the implementation level. Patterns are nothing but repeatable design, architecture, and implementation practices that are given names . This book is meant to provide you with new patterns and practices unique to .NET, as well as to build on what has already been accepted as classic OO principles. Throughout the book, I will describe some of the classic design patterns that everyone should understand. I will show you which classic patterns are related to those presented and even which ones aren't. I will also provide you with a roadmap of the material in the book and a classification system to use for pulling items from your design tool belt.
How Did We Get Here?
I don't want to inundate you with yet another technical history lesson. Frankly, I think there are too many books with unnecessary "filling." The only things that should contain fillings are things you eat. Personally, many times I skip Chapter 1 in the books I read, and I hope I've saved you from having to do that here. For those who want the "Twinkie filling" right now, go to Chapter 2!
To provide you with a brief perspective so that you appreciate the "coolness" factor of .NET, let me quickly run down where we've come from. I find that understanding the motivating forces behind .NET will give you a better understanding of what it really is. This will also later frame what I'm trying to accomplish in this book.
A Distributed Introspection
When the idea of the network PC was introduced to the public, it soon received mixed reviews and was not very successful. Why? I think the right idea was there but it was a little too much too soon. Too soon in that such radical computing paradigms rarely take off quickly. Look at voice processing. By now, everyone should have a voice processor. I mean, the technology is there, it is highly effective, and it has become rather inexpensive. So why don't all of us automatically use voice processing software every day? Instead, I am still typing this book the old-fashioned way. Ideas like this take time. They take time to evolve and standardize. They take time to become commonplace enough to be the default option. The idea of a network PC may not have received enthusiasm simply because we like our computing power. For example, the majority of folks still do not use public transportation. Even though it is better for the environment and in countless other ways, most of us still would rather drive to work. The same could be said for PC computing. We still want our local PC! This includes the myriad of personal devices we own, such as palm tops, laptops, cell phones, etc. We want the power to do what we like without being online to do it because we are not always connected. This "social tendency" can be applied in facets (hold on, I'm getting somewhere).
The "too much too soon" philosophy can be found in the world of distributed computing. Distributed technologies have been around long before the Internet but until now, industry players have had decisively different opinions as to which distributed technology should be used and what infrastructure was going to get us there. It took a slower, more accepted form of technical evolution to finally provide the general public with a model upon which to build a standard distributed platform. The model I'm referring to is the Internet. Through the standard protocols of the Internet, the general public now had a standard network infrastructure upon which to build truly common distributed paradigms. Today, people expect information to be available wherever they go with whatever device they have handy. This information can come from anywhere and in any form, and the Internet is the means for delivering it.
The Internet and its bed of standard protocols (e.g., TCP/IP, NNTP, SMTP, etc.) were only the first step in organizing this distributed web of information, however. Besides the network infrastructure, you still needed several other standard protocols and formats of data interchange. Retrieving data from a Web server in the form of HTML content is one thing. Automating the organization of information flow and the interchange of information from server to server is quite another. Other standards had to emerge for us to evolve from simply sharing information on a Web server and displaying it in a browser. We needed a way to interchange information from server to server, as well as a means of intelligently accessing information from anywhere on the Internet, much like we do when calling a simple API, but in a distributed fashion.
There are many ways to distribute services across any network, including the Internet. Using remote procedure calls (RPCs), I can invoke any interface, given an infrastructure that supports either UDP or TCP. I can also use Java's remote method invocation (RMI) protocol to invoke an externalized Java class method across the Internet. For those developing applications in Visual Basic or Visual C++, COM, or more appropriately, DCOM, can be used for your "remote write protocol," as Microsoft calls it. The same goes for OMG's CORBA. Each of these protocols can be effective in distributing your application and have been for many applications. However, each has its disadvantages. Universally, each has its own proprietary wire protocol used to interchange data. This includes the actual communication protocols, as well as the data formats used for the messages passed. Individually, they each have their own shortcomings, as well. For instance, Java's RMI is simple to implement but it forces the developer to use a single language and requires enterprise additions, such as J2EE's Enterprise Java Beans, to provide any form of true scalability. Heck, even after that, scalability is still a question, sorry Sun. DCOM, on the other hand, can be implemented using different languages but falls short in its support for network firewalls. DCOM also is not object oriented and, even though VB has made building COM components simpler, it is rather complex under the hood. The same goes for CORBA. CORBA is object oriented (and component oriented), supports multiple languages, and is rather scalable if implemented correctly, but it too suffers from complexity. What is needed is a standard means of remotely invoking objects using a standard message format that can be implemented in any language. Okay, enough setup. Enter XML and XML Web services!