Mega Code Archive

 
Categories / Delphi / Examples
 

Designing Multitiered Component Architectures

Title: Designing Multitiered Component Architectures Question: An excerpt from Abernathy Randy's book COM/DCOM Unleashed - Chapter 2 Answer: Create Interfaces Interfaces are at the heart of COM. They are powerful abstractions that enable you to separate advertised behavior from internal implementation. An interface should describe only what public services an object offers. The private state of an object should never be disclosed via public interfaces. An interface in COM is the binding contract between a component and its clients. Interfaces at their core are a collection of semantically similar methods or functions accessed via a vtable pointer at runtime. An interface itself does not have any functionality. It merely points to the implementation. Interfaces can be reused (polymorphically or with inheritance) across components and upgraded. New methods can be added, but old ones should always remain. When designing interfaces, keep in mind that all the methods contained in an interface should have something in common. There is no limit to how many methods an interface supports, but a good rule of thumb is to keep the number below ten. This keeps the interface from becoming unmanageable and monolithic, defeating the purpose of COM. Implement the Components Finally, after you have created a conceptual model separated across tiers and interfaces, it is time to implement the behavior. Depending on the complexity of the application, this can be the quickest part of all. With the interfaces serving as a blueprint, and with the confidence of a sound design architecture, the requirements of the application can be implemented in code. Design Constraints When designing applications, be they multitiered or monolithic, a whole slew of requirements impose constraints on the finished product. Sometimes the requirements are conflicting or require bargaining tradeoffs. Size versus speed, for example, has historically been a major tradeoff facing software architects. With memory prices constantly dropping, this particular tradeoff is not as relevant today as it was a decade ago. Many new tradeoffs have emerged to take its place. These are discussed next. When working with modem-day multitiered architectures there many real and measurable forces acting on the overall shape of the architecture. The following are some of the most important: -Leveraging existing technology and skills -Time to market -Platform deployment Leveraging Existing Technology and Skills It is unrealistic to assume new projects will use all the latest high-tech tools, programming languages, and server-side products, setting aside all existing technology investments. In the real world, significant resources have been invested into software development: hardware, software, training, and sky-rocketing IS salaries all add up to a huge expense for any corporation. Fortunately, programming with COM does not require a major IS overhaul. It is possible to develop successful COM-based applications inexpensively and without having to throw in all the bells and whistles Microsoft has to offer. For example, expensive database products like SQL Server 7.0 may not be necessary if a corporation already owns another database. Same for operating systems. Although it is ideal for everyone to be running Windows NT workstations, Windows 95 or Windows 98 works just fine with COM and DCOM. Existing legacy code is not a problem either. SNA Server, Microsoft's bridge to the mainframe world, ships with the COM Transaction Integrator (COMTI). COMTI is a tool for creating COM components that transparently access mainframe resources. Chapter 17 of this book covers COMTI in detail. For interoperability with UNIX, several vendors (ChiliSoft, for example) have announced COM libraries for UNIX and VMS operating systems. Time to Market Software projects are consistently late and over budget. There are many reasons for this, but implementation and integration issues always seem to emerge as primary culprits. Although C++ is the ideal choice for COM, it is not always optimal. If the application requires real- time guarantees or is performance-critical, then a medium-level language like C/C++ can be the only choice. However, the majority of applications built today are not time-critical and can benefit tremendously from a Rapid Application Development (RAD) boost. As discussed in chapter 1, many excellent RAD tools exist; the most popular ones are Visual Basic, Visual InterDev, and Visual J++. With their COM support, these tools are well suited for creating prototypes that will scale to the real thing over time. Even better, a combination of C++ and RAD can prove to be the best choice because the developer can quickly create a UI with RAD, but with the speed and efficiency of pedal-to-the-metal C++. All this, of course, is married through COM for reusability and maintainability. Platform Deployment Even with the growing popularity of the PC, and the year 2000 quickly closing in, many companies are not yet ready to leave behind legacy systems. Their current systems might work correctly and not need fixing. Why invest so much money in new equipment and training when the current systems get the job done? The concerns are legitimate. Software has always been a very expensive craft, and business wants to milk its investments as much as consumers will tolerate. With the advent of the Internet and Web commerce, the software industry has witnessed an acceleration of new high-tech development with the latest tools and programming paradigms. It is not surprising that so many managers are overwhelmed by the choices and in frustration keep their existing obsolete systems. They figure waiting another six months will bring down prices and increase performance. Fortunately, one platform is virtually universal and seamlessly adapts to future hardware and software changes: the Web browser. HTML interpreters have been written for all operating systems imaginable, even telephones. The reality of an Internet-ready toaster doesn't seem so comical anymore. HTML is here to stay for a good while and makes perfect sense as a "platform." Consider HTML as your target platform. Design Goals In today's world of distributed computing and Internet applications, memory is cheap. It is reliability, not size, that matters. But reliability alone is not sufficient to justify an application to a modem user. There are several key intangibles that you must aim for as a developer. The following is a list of the most important ones: -Maintainability -Reliability -Availability -Scalability -Portability -Reusability -Locality (distributed or local; ties closely with performance) Maintainability How effective is a software system if it cannot be upgraded or evolved over time? If there is one lesson we have learned from the Y2K problem, it is that computer programmers should be more judicious and critical of the assumptions they make about the future. Foresight and flexibility during design and implementation win be greatly rewarded. A narrow and specific solution usually must be rewritten several times as new features are requested and unexpected requirements arise. Instead of attacking the problem in the particular, strive to solve the problem in general with additional rules for the specific problem at hand. All too often we come back to old code and wish we'd put a little extra effort into decoupling a large procedure or function. It's no fun to have to spend valuable time in a partial or complete rewrite. With COM, this is very easy to accomplish with interface inheritance. Create generic interfaces, then implement specific behaviors to suit your problem. A great example of this technique can be seen in the Persist family of interfaces, which am discussed in Chapter 3, "Persistent Storage." Reliability Probably the single most popular complaint about PCs is their instability. Whether it's the fault of the operating system or third-party software, it is the user who is left with a hung program and hours of work lost. PC versus UNIX reliability flame wars of biblical proportions have raged on Usenet for years, with no end in sight. The issue of UNIX versus PC reliability is not to be dismissed so quickly, and for time-critical or life-support systems it can be a matter of life and death. Consider medical equipment with embedded software, or the navigation software on airplanes. If the patient or passenger had the option of choosing which OS they would trust their lives on, what would be the most common answer? (I would most certainly pick UNIX!). Having worked on both platforms for almost 18 years, I have experienced the cold but faithful glow of a UNIX command prompt along with the warm, but fragile charm of a colorful PC window. But "COM," as Don Box once said, "is about love." COM embraces all strangers (IUnknowns), and does not discriminate across platforms (as long as they support COM). So we won't discuss which operating system is more reliable, and frankly, as COM developers, we have little control of this part. We are normally faced with platform constraints and may not always have an option of which OS to work under. We can, however, ensure that our code adheres to Microsoft guidelines for well-behaved components and can be ported not just to UNIX, but VMS or other systems that COM supports. These guidelines transcend your tried-and-true wisdom such as "Don't use global variables," or "Avoid goto statements. " They have more real-world implications like concurrency, threading models, or interprocess communication. Techniques for creating reliable components are covered in the rest of the book. Availability In the '90s, consumers are educated and careful. Gone are the days when it was the status quo to accept "system down" signs at bank tellers' posts or busy signals for customer service lines. Today's consumer is Web-enabled and spoiled to near instant transactions. If a Web site doesn't load in a few seconds, a few impatient mouse clicks land the user in one that does. Availability is expensive and difficult to achieve in a typical non-distributed PC environment. However, it is not necessary to create fault-tolerant rollover cluster systems to give the illusion of high availability. Windows DNA provides server-side products that offer users real-enough-time for the most demanding environments. The later chapters on MTS and MSMQ elaborate this point further. Scalability Historically, applications have been built to tackle current problems without foresight into evolving requirements that will place unforeseen demands on all or part of its components. A well- designed application can scale or absorb a changing environment, even under circumstances the developer didn't account for or imagine. As COM programmers, we are fortunate to have MTS, the scalability machine. We put regular but well-behaved components in one end, and watch them be transformed into scalable, robust objects on the other. But if it were only that easy! MTS does give us a lot of scalability for free, but that should not be used as an excuse to code resource-abusive components. When working with resources, try to be as frugal as possible and never hold a resource more than is necessary. Portability There are two levels of portability. One is at the implementation level, and the other is at the user or finished-product level. Before browsers and HTML, portable applications were written in languages like C or C++ and then compiled for each desired platform. This technique didn't always work because C does not provide a standard API for rich user interfaces. To exacerbate the problem, presentation code was written along with business logic, coupling the application and producing monoliths. Porting was a whole project in its own right and required significant resources to accomplish. Today there are browsers and platform-neutral markup languages like HTML or the new XML. It is only necessary to write the application for one platform and rely on the presentation layer to produce compatible HTML for universal compatibility. There is one disadvantage to browsers, however. They lack rich UI controls. Technologies like Java Applets, Dynamic HTML, and ActiveX can alleviate the problem but at the cost of introducing incompatibilities among browsers. To be truly browser-agnostic, we must do with standard HTML and its primitive forms capability. In practice, this is not the sacrifice third-party ActiveX and Java component vendors would want you to believe. If buttons and text boxes are not rich enough for your application, it is possible to use image maps and offer the illusion of a sophisticated GUI. Once again, if you haven't done so already, consider using an HTML browser as your presentation tier. Reusability The most widely accepted definition of software utopia is that place where software can be built effortlessly by assembling ready-made standard components, much the way circuit boards or vehicles are manufactured today. Although we are stiff many decades from achieving such a grand goal, we can certainly build COM components today and plan to reuse them a few months from now. The versioning properties of well-written COM objects guarantee that an existing interface today will continue to work (in some capacity) for the lifetime of the object. So even if new features are added to an otherwise old component, its past and present clients will not break. They just use what they need. The COM specification speaks of immutable interfaces but, in reality, this turns out to be more of a suggestion. It is specified by COM that once a component interface is published, it should never be changed. But it is possible to change the interface (or delete it altogether) and break the rule. This also breaks the binding contract between a COM object and its clients who expect to always find a specific interface. Blissfully ignorant clients of a misbehaving component will simply die after an illegal memory address rather than check to see if an interface query was successful. COM does not "catch" these breaches of contract and does not warn the developer of COM Specification violations. That is entirely up to the developer. Some of the tools in Visual Studio 6.0 (like VB or VI) do give a warning message when deleting interfaces, but it's still up to the developer to exercise the contract. Without this contract, the lifetime of a component is limited and its reusability compromised....