"A lot of discussions about component-based design focus on how to design the components. But you also need to know how to connect the components. That's just as important as how to design the components in the first place. So I'm going to talk a little bit about how you connect the different physical nodes and logical nodes within your application.
"The first connection issue I'm going to look at is data access. The key is to use good principles of encapsulation and abstraction to hide the details of the data layer from your business objects. These details include such things as where data is stored, the physical structure, and the physical schema of the database. Use the data objects to present a nice, neat, logical model that business objects can work on. You don't want the business objects to have the responsibility of remembering where the data is, or what the physical data schema is, or what the best ways to access the data are. Get that information encapsulated in a data object.
"So what are some ways that you can implement access to the information in the data access service layer? There are several things to think about when you're picking a data access technology. We have a lot of them, including DAO, RDO, ODBC, OLE DB, ADO—in fact, you could probably pick any letter and add DA to it, and come up with an acronym for a data access technology. So how do you pick a particular technology? You look at things like ease of development. This could be important if you have a short development life cycle, or your developers are relatively new to this particular set of technologies. You might want to pick the access technology that has the best tools support or one that is easiest for your developers to work with, because you want to make it easy to build these particular types of components. On the other hand, ease of development tends to conflict with high performance, so programs that are easy to write might not meet the most demanding performance requirements. Then you need to look at whether you can get acceptable performance out of this component with the particular data access technology that you want to use. If you can't, then you might want to look at a slightly higher performing technology.
"You also have to think about the long-term impacts of picking these technologies. Are you going to be able to reuse this component in different situations? Are people going to be available to update the component if you have problems? And there might be other considerations that are important to your particular company. The key thing is to think about the non-functional requirements and business objectives and how everything fits into the overall enterprise structure and development standards, and use that information to pick the technology you use.
"Some of the options are whether to use a native data access API or something like OLE DB or ADO. These have greatly different ease of development standards, different tools support standards, and different flexibility. If you use a native API and you later change the underlying data store, your data object will need to be rewritten. But if you're using either OLE DB or ADO, you might be able to update some configuration information instead of having to change the code very much.
"You also might look at the difference between using dynamic SQL and using stored procedures. Stored procedures are probably going to give you much higher performance, but building query strings with dynamic SQL might give you more flexibility. In addition, stored procedures are typically specific to a particular database. So, again, if you think the data store might change or you need to support multiple data stores, you might want to keep that information in dynamic SQL statements.
"With COM+, you need to ask whether you go directly to the data store or use IMDB as a local cache for data. Are you mostly reading this information? Do you have one store where you can do updates? Or do you have to have some type of interactive development?
"You also need to think about communication with the external users of your system—both people and other programs. The protocol that you use to communicate with an external program or external user is determined by the kinds of user interface you want to present. If you're using a Web browser interface to present information to a user, then the communication protocol might be HTTP, because HTTP requests return HTML that naturally goes into the browser. But if you are talking directly to a WIN32 application, you might decide to use DCOM to communicate between the program and components that are running the business tier.
"You also need to think about firewall considerations and security issues. DCOM is good at communicating over TCP, but in most situations, it depends on a trusted domain relationship between caller and callee. Also it doesn't work really well through all firewalls. So in those situations, you might use an HTTP-based approach to get through the firewall and communicate with a Web server, and then have the server-side processing in the Web server communicate with the data objects.
"Some constraints might come from the operating system. For example, if you need to talk to an IBM mainframe, there are only certain protocols you can use. You need to think about the locations of the things that are communicating. Are they close together? Are they connected by a slow link? Is it a dial-up line? Is it a high-speed data connection? Your answers to these questions will help you define the protocol that you use to communicate between two tiers.
"As I mentioned before, two of your options are HTTP and DCOM. But you can also look at Remote Data Services, which gives you the ability to use either HTTP or DCOM through a COM component. This can be a nice option for accessing business objects and data without having to choose up-front either HTTP or DCOM.
"You should also think about messaging using MSMQ, or potentially using MSMQ in conjunction with IBM's MQ Series or some other messaging technology through a bridge. Then there are lower-level protocols such as RPC and sockets. But then you need to consider whether picking a particular option will affect whether you can build your application in a timely manner.
"I mentioned a while back that one of the things that you can do to improve performance is to eliminate some of the out-of-band work or independent operations, rather than tying them all together in one, big, synchronous operation. COM is synchronous: You make a method call, and you wait until you get a response. It's also tightly coupled, in the sense that the client knows what interface it's calling, goes to a particular object, and gets a response back from a particular interface method. But suppose your application doesn't need a synchronous response. You just want to say, "Here's some information; go process it at your leisure." In that case, you really want to consider using MSMQ or Queued Components, depending on whether you need to specify the message format or not.
"You might also want to develop your application as an independent silo that provides information that somebody might be interested in some day. In that case, you might consider using events, or you might consider publishing a message format that people could pick up. You might also combine these together in different ways, using Queued Components with LCE, for example.
"When you design parts of your application to work independently, you need to think about how you get status information back to the caller. If an operation has been working for some period of time, how do you let the caller know that it's done? You could send an asynchronous message back, or you could pull some status information from a data table. You also have to figure out how to recover from operations that are partially completed. For example, you order something and you get a message that the order has been placed, so you assume that the stuff that your order will be shipped eventually. What happens if the shipping department is not able to ship a particular item to you? The department has to have a recovery mechanism that says, "We're going to delay shipping this item for a while. If you don't want this particular product anymore, please let us know, and we'll cancel your order." Some business logic has to happen to recover from that partially completed operation.
"You also need to worry about security. Are you going to be able to communicate between these nodes, and do you have to protect the information that's being passed back and forth between them?
"After you've kind of figured out the big picture—here are the components we want, or here are the services we need to provide—how do you actually group them into the components that you're going to implement? First you pick classes that implement particular interfaces. Then you group the classes into components, which are the physical packages that you're going to install in a COM+ application. In most cases, you're going to have one class per component, but in some cases, several classes that all work together can be grouped into one component. Then you need to group the components into applications and processes.
"Now you have to think about the units of trust and the units of deployment. You do security checks when you cross into an application, but everything within a particular application is trusted. Each application is deployed as a block, so if you want to put two different components on two different computers, you need to make sure that those components are in separate COM+ applications. If you need a security check, you need to make sure that the call into that component crosses an application boundary. An additional complication is that today each class can be part of only one application per computer. So we have two types of applications: one that runs in an independent process, and one that runs in its caller's process. That gives you a way to build up a library application.
"You have to think about where you want things to be activated—on a particular computer, for example. Which components share resources and should probably be in the same process? You want to make sure that you are taking advantage of the underlying pooling operations provided by the system, which are typically per-process. You might also want to make sure that, if a particular component fails in such a way that it crashes, you don't bring down the rest of your system. That would be a good reason to put a process boundary around a component or set of components, to make sure that they can't cause the rest of the system to fail.
"I've already mentioned security isolation—assigning components to separate applications if you need a security check. You also need to assign applications and processes to particular computers. How you do that will depend partially on your deployment constraints. You're also going to have to tune everything based on your performance requirements. You may need to implement load balancing to get the scalability you want.
"What this all boils down to is: you shouldn't make decisions too early. You want to maintain flexibility in how you assign components to applications and processes as long as possible. On the other hand, you need to build any known constraints into your application up-front. You don't want to maintain flexibility and then have the application break because it was installed in a way that didn't meet the constraints you assumed when you built the application. So put in the flexibility you think you're going to need, but make sure that you have constrained the places that should not be flexible.
"Well that pretty much wraps it up, Dan. Sorry I've got to run, but I hope that helps your team get a better idea of COM+ and application design."
"Absolutely, Mary. Judging by the grins on everyone's faces, they're really going to like this new stuff." Dan brought the meeting to a close.
Bill walked over to the VCR and gingerly removed the tape, handling it as though it was precious gold. "This was great Dan, I'm going to make a few copies for my development team. They won't need to rent video tapes for a month; they can just watch this one again."
"Yeah, yeah, you developers always do things the hard way," said Tim not wanting to pass up the opportunity for a good dig. "I streamed this out to our new Microsoft NetShow server, so we can just stream it to everyone's browser. They can watch it day and night."
As Dan ducked out of the room, he shouted, "Well, it sounds like this was sage advice. I'll leave it to you guys to figure out the details. Let's go get this application shipped."