1
Starting Out With Components
As our customers, our managers and the sales team ask for
increasingly complex applications, the demands made of software developers are
growing at an ever-increasing rate. Lately, the vogue for companies, quite
rightly, has been to automate their business processes. Now the drive is to
integrate all of these disparate systems together, often with the addition of a
web interface so that access to these products and services is more widely
available.
The continual growth in the adoption and expansion of
computer-based systems leads to more sophisticated (or complicated)
applications�some of which take years to develop, or evolve without direction
into unmanageable systems that no single developer fully understands. When the
system requires maintenance or an upgrade, where's the developer who built the
thing in the first place? They're either 'too busy', or they've moved on to
richer pastures (not uncommon in today's market). That means that some other
poor developer has to bear the pain and hardship of working out where changes
need to be made�and the ramifications that these changes will have on other
parts of the system.
Concerns over scalability, structure and maintenance of
these increasingly complex systems, coupled with the demands that are the very
nature of software development, mean that something is needed to ease the
burden. Components have got a lot
to offer us. If you think of a component as a small, self-contained nugget of
code that we write to sit at a well-defined point in a system's architecture
and perform certain (related) tasks, we can begin a list of the benefits of
components right here:
q
Because by itself it is a lot simpler than the entire
application, we can maintain it easily.
q
Because it's self-contained, we can upgrade simply by
taking out the old component and putting the new one in its place. The same
applies to components that we discover to contain bugs.
q
If it's useful elsewhere, we can reuse it�we may borrow
it for our own purposes, or put it on the market.
We could go on, but we'll save that for later. The point is
this: everything we've said so far is just as applicable to ASP and web
development as it is to any other kind of development. Web sites are becoming
more complicated: our ASP applications are being asked to incorporate the
functionality of traditional applications; to centralize the point of access
for end users who need to get at different applications; to handle increasing
numbers of users. The fact is, we need to give components some serious
consideration.
Components are already an important part of programming and
software development, and the ability to build and use components is a valuable
tool in any programmer's arsenal. In fact, these days, component building is
arguably an essential skill.
In this chapter, we're going to convince you that you
already know quite a bit about programming with components; we'll look at some
typical scenarios in which components are used; and we'll begin to investigate
the impact that component programming has on application design. By the end of
the chapter, you should understand that componentization isn't just about code reuse�it implies a new
way of creating applications, opening the door to techniques and technologies
that aren't available in 'traditional' programming. Specifically we will see:
q
The advantages of using components
q
The basics of COM�Microsoft's Component Object Model
q
An introduction to 3-tier and n-tier application development
q
Examples of situations where you're probably using components
already
q
How to build and use our first component
The Advantages of Componentization
Consider the question, "What's the best approach to the
solution of a complex problem?" Perhaps the most obvious answer is this:
q
Break it up into a number of smaller parts, each of
which is self-contained and can be easily understood
q
Solve each of the smaller parts (or use a ready-written
solution�you might have a solution lying round from a previous project, or you
might buy in a third-party solution)
q
Bring each of the smaller parts together to create the
overall solution
This approach generally works very well�and programming is
no exception. The reason is probably its simplicity�but this simplicity is the
key to good software engineering and development.
COM�the Component Object Model
The good news is that there is an established technology
available to us today that allows us to build our applications this way. It is
called COM�the Component Object Model. COM is the
software industry's favored solution for solving the complex problems relating to
large applications and code reuse on the Windows platform. Using componentization, large
applications can be assembled from smaller, self-contained packages of software,
each of which performs a particular task.
By using components, we only need to write a small amount of
application code to act as 'glue', sticking the pieces together. The 'glue'
then simply calls the components into being, provides them with the information
they need to do their work, and then either lets them get on with it or waits
for them to produce a result. In this sense, they can be like little
"black boxes" of functionality: you don't need to know how each
component achieves its task; you just need to know what it's capable of doing
and what values you can provide it so that it will accomplish the task it is
built for.
A Couple of Analogies
If that sounds a bit esoteric, consider what happens when
you need to ask the operator for your uncle's telephone number. You call the
operator, and you give the name and address of your uncle. Then, they go away
and do their thing... and eventually they come back with a number (or not, if
your uncle has no telephone). In this sense, the operator is acting like a
component�maybe the request would be programmed like this:
�� Dim objOperator
�� Set objOperator =
Server.CreateObject("Operator")
�� Response.Write "The phone number you
require is " & _
������������������
objOperator.GetNumberFor("Uncle Brian", "Chicago")
The point here is that we're not particularly worried about
how the operator finds the number�we just give them the information and expect
them to do the job.
As another example, think about hi-fi 'separates'. You buy
an amplifier, a pair of speakers, a CD player, and you wire them all together
with some leads. Then, a month later, you decide that you wanted a turntable so
that you can play all your old vinyl. But you don't go out and buy a whole new
system�after all, you already have an amplifier and speakers. You just expand
the existing system by purchasing the turntable and plugging it into your
amplifier.
In your average software house, this is how customers and
the sales/marketing department think that application development works.
Wouldn't it be nice if it really did?
Well, there can be a strong similarity. You may not have
realized it, but you're already using COM components. For example, in your
software development, you've probably already come across ActiveX Data Objects
(ADO)�a set of components for data access. Or perhaps you've used the Ad
Rotator component, the Content Rotator component, or some of the other
components that are provided as standard with ASP?
Better still, look at the software you use every day�things
like Microsoft Word and Internet Explorer. Many of these kinds of application
are written using components. The Internet Explorer executable (Iexplore.exe) is only 77Kb in
size; all of its sophisticated functionality is handled by numerous other
components, which the executable only calls into action when necessary.
What Do Components Do for Us?
Hopefully, we've given you an incentive for wanting to learn
about components. The advantages of packaging up our code into
components rather than using script are numerous, and we'll outline the main ones here.
Code Reuse and Distribution
Possibly the two most common reasons for using components
are:
q
Breaking up a complex application into manageable
chunks, as we've already discussed
q
Packaging up code that you are likely to need more than
once so that it can be re-used
Having written a piece of code that performs a specific function, cutting and
pasting the appropriate pieces into another program can often be
difficult. If you've ever done this with your own code,
you'll know how tricky it is to remember how you originally
intended the code to work�you may have to work out what each line is doing in
order to select precisely the correct lines. And if you've ever done it with
someone else's code, you'll know that it's even harder!
When you package code into a COM component, you are
automatically providing a clear definition of precisely how to use the
functionality of that component. You'll still need to document it, but you
won't need to do any cutting and pasting of code.
Easy Distribution
Of course, this also makes for a convenient code
distribution technique. When passing your neatly packaged component to your
colleagues and customers, they don't need to
understand the code behind it to get it to work�you just tell them what tasks it can achieve and
what information they'll need to pass to it.
For example, we don't need to know how the ADO components
work in order to use them. We can just retrieve them from the Microsoft web
site, install them, and let Microsoft's documentation tell us the rest.
Binary Distribution and Reuse
As we'll discuss in more detail later on, COM components are
language neutral�they can
be written in one language and used in another. If you ask a
Visual Basic compiler to compile some C++ code, you'll see some interesting
errors and it won't work. Ask a Visual Basic application to use a COM component that was
written in C++, and it will work fine.
Maintenance and Replacability
Here's a case in point: if you have to do a lot of form
field validation, you can write a component that performs the task for you�that
way, you centralize the code in a
component, and you can simply reuse it time and time again.
If you ever find a problem with your validation code, you
can just correct the component and reinstall it in place of the faulty one.
Drawing an analogy with our telephone operator example, this is comparable to
the operator being off work. The telephone company just
installs another operator as a stand-in.
We, as clients, don't care which
operator is on the other end of the 'phone�so long as they can do the job.
Commercially Available Components
There are an ever-growing number of components that are
available commercially. If you have a programming task to achieve, it's quite
possible that there's already a component out there in the marketplace that
will help you to achieve you goal, or even provide a complete solution. Buying
a suitable third-party component means that we don't need to research,
write and test the component ourselves�this brings three immediate advantages:
q
We can acquire the component immediately, and therefore
we should be able to deliver our final solution faster
q
We've effectively replaced the cost of development and
testing (for that part of the project) with the cost of a fixed-price lump of
pre-written code�which is usually cheaper
q
Highly specialized components are usually written in
consultation with specialists in the field. In that case, we also avoid the
cost of employing a specialist
In addition, commercial components should be tried and
tested in their market situations, so you can be fairly confident that it will
perform well at the task it is intended to achieve (although it's worth
restricting yourself to buying components only from trusted suppliers, as you
generally don't get to see the source code). One very popular example of such a
component would be a credit card verification component for use in e-commerce
sites.
To get an idea of the
number of components on the market, check out some sites that specialize in
selling components over the Web. For starters, try http://www.componentsource.com, http://www.greymatter.co.uk, and http://www.serverobjects.com.
Performance Advantages
When you're executing complicated code, you're always
looking to reduce the time it takes to process. However, if your code is in the
form of ASP or some other script, you can reasonably expect it to take a while.
That's because scripting languages are interpreted.
That is to say, each line of code needs to be converted into more elementary instructions (binary code)
that the processor can understand, before that line can be executed. That happens every time a
script is run.
By contrast, components are usually already compiled, which means that they
have already been converted into the binary format. This means that the
component's methods�the functions that
it makes available�can be executed straight away. The result is that components
often execute much more quickly than plain scripts do.
Hiding Sensitive Code
If you're distributing code, then you need to think about
whether you want other people to see it. If they can see it, they can figure
out how it works, and they can probably also tamper with it. If you're
distributing script files, your code is open to these kinds of threat.
Writing components in languages such as Visual Basic and C++
requires you to compile them. By compiling the component, you produce the
binary representation
that we mentioned in the previous section�not only does this execute
efficiently, but also it protects your code from snoopers and code-changers.
Your component's business logic is safe from anyone who may wish
to meddle with it.
Splitting Tasks Into Distinct Areas
If you have several developers or teams working on an
application that is split up into discrete chunks, componentization makes it
possible for each of the different groups to work on a different part of the
application. Each task can be clearly defined, and you can specify the values that
the different parts of the application need to share in order for the
application to come together as a whole afterwards.
Ease of Debugging
While the Script Debugger is a very useful tool, it isn't
nearly as sophisticated as the debuggers in Visual Basic and (in particular)
Visual C++ . The debugging tool in the Visual C++
development environment,
for example, allows you to look right down into the computer's
memory to see what is being stored where.
This kind of capability means that, if you're using Visual
C++ or Visual Basic to write components that are intended to perform complex tasks,
you gain the edge in terms of finding out exactly why your code isn't working
properly.
That covers some of the major advantages of
componentization, although we will see others as we go through the book�in
fact, we'll see some more in this very chapter. If you take all of these
advantages into account as you write your ASP applications, you may soon find
yourself writing less of your programming logic in script, and placing more of
it into components. The ASP script becomes the 'glue' that binds the component
pieces of your application together.
How It All Comes Together
So, to recap: COM
stands for the Component Object Model, which is a framework
for creating and using components.
Microsoft introduced the COM framework back in 1993, as a
model for describing and implementing components in such a way that they could
interact with each other and with all COM-enabled platforms and applications.
COM is the specification to which
components are written and used on the Windows platform�and there are now
implementations of COM on many non-Microsoft platforms. Every component that we
develop in this book will be a COM component, and will therefore conform to
this specification.
Let's backtrack a little. We've just made a rather lofty
claim. All COM components will be able to interact with all other COM-enabled
platforms and components? How do they do that?
The foundation of COM is a binary
specification that defines how the code using a component�usually
called a client�can use the functionality
that a component makes available. On the flip side, it also defines how a component exposes that functionality to
a client.
Because COM is a binary specification, it allows language neutrality. As long as a
given language can produce compiled code that complies with the binary
specification, it can be used to write COM components�and it can also interact with COM components written in
any other COM-enabled programming language.
There are a number of languages in which you can write COM
components. In this book, we will mainly see how to write COM components in
Visual Basic and C++, although there are many more languages you could use,
including Visual J++, SmallTalk and Delphi.
So, while this book is about components for ASP, the
components that we'll develop are all COM components�and that means that (with
some exceptions) they can be used in other COM-aware programs, such as
standalone applications written in Visual Basic or Visual C++. As we will see
in Chapter 3, the ability to do this is dependent upon whether our components
are designed to interact with the environment that calls them. If we develop a
component that relies on some functionality of the ASP object model, for
example, we will only be able to use it within with ASP applications. There
are, however, very many occasions when our components will be reusable in
different environments.
COM is not the only
specification for components�CORBA and JavaBeans are two others.
However, as this book is about components for ASP, we will be focusing on COM
components.
ActiveX and COM
A term that you may have come across in the context of
component-based development is ActiveX,
and we should make clear that in most situations, ActiveX means pretty much the
same thing as COM. An ActiveX component is the same as a COM component. In
addition, an ActiveX control is the same as a COM control, and an ActiveX
server is the same as a COM server. But don't let all that confuse you�we'll
come back to these terms shortly.
Today, ActiveX is little more than an outdated brand name
that was introduced by Microsoft a few years ago when they redirected folks
towards the Internet and revamped and optimized some of their technologies to
meet the low-bandwidth requirements of the Net. There was ActiveX Scripting,
ActiveX Components, ActiveX Data Objects, ActiveX Controls, and ActiveX
Documents.
ActiveX achieved its original goals and got lots of media
attention, but since then people have been confused about the differences
between COM and ActiveX. Essentially, however, in modern-day parlance and as
far as ASP component development is concerned, ActiveX implies COM.
Components and Objects
We've established that a COM component describes a set of
related functionality and the code required to achieve that functionality. When
we want to use a component's functionality, however, we don't make constant
references to the component itself. Rather, we use the component as a
blueprint, and we use it to create an entity that we refer to as an object.
The process of creating an object from a component is called instantiation. An object is a
single instance of a component. The object is created in the image of the
component, and is the vehicle by which we make use of the component's
functionality.
In code, we use objects. An object
represents a single entity within our code; we use a component as the blueprint
for creating an object.
We may want to use several instances of a single component
at any one time, within different applications. Or we may have a single
application that uses several instances of the same component�just like having
many variables (or 'instances of variables') to hold different strings.
You should be aware
that the term 'component' is often used to refer both to the COM component and
to the instance�relying on the context to imply the exact meaning.