Chapter 2: .NET Objects


To match wi’ Scotia’s noblest speech yon orchestra sublime
Whaurto-uplifted like the Just—the tail-rods mark the time.
The Crank-throws give the double-bass; the feed-pump sobs an’ heaves:
An’ now the main eccentrics start their quarrel on the sheaves.
Her time, her own appointed time, the rocking link-head bides,
Till-hear that note?—the rod’s return whings glimmerin’ through the
guides.

—Rudyard Kipling, writing about the vastly different types of components
that any large application needs to work together
harmoniously,“McAndrew’s Hymn,” 1894.

Problem Background

Good code is hard to write. It’s never been easy, and the problems that developers need to solve to produce useful applications grow ever more complex in today’s distributed, heterogeneous Internet world. I sometimes catch myself longing for the good old days, when software development meant writing an input processor that read characters directly from the keyboard and parsed them into recognizable tokens to be fed to a command processor. It doesn’t work that way any more. Here are several of the difficult problems dogging the efforts of developers today.

Good code is hard to write.

First, we have the ongoing controversy over which programming language to use. While in theory any language can produce binary code that takes advantage of the entire operating system, it’s all too common to hear something like, “Hey, you’re using COBOL, so you can’t have automatic memory management. Get yourself a real language, kid,” or “Visual Basic doesn’t do uncouth things like threads” [nose in air]. We’d like the choice of language to be dictated by how well it matches the problem domain, not by how well it matches the system features. We don’t want any more second- class citizens. What’s probably going to be the downfall of the Java language is that you can only use its cool features from Java. I have no patience for anyone who insists that I embrace the One True Programming Language; instead, I believe that salvation ought to be available to believers of any development creed.

We need all system features to be available to programmers in any language.

With the release of COM in 1993, Microsoft Windows developers found that they didn’t have to write all of their application’s code from scratch. COM allowed a client to call functions on a server at a binary level, without needing to know the server’s source code implementation. Using COM meant that we could buy components—say, a calendar control—from third-party vendors and wire them into our apps by writing a relatively thin layer of “glue” code to express our business logic. We got faster application development and better functionality than we could have written ourselves, and the third- parties got a much higher unit volume over which to amortize their development efforts. Microsoft also used COM to provide access to operating system functionality, such as queuing and transactions, again making apps faster and easier to write. It was a good idea, and the software gods smiled. For a while.

COM helped us develop applications by assembling purchased components; we didn’t have to write everything from scratch.

As with most software architectures, COM helped to a certain point, but its internal structure has now become an obstacle rather than a help. COM has two main problems: First, it requires a substantial infrastructure from each application; for example, class factories and interface marshalers. Every development environment has to supply its own implementation of these mechanisms, so they’re all slightly different and not as compatible as we’d like. Second, COM operates by keeping client and server at arm’s length. They deal with each other through external interfaces, not through sharing their internal implementations. You might say that a COM client and server only make love by telephone. Unfortunately, everyone’s implementation of a COM interface differs in sneaky and hard-to-reconcile ways. For example, strings are implemented differently in C++ than they are in Microsoft Visual Basic, and both are implemented differently than strings in Java. Passing a string from a COM server written in Visual Basic to a COM client written in C++ requires work on someone’s part to iron out the differences, usually the C++ application because Visual Basic’s implementation isn’t negotiable. Programmers spend an inordinate amount of time ironing out these differences. That wastes valuable programmer time (and annoys programmers, making them change jobs to do something more fun), and you never know when you have it right, when any COM client regardless of implementation can use your server. We need to iron out differences in implementation, allowing our apps to interoperate on a more intimate basis.

COM only went so far. We need to abstract away the differences in implementations.

The Web is nothing if not heterogeneous. That’s the dominant feature that any successful software architecture has to deal with. Much as Microsoft would like to see Windows PCs everywhere, they’re starting to realize that it isn’t going to happen. We’d like to be able to write software once and run it on a variety of platforms. That’s what Java promised but hasn’t quite delivered. (Spare me the righteous e-mails disagreeing with that statement; this is MY book.) Even if we can’t make that approach work completely today, we’d like our software architecture to allow platform interoperability to evolve in the future.

We’d like our code to be able to run on a variety of platforms.

One of the major causes of program failure today, particularly in applications that run for a long time, is memory leaks. A programmer allocates a block of memory from the operating system, intending to free it later, but forgets and allocates another block. The first block of memory is said to be “leaked away,” as it can’t be recovered for later use. If your app runs long enough, these leaks accumulate and the app runs out of memory. That’s not a big deal in programs like Notepad that a user runs for a few minutes and then shuts down, but it’s fatal in apps like Web servers that are supposed to run continuously. You’d think we could remember to free all of our memory allocations, but they often get lost in complex program logic. Like an automatic seat belt that passengers couldn’t forget to buckle, we’d like a mechanism that would prevent memory leaks in some way that we couldn’t forget to use.

We need automatic memory management to prevent leaks.

When you ship a product, it’s never perfect. (I know, yours are, but you’ll have to agree that no one else’s are, right? Besides, with no updates, how would you get more money from your existing customers?) So some time after you ship the first version, you ship an updated version of the product with new features and bug fixes for the old ones. Now the fun starts. No matter how hard you try to make your new release backward compatible with all of its old clients, this is very hard to do and essentially impossible to prove that you have done it. We’d really like some standardized mechanism whereby servers can publish the version level they contain. We’d like this mechanism to enable clients to read the version level of available servers and pick one with which they are compatible or identify exactly what they are missing if they can’t.

We need help with managing different versions of the same software package.

Object-oriented programming, using such techniques as classes and inheritance, has permeated the software development world. That’s about the only way you can manage programming efforts above a certain, not-very- high level of complexity. Unfortunately, every programming language provides a different combination of these features, naturally all incompatible, which means that different languages can interoperate with each other only at a very low level of abstraction. For example, COM does not allow a Visual Basic programmer to use the convenient mechanism of inheritance to extend an object written in C++. Instead, COM requires cumbersome workarounds. We’d like object-oriented programming techniques to be available in and between all programming languages.

We’d like object-oriented programming features to be available in and between all programming languages.

The Web is fast becoming the main avenue by which users acquire software, which leads to major security problems. While current versions of Windows use digital certificates to identify the author of a piece of downloaded code, there is currently no way to ensure that a piece of code can’t harm our systems, say, by scrambling files. We can choose to install or not install a downloaded component on our system, but there is no good way to restrict its activities once it’s there. It’s an all-or-nothing decision, and we really don’t like that. We’d like some way of setting allowed and forbidden operations for various pieces of code and of having the operating system enforce those restrictions. For example, we might like to say that a piece of code we’ve just downloaded can read files but can’t write them.

For safety, we want to be able to restrict the operations of pieces of code we don’t fully trust.

The Windows operating system has grown almost unimaginably complex. From its humble beginnings as a Solitaire host with just a couple of hundred functions, it’s mushroomed into a behemoth FreeCell host with over 5000 separate functions. You can’t find the one you want simply by looking at an alphabetical list; it takes too long. Programmers manage complex projects by organizing their software into logical objects. We need a similar method of organizing the functionality of the operating system into logically related groups so that we have at least some chance of finding the function we want.

We need a better way of organizing operating system functions for better access.

Finally, I don’t want to dump on COM too badly. It was revolutionary in its day, and we’re going to have a lot of it with us for the foreseeable future. Just as the first color TV sets needed to also receive the black and white broadcasts that predominated at the time, so does whatever object model we start using need to seamlessly interoperate with COM, both as client and as server.

Our new object model needs to seamlessly interoperate with COM, both as client and as server.

It should be obvious that this long list of requirements is far more than any application vendor can afford to develop on its own. We have reached the limit of our potentialities. To move into the Internet world, we need a higher power that can provide us with a world we can live in.




Introducing Microsoft. NET
Introducing Microsoft .NET (Pro-Developer)
ISBN: 0735619182
EAN: 2147483647
Year: 2003
Pages: 110

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net