Certification Objective 7.01: Creating a Logical Design


There are four major steps for converting an application’s conceptual design model into a logical design:

  1. Identify the business objects of the application.

  2. Identify the behaviors (actions) of the objects.

  3. Identify the attributes (properties) of the objects.

  4. Establish the logical relationships between the objects.

In addition to these steps, the other major goal of the logical design phase is to convert the conceptual data model into a logical data model. The logical data model is often called the database schema because it defines tables, data fields, and relationships between tables. As discussed in Chapter 5, logical database design is often used as a visual map of the database and its architecture.

The Value of a Logical Design

At the end of the logical design phase, the team will have a set of important application documents. This documentation will provide application developers with important information about the internal workings of the program. Every database table and every application object will be fully documented in such a way that application developers will not have to look at the actual code in order to learn how certain components are meant to be used.

It is important to note that specific technologies will not be discussed or considered during the logical design phase. For example, we still have not decided if preexisting .NET framework classes can be used in place of particular business objects. There are several .NET enterprise servers that provide ready-to-use components, such as Microsoft Commerce Server 2000. These components can be used in place of one or more of the business objects defined during this phase, but those components won’t be investigated or considered until the physical design phase has begun.

Deriving a Logical Design from a Conceptual Design

During the conceptual design phase, we identified several potential business objects in the application. During the logical design phase, we will identify the objects that will be represented in our application.

All applications typically belong to one of the following three categories:

  • Data-oriented The prime objective of data-oriented systems is to collect and store data. These systems can be thought of as data entry and reporting systems. One of the key features of a system such as this is that the application is tightly integrated to a database at the back end. Almost every function of an application such as this requires the existence of a database.

  • Functional The prime objective of functional systems is to perform a well-defined function. For instance, the Microsoft Calculator application is a good example of a functional system, as is Microsoft Internet Explorer. Another less obvious example would be the programming logic inside a microwave oven. Functional applications can sometimes have a database component, but most do not.

  • Behavioral The objective of behavioral systems is to watch for, and respond to, certain events. An example of a behavioral system would be one that keeps track of inventory levels and automatically reorders more items from the appropriate supplier.

Some applications contain elements of more than one type of system. For instance, a banking application will have strong data-oriented components but may include financial calculators (functional) and automated credit-risk alerts (behavioral). In this case, the application really is made up of three interrelated applications. An application developer would probably analyze and construct each part of the application separately.

Identify Objects in a Data-Oriented System

There are several methods for identifying the objects in any system, depending on the system type. In a data-oriented system, there are four methods for initially identifying the objects in the system:

  • Locate nouns in the use case scenarios.

  • Examine the conceptual database design diagrams.

  • Consider external entities.

  • Identify events that need to be remembered.

For example, the use case document might contain the following scenario: “A data entry clerk enters orders into the application. Each order contains one or more items.” The nouns in this scenario are Clerk, Orders, and Items.

At this step, we really just want to list as many objects as we can. Proceed through the rest of the user specifications to see if any other nouns can be located. One potential trap is the use of adjectives to describe the potential objects. For instance, the user specifications may specify certain details about full-time employees and other details about part-time employees. At this stage, whether an employee is full-time or part-time is really just an attribute—in both cases, we list Employee as a potential object and deal with the subclasses later.

Another source for potential objects in a data-oriented system is the database conceptual design. Back in Chapter 5, we were examining the database for an employment agency. Some of the potential objects from that database were Job, Candidate, Skill, and SkillLevel. These all must be considered as potential objects in our application.

A third source of objects for the application would be the external entities that interact with the application, either directly or indirectly. In the employment agency application, the Agency, Client, and Candidate are all entities that the system might need to track. In an order entry application, the Customer object would likely be identified at this stage.

The fourth source of objects in any data-oriented application are the events that may need to be remembered. Identify the objects that receive the event and the objects that trigger the event. Following are some examples of some events:

  • Invoice printed This event increases the amount outstanding on a customer’s account.

  • Payment received This event decreases the amount outstanding on a customer’s account.

  • Online order entered This event triggers an e-mail to the customer account manager.

Identifying the events in a system can help you understand which application objects are important, as it makes it clear which objects need to send events and which ones should be available to accept them.

After examining these four sources for application objects, you should have a fairly complete list of all the logical entities required by the application. The list will likely need some refinement later down the line, but is a good place to start for now.

Identify Objects in a Functional System

Functional systems use slightly different sources for identifying important objects. Recall that a functional system is an application, such as the Windows Calculator, that performs a specific function but does not usually need to connect to a database or wait for an event to occur before acting. In the case of functional systems, our task is to identify the responsibilities of each of the system’s components.

The first step for identifying objects in this type of system is to extract the verbs from the user requirements. (Recall that we extract the nouns for data-oriented systems.) For example, we can extract the verbs from the following user requirement: “The user will be able to calculate the monthly mortgage payment for potential new mortgages.” The key verb (or action) phrase in the sentence is “calculate the monthly mortgage payment”. This verb phrase is listed as a key responsibility of the system.

After the key responsibilities have been identified, the next step is to break these tasks into smaller tasks. For instance, in order to calculate the monthly mortgage payment, the system needs to do the following:

  1. Enter the principal amount.

  2. Enter the interest rate.

  3. Enter the amortization period.

  4. Calculate the monthly mortgage payment.

Subtasks should be identified for each responsibility identified in this process. It is important to keep the steps from becoming too detailed during this process. Notice, in the previous example, we did not break the fourth step (calculate the monthly mortgage payment) down into the precise formula required to do this. The subtasks identified during this process will become functions (or methods in object-oriented terminology) of our objects.

Another example of breaking a user requirement down into tasks is the following. The user requirements might state, “The user should be able to change their e-mail address.” The key action verb in that statement is “change their e-mail address”. The process of changing an e-mail address can be further refined into:

  1. Retrieve user data.

  2. Update database.

After completing the process of identifying all of the responsibilities of the system, you can then match the subtasks with the data they are related to. For instance:

Data

Tasks

Mortgage

Enter principal; enter interest; enter amortization; calculate monthly payment; load mortgage from database; save mortgage to database; delete mortgage.

User

Retrieve user data; update database; add new user; delete user; validate password; change password.

With a slightly larger and more complex system, a definite pattern will emerge as to what the objects in your system will be and what methods those objects will need to support. Grouping related functions and data together is known as encapsulation in object-oriented programming. Related data and functions are encapsulated in a class.

Identify Objects in a Behavioral System

Finally, behavioral systems use another set of methods to identify the objects in a system. Recall that behavioral systems are those that watch for, and process, events. These systems are typically real-time systems, such as an instant messaging (IM) client. IM clients, such as Microsoft Messenger, wait for messages to be sent to the current user from other users across the Internet, and they take some type of action (usually a pop-up dialog box in Windows) once a message is received.

As you might expect, the potential list of objects in a behavioral system is derived from the events the system acts on. An event, in this context, is a signal, interrupt, or message of some sort that triggers some action within the system. In our IM example, a message being received from the Internet is an event. An automated stock system that allows a stock purchase or sale to be executed automatically when the specified equity reaches a predetermined price also has elements of an event-based system in it. So does the application that monitors my laptop battery and warns me that the charge is getting too low.

Once the events are identified, we need to identify the processes that handle these events. In Chapter 6, on conceptual design, we created procedural diagrams to help us understand the processes in the application. So what process within the application triggers the event (for instance, “monitor stock ticker”)? And what processes handle the event (for instance, “execute stock trade”)? We need to connect events and their processes.

Finally, we need to group into logical units the processes that act on related data. For instance, the processes that access messages in an IM system can be grouped into the Message unit, or the processes that access user accounts in a stock-trading system can be grouped under the Account unit. These units become the classes in our behavioral system.

Remove Unlikely Objects

Inevitably, there may be objects that were identified during the first phase of logical design that don’t serve any useful purpose and thus shouldn’t be included in your application as a system object. This could happen for objects that fall far outside the scope of your application’s core business purpose.

For instance, let’s assume you are designing an application for employees to enter their weekly timesheets. You may have identified an OfficeBuilding object during the conceptual design phase so that your application can relate each employee to a physical location. At this stage of the design process, you should honestly try to assess the real benefit of having an OfficeBuilding object within your application. Is there any functionality within the business requirements that require the application to distinguish an employee based on his location? Could that functionality be handled easily inside the Employee object by using encapsulation to hide it? As a designer, it is your responsibility to decide which objects in your system may be so unnecessary as to be inconsequential and possibly to remove them.

Identify Object Behaviors

Once the application’s system objects have been identified, you need to identify the behaviors associated with each object. For most objects, there are a core set of behaviors that need to be supported, such as the ability to create a new instance, load an existing instance, and delete an instance. Also, objects that have relationships with one another need to be able to establish and sever those ties. Finally, some system objects will need to perform other tasks in order to be useful in the context of the application.

For instance, let’s assume we are developing a calendar application that allows users to add tasks and appointments. Calendars are essentially made up of dates, so the main object in this application will be the Date object. The object will need to have certain mandatory behaviors, which will then become methods, in order to do the following:

  • Create a new instance of a Date.

  • Load an existing instance of a Date from the database.

  • Delete an existing instance of a Date from the database.

  • Save changes to an existing instance of a Date.

In addition, a Date may have zero or more appointments, so the Appointment object is a child object of Date. This means that the Date object will need to have behaviors that allow it to add and remove appointments:

  • Link an Appointment object to the current Date object.

  • Unlink an Appointment object from the current Date object.

Finally, this application requires the Date object to handle certain tasks, so the Date object will have the following additional behaviors:

  • Retrieve all appointments for the current Date.

  • Print the current Date to the local system printer.

Thus, we have been able to identify eight behaviors that the Date object must be able to support. These behaviors need to be documented as part of the logical design.

Exercise 7-1: Identifying Business Object Behaviors

start example

If fulfilling user requirements is the ultimate goal of developing an application, defining and implementing the appropriate object behaviors is what gets you there. In this exercise, you are going to examine an object and identify appropriate object behaviors.

Let’s start by looking at an example of an application that is being developed. A law firm has asked you to redesign their client billing application. From your conversations with the client, you have learned the following about lawyer’s invoices:

  • Invoices must contain the name of one and only one client.

  • Invoices always have a unique invoice number.

  • Invoices always have an invoice date.

  • Invoices contain a list of one or more billable tasks.

  • Each billable task contains a descriptive text field, a lawyer name, an hourly rate, and the number of hours worked.

  • Invoices contain one subtotal, one tax line, and one grand total line.

  • The application will need to be able to create new invoices, load existing invoices, edit and update invoices, and print invoices.

From these requirements, three business objects have been identified: Client, Invoice, and BillableTask.

  1. What are the core set of behaviors that the Invoice object must support? “Core behaviors” are those that support the creation and initialization of the object.

  2. What are the set of behaviors that are required to support the relationship between the Invoice object and one or more BillableTask objects? When dealing with an object that is the parent to another object, you will likely need to define a method to retrieve a list of the child objects, as well as several methods to support adding and removing child objects from that list.

  3. Finally, list the behaviors required to support basic application functionality, such as saving and printing.

end example

Identify Object Attributes

The attributes of an application object that are identified at this stage will become the properties of the class that eventually gets created. For objects that were taken from the conceptual database design model, identifying the attributes may not be too difficult. The conceptual model clearly identifies the attributes of the object. However, for objects not based on an existing conceptual model, you will have to refer to business requirements or other specifications documents to identify the relevant attributes. For instance, coming back to the calendar application referred to in the last section, the Appointment object will have a number of obvious attributes:

  • The title of the appointment

  • The date when the appointment occurs

  • The time, if any, when the appointment occurs

  • The appointment’s scheduled duration

  • A detailed description of the appointment

Some calendar applications may support many more details for appointments, including separate properties for the location, an array listing all of the people scheduled to attend, and the name of the originator of the appointment. The attributes identified for each object will obviously be based on what type of data each object is required to store.

Establish Logical Relationships

While you were identifying each object’s behaviors, you might have already given some thought to how each object relates to other objects in order to establish methods that create and destroy relationships between objects. The final step in creating the logical design is to formalize those relationships in your logical design.

Many of the relationships between objects will be already taken into consideration in the database conceptual design diagram described in Chapter 5. There is a good reason for this—the database conceptual design aims to model the elementary facts of the system. So, for data-oriented applications, there should be many similarities between the database model and the application model. (Obviously, for functional and behavioral applications, there will not be very much similarity, if any.)

start sidebar
From the Classroom—How Does Unified Modeling Language (UML) Fit into Application Design?

UML is a popular set of modeling languages designed to standardize the way in which object-oriented applications are designed and documented. It is important to know that UML is a collection of various techniques developed independently that have evolved over the years. UML version 2.0 is currently underdevelopmentbytheObjectManagement Group (OMG). More information, including the official specifications, can be downloaded from the official UML web site, at http://www.uml.org/.

There are twelve core diagrams in the UML specification, and they are divided into three categories:

  • Structural diagrams Class, object, component, and deployment diagrams

  • Behavioral diagrams Use case, sequence, activity, collaboration, and statechart diagrams

  • Model management diagrams

    Packages, subsystems, and models

    As you would expect, structural diagrams describe the structure (or architecture) of the application. The class diagram is one of the most useful diagrams during the logical design stage of development because it defines the classesthatarecontainedinsidetheapplication. Class diagrams also contain the properties and methods of each class, as well as related connecting classes.

    Behavior diagrams describe how a system is expected to behave over time. Some diagrams, such as sequence or activity diagrams, describe an order of events, while others, such as statechart diagrams, simply describe the valid states of an object.

    Model management is a methodology within UML that allows complex application models to be organized into packages. This is especially helpful when more than one person is working on a large UML model. Charts of all types can be organized into hierarchies of packages, subsystems, and models. Each UML modeler can be working on the section of the application that they are an expert in without affecting other modelers working on the same model.

    It is not mandatory that developers use UML models in their application designs, but being familiar with and using UML in a project will have at least four important benefits:

  • UML models are self-documenting. After the application has been built, the model used to design the application can be referenced in system documentation to help future developers understand what is going on.

  • UML models have a standard (and precise) notation, so models developed by one person can easily be understood by another. This reduces confusion and improves the maintainability of an application.

  • Many tools exist that can turn UML models, such as class diagrams, into empty class and attribute definitions, sometimes called skeleton code. This can save development time and reduce errors in translating the model into an actual class.

  • Some models, such as use cases, make testing the application easier. Quality assurance (QA) analysts can easily turn use cases into testing scripts instead of having to create those scripts from scratch. More accurate testing scripts usually reduce the likelihood of system errors when the application is rolled out into production.

    As a .NET solution developer, it is probably in your best interest to make the effort to understand the various UML notations that exist. UML may not be used in every project, but these diagrams are easy and accurate ways to describe the design and expected behavior of an application.

    — Scott Duffy, MCSD, MCP+SB, SCJP, IBMCD-XML

end sidebar

Organizing Logical Structures

Once all of the application logical classes and objects have been identified, the next step in the process is to organize them into logical structures. Most typical business applications do not perform only one task. Applications that perform only one task, such as Microsoft Calculator, are actually quite rare. Most applications end up being closer to Microsoft Outlook Express—that is, they do one key job, but can also perform a bunch of smaller jobs. Outlook Express is used mainly for sending and receiving e-mail, but it also supports an address book and newsgroups. These functions are in some ways similar but in many ways are not. The underlying Outlook Express application objects can be logically grouped as follows:

Group

Logically Related Objects

E-mail

Message, LocalFolder, MailAccount

AddressBook

Contact

Newsgroups

NewsMessage, Newsgroup, NewsAccount

Each object has its own set of encapsulated data and functionality. For instance, the Message object encapsulates data about the message (to, from, subject, and so on), and also includes functions (new message, send, and delete). But the Message object interacts with the LocalFolder object (which represents folders such as Inbox, Drafts, and Sent Items), so the functionality can be grouped. The Contact object might have some communication with the Message object (such as when double-clicking on a contact triggers a new message to be created that is addressed to that person), but the functionality required to maintain an address book is quite separate and distinct from the functionality required to compose an e-mail message.

Considerations for Auditing and Logging

To this point, the logical application design has focused on user-related functionality, and for good reason. The success or failure of the application largely (but not entirely) rests on the ability of the application to do what is expected of it. But there are some processes and procedures that are oftentimes necessary to include in an application design that do not have an effect on the user. Auditing and logging are two examples of these processes.

Auditing (sometimes called an audit log or an audit trail) is used to record system activity for the purposes of after-the-fact security. Auditing is not usually used to prevent problems from occurring, but instead to be able to answer the question, “What happened?” For example, an application that contains sensitive data might keep an audit log of all users who log in and out of the system (by recording user IDs and timestamps) or keep a log of who is making changes to the data. If it is later discovered that some data has been maliciously altered or destroyed, the audit log will contain the perpetrator’s identity—as long as that log cannot be altered. In the interest of security, access to the audit log should be restricted to everyone except systems administrators.

Whereas an audit log is kept primarily for security purposes, other event logs are often needed for other purposes. The process of keeping these other event logs is called logging. Examples of these nonsecurity logs include:

  • A record of system error messages (error logs)

  • Logs required for statistical purposes (web server logs)

  • Logs to assist developers with system bugs (debug logs)

  • Status messages of batch processes (status logs)

It is often a good idea to segregate the processes that support application logging into a separate object. This helps with code reuse and keeps similar functionality together. Each business object in the system that needs to write information to the log can call a common logging object. This also makes it easier to change systemwide logging practices (toggle on and off, change log destinations, avoid verboseness, and so on).

There are several methods a developer can use to implement logging within the application being designed:

  • Write log events to a table in the database

  • Write log events to a file on the file system

  • Write log events to the Windows Event Logger

  • Compose and send an e-mail based on the event

  • Any combination of the above

    Exam Watch

    Microsoft recommends developers use the Windows Event Logger, which displays operating system, security, and application events in a single interface, alongside any custom logs you have created.

Handling Errors and Exceptions

In object-oriented programming, an exception is an error message that is passed from one object to another. The object that first encounters the error creates an exception, and then passes it to the object that called it. If the object receiving the exception is not watching for it, which in object-oriented terminology is known as not handing the exception, the exception will be passed back to the preceding object in the chain, and so on. The process of continuing to pass an exception back to previous objects until it is handled is known as bubbling.

During the logical design phase, we need to identify the objects that can encounter either system or application errors. For example, in a database application, any objects that interact with the database could potentially encounter a database error. In a previous example, we identified a User object that had an associated method of “retrieve user profile.” In the process of retrieving the user profile, a multitude of system problems could occur:

  • The network could be down.

  • The database server itself could be down.

  • The database instance running on the server could be down.

  • The database could be corrupt.

  • The user authentication for connecting to the database could have failed.

  • The record might not exist inside the database.

Obviously, many other problems could occur. Each of these system problems could create an exception, and so obviously any object that is relying on the “retrieve user profile” method of the User object will have to handle exceptions.

There are also application-specific exceptions that could occur. These are usually business logic errors that your application code has detected. As a programmer, you can create and send your own exceptions to indicate an error. This is known as raising an exception. Following are some examples of application-defined exceptions:

  • The account does not have enough money in it.

  • There are not enough parts in inventory to fulfill the order.

  • The Date of Birth entry cannot be in the future.

Perhaps the most important thing to understand about exceptions at this stage of the logical design process is that they are used to report errors. This makes it crucial to document which classes and methods within the application design could raise errors and who should handle those errors.

Integrating the Solution into the Enterprise

One of the important considerations when designing a solution is how it will integrate into the existing enterprise architecture (EA). You’ll recall we discussed EA back in Chapter 2. Enterprise architecture is the business, application, and technical infrastructure of an organization. How well an organization’s application architecture matches its current business processes is an important factor in its operational success or failure.

Applications rarely exist in a vacuum. Oftentimes, systems will need to retrieve data from an external source—a centralized customer database, for instance—or provide data to an external system. The specific components within the logical design structure that will be responsible for interfacing with these external systems should be identified at this stage. We still are not ready to think about the specific technologies that will be implemented, but we can design generalized methods within specific objects, such as adding ExportData and ImportData methods to the Customer object, to handle these tasks.

One important suggestion to keep in mind at this stage is to try to centralize the interfacing tasks as much as possible to make it easier to make changes to those interfaces in the future. If each object in the system is required to send its data to a central reporting database each night, it might be a wise idea to create one object that does the actual transfer of data, while the individual object might only be responsible for preparing the data for transfer. For example, each object might have a “Serialize” method that will allow it to be saved to database in a retrievable fashion.

Considerations for Globalization and Localization

One of the challenges faced by application developers today is the issue of localization. Localization, sometimes abbreviated to l10n, is the process of designing an application that can be altered to fit the language or cultural differences of a specific locale. Many developers think that localization merely involves translating the text strings within an application into multiple languages. In fact, many considerations need to be made during the application design phase for localization:

  • Language Some applications need to support multiple languages such as English, French, and Spanish.

  • Dialects Some countries and regions have terms and phrases that would not be understood in other regions of the world.

  • Date and time considerations Applications that display current dates and times need to be sensitive to current time zones, observance of daylight savings time, preferred formatting of dates and times, and so on.

  • Currency and numbers Many countries have their own unique way of representing units of currency, the currency symbol, the thousands separator, and the decimal point.

  • National holidays Applications that contain embedded calendars might need to display different sets of holidays to users in different locales.

  • Other cultural differences Localization involves replacing examples that may be relevant in one part of the world but not relevant in another.

    Author's Note

    The abbreviation l10n is sometimes used in place of the word “localization” because there are 10 letters between the initial letter l and the final letter n. For the same reason, the word “internationalization” is sometimes abbreviated to i18n.

Building with Security in Mind

The word security can be defined as something the gives or ensures safety. You know security is working when you (and your personal property) are not at risk from attack. In real life, security is achieved using methods such as fences, locks, guards, identity cards, cameras, and metal detectors. In the world of information technology (IT), security is achieved using technologies such as firewalls, certificates, IDs, passwords, well thought-out business logic, and proper logging techniques.

It is often much more difficult to add security to an application after it has been designed and developed than if adequate consideration was given to security during the design phase in the first place. Security is, of course, an even more important concern for applications that have a network or database component.

Of course, there are various levels of security. You can have security in applications that have no user ID or password component—kiosks in a mall, for instance—just as you can have security that requires retinal eye scans or fingerprint identification. The level of security is, of course, directly related to the sensitivity of the data and the severity of the “worst-case scenario” if the application security is fully breached.

For some web sites, the worst damage that can be inflicted by outside hackers is modification (or defacement) of web pages on the site. That’s embarrassing enough, and most companies will spend a reasonable effort to avoid being publicly humiliated in that way. But other types of security breaches can inflict millions of dollars in damage on a company if trade secrets are stolen, financial accounts are modified, or transaction records are deleted. These security incidents can have a lasting effect on a company, particularly if customers have lost trust in the company and sales drop as a result.

Designing security into applications always involves tradeoffs to some degree. Should you inconvenience your users by forcing them to log in every time they access the application? Should you place restrictions on what functions within an application each user can access? There are also a number of concerns relating to how a tight security system will be managed over the long term. For instance, who will decide which security restrictions to place on each user? And how easily can system privileges be granted and revoked based on an employee’s changing roles within the company? After all, you do not want the process of security to seriously impede your company’s ability to do business.

And therein lays the tradeoff. Security tends to be, almost by definition, a bit inconvenient for users. How much extra inconvenience would your users be willing to endure in order for their data to be completely secure? That question can only be answered on a project-by-project basis.

Security in .NET

With the flexibility and variety of the .NET framework classes, Microsoft .NET provides many ways for an application developer to implement security in a .NET application. The three most common techniques are

  • Role-based security

  • Web application security

  • Evidence-based security

Role-based security is the concept that the various components of the application always execute under the security restrictions of the user. That is, even if an application is spread out across several back-end servers in an n-tier architecture, the server-side components are logged into the servers using the user’s ID and password to execute their function. If the user doesn’t have access to a Windows folder or SQL Server, then the application will fail. This type of security is recommended because so many of the security breaches (or “hacks,” as they are commonly called) have involved a user being able to get system-level privileges. The theory is that it will be much harder for malicious users to breach security if even the back-end components run in the user’s security context.

The WindowsPrincipal .NET framework class is used to handle authentication for Windows-integrated role-based security. This security model relies on each user having a user ID and password on the Microsoft Windows server or domain in which the application is running. Since many organizations already provide their employees with Windows domain-level user IDs and passwords, role-based security can be quite convenient for users. In fact, by integrating the security of an application with that of the Windows operating system, the job of managing user IDs can be centralized.

The GenericPrincipal class is used to handle authentication for applications that need to handle their own user IDs and passwords. Applications can further customize their security by implementing their own Principal classes based on implementing the IPrincipal interface.

Exam Watch

It is important to understand what the WindowsPrincipal and GenericPrincipal classes do and that their respective roles are within an n-tier application security model.

Web application security is an important consideration when building ASP.NET applications. ASP.NET integrates well with the Internet Information Server (IIS) web server to support common Hypertext Transfer Protocol (HTTP) authentication schemes, such as the following:

  • Basic

  • Digest

  • Windows NT LanMan (NTLM)

  • Kerebros

  • Secure Sockets Layer (SSL)/Transport Layer Security (TLS) client certificates

In addition, ASP.NET integrates into Microsoft’s new Passport web-based authentication system. One of the big benefits of using Passport for your web-based application security is that Passport already has an estimated 200 million users. If your application integrates with Passport, your users will not have to create a separate user ID and password for your application.

Author's Note

You can learn more about Microsoft Passport at http://www.microsoft.com/net/services/passport/.

A third technique that .NET provides for implementing security is called evidence-based security. This method involves placing restrictions on the type of code that can be run within the application. An example of this type of security would be a server component that does not explicitly trust the client component calling it. Some component’s methods may be called freely, while others require some evidence—for instance, a client certificate, a valid digital signature from the client, or even the IP address of the machine making the request. Additionally, developers can pick and choose which methods are restricted, which need additional evidence, and which do not.

Identifying Appropriate Technologies for Physical Design

Even when we drafted the solutions concept, which was discussed in Chapter 2, we have been hinting at the technologies involved in the application design. If our application is to be a two-tiered architecture, with a Windows client that connects to a database server, there is an implied physical design. We are just now going through the process of converting the conceptual design into one that is separated into logical categories. So while it is too early to talk about specific technologies involved in the application, it is safe to begin identifying which technologies are appropriate from the design point of view.

For example, you may already have decided that the application is to be developed using Visual Basic .NET whenever custom code has to be developed. That decision does not restrict you from using third-party or off-the-shelf objects to manage certain areas of your application (messaging is a good example). One of the powerful features of .NET is the choice of application language to use (Visual Basic, C#, and C++, for instance), which is now more of a programmer choice. Whereas certain applications had to be developed in C++ in the past for performance reasons, that is less of a consideration in .NET.

Another technology decision you might have already made at this stage is which operating systems the application will have to support. If you know your users have a wide variety of Windows, Mac OS, Sun, and Linux desktops, that will restrict you from using certain technologies and may even force you into having no choice in the matter. Certain technologies are required and may even have been specified in the business or user requirements as a given—for example, “The client portion of this application will be written in HTML 4.0.”

Creating the Logical Design for Data Privacy

Privacy and security are two related yet distinct topics, and it is sometimes easy to get them confused. As we discussed in a previous section, security is something that gives or assures safety. Data safety is assured by first establishing a person’s identity (through authentication) and then ensuring that the person can only visit areas of the application where they have explicit permission to be.

Data privacy, on the other hand, is the notion that not all data should be shared equally. For instance, I may not mind that my local video store keeps a database with my name in it. After all, the video store and I have an ongoing relationship. But I would mind a great deal if that database also contained my social security number, my employment salary, and my medical history. There is a great deal of information about me that I wish to keep private.

A second aspect of data privacy is the handling of passwords. Applications have for years been treating password fields differently from other data fields in applications, using one-way encryption techniques to ensure that passwords are irretrievable once set. Most applications also mask password fields using a series of asterisks (such as “********”) at the user interface level.

A third aspect of privacy is to protect sensitive data (such as online banking applications) from being intercepted between the bank’s server and the client’s PC. This is done using Secure Sockets Layer (SSL) encryption. In order to protect the privacy of the financial or other information contained on the page, most web browsers also do not cache (store on the local PC) web pages retrieved through SSL.

The proper time for application designers to give some consideration to data privacy is during the logical design phase. Security often plays a big part in ensuring privacy, but as you can see, the issue of privacy goes beyond that.

Building the Presentation Layer

The presentation layer is one of the three primary layers of traditional application design. The business and data layers are the other two. The presentation layer is represented primarily by the user interface, and we touched on that in the previous chapter (in the section titled, “User Interface Conceptual Design”).

In .NET applications, the presentation layer is created using four sets of .NET Framework classes:

  • Windows Forms

  • Web Forms

  • Console applications

  • Web services

Windows Forms classes, available in the System.Windows.Forms namespace, are used to add graphical user interface controls to applications running within the .NET Framework environment.

Web Forms classes, available in the System.Web.UI namespace, are used to add graphical user interface controls to applications running remotely inside a web browser (commonly called web applications).

Console applications have a text-based user interface. The System.Console namespace contains classes that allow applications access to the three streams that make up the Windows console—input, output, and error. These three streams have been available to text-based applications since the early days of DOS, and it’s good to see that they’re still kicking around.

The user interface for web services is purely in XML text. That is because the users of web services will always be other applications and not people. Despite the lack of a direct human interface for these types of applications, web services still have nonhuman users that need to communicate with them.

Logical User Interface Design

It is during this phase of application design that you should start putting some screen shots or other UI design ideas together. You should start thinking of the application in terms of how the user will see it. Many projects actually present the UI design to the users in order to get their approval.

This does not mean, however, that the users will have a working application with which to play with. After all, we haven’t even gotten into physical application design yet. We haven’t decided on which underlying technologies will be used to develop the application. Logical user interface designs are often nothing more than artistic renderings of what a screen might look like once the application is developed. I have worked on projects that did the initial user interface design using a graphical image editor (such as Adobe Photoshop).

Typically, all you need at this stage is two or three representative screen shots to show overall UI concepts of how the application will look. Concentrate on colors, menus, themes, navigational guides, and other key application features. You don’t even need actual content. Many preliminary user interface designs use “Blah blah blah,” “Lorem ipsum dolor sit,” or some other nonsense text where the written content should be. Using nonsense text actually has a beneficial purpose in some cases because it helps focus the user’s attention away from the content and towards the overall UI design, where it belongs. Including actual content could distract the user into making spelling corrections, rewriting sentences and paragraphs, and so on.

Considerations for Synchronous or Asynchronous Architecture

Most applications developed today are synchronous. That is, when passing a task off to another component to perform, the application waits patiently for the task to complete before continuing. An example of this would be the process that occurs after a user saves a record in a data entry application. Typically, the application sends the data on to a relational database such as SQL Server and then waits for the database update to complete no matter how long that takes. Most database transactions such as this have built-in timeouts to give up after a set number of seconds or minutes have passed.

Usually, the use of this type of architecture is entirely appropriate. Most transactions, such as saving a record to a database, only take a fraction of a second and do not create a performance bottleneck for the application. Also, there are also times when the application absolutely needs to know the results of the previous task before it can move on to process the next one. In cases where tasks are heavily dependent on each other or application response time is not likely to be a concern, it is usually wise to stick with the synchronous setup.

But there are also times when you will want to do things in an asynchronous manner. An asynchronous application will pass a task off to another component to perform and then not wait for the task to complete before continuing. The application can then ask to be informed when the task has completed or not, depending on whether it cares about the outcome.

An example of an asynchronous process is the way printing works in Microsoft Word. You do not have to wait for the entire document to print, or even for the entire document to be sent to the printer, in order to continue working within Word. Printing a document, particularly a lengthy one, can be a time-consuming task. Before Microsoft introduced asynchronous processing into Word, users would have to wait for the document to be sent to the printer, which could take several minutes, during which time Word would not respond to user requests.

You can take advantage of asynchronous processing within your Microsoft .NET applications as well. There are times when it makes good sense to do so, such as when generating a report will likely take several minutes or a systems administration task triggered from within your application (for example, a function that updates thousands of database rows) could take hours.

The System.Threading namespace within the .NET Framework contains classes that enable asynchronous processing. Typically, an application creates a new thread for these separate system processes to run and passes in a callback function as a parameter. A callback function is a function in the current thread that will be called by the new thread when it is finished processing.

Creating the Logical Design for Services and Components

Designing web services and application components have their own set of unique challenges, which are slightly different from regular Windows Form or Web Form application design challenges. Services and components do not have a graphical user interface but do have an application interface. The application interface is the protocol used by clients when sending requests to and receiving responses from these server applications.

A component is a self-contained object that performs a specific task. It is a building block that can be combined with other components to form an application. For instance, Microsoft provides certain .NET Framework classes, such as ADO .NET, as components that applications can use to access various data sources. Developers can create their own application components, either as .NET assemblies or Component Object Model (COM) objects.

A service, sometimes called a web service, is an application that provides its functionality to other applications over a distributed network such as the Internet. Microsoft Windows has supported applications running in the background, called Windows services, which have some traits in common with web services, but are on the whole quite different. It is important not to get Windows services confused with web services.

Exam Watch

There may be questions on services and components in .NET on the MCSD Solutions Architecture exam.

A Windows service is best described as an application that runs under Windows, which generally is always running but does not have an integrated user interface. For instance, the Microsoft IIS web server is configured to run as a service on Windows servers. Administrator access to the web server is made using a separate application, using a Microsoft Management Console (MMC) plug-in that is not part of the IIS service application.

An example of a web service would be an application that provides stock quotes. Other applications could connect to this service to request a quote, but unlike a Web Forms or Windows Forms application, users could not access the service directly themselves. Unlike Windows services, which always must be installed and running on the local PC, web services are almost always remote applications. The architecture of an application that consumes web services—web services are consumed, not used— is almost always two-tier or n-tier. Web services use widely accepted standards such as Extensible Markup Language (XML) and Simple Object Access Protocol (SOAP) to communicate with other applications.

Author's Note

More information on XML can be obtained from the World Wide Web Consortium (W3C) web site, at http://www.w3c.org/XML/.

Following are some of the challenges of designing and developing components and web services:

  • Since these applications are designed to be used by several users at a time, how do you deal with passing or storing session state?

  • How do you upgrade or change an application that is used by hundreds or even thousands of other applications that you don’t have any control over?

  • With direct access to the application interface via methods and properties, how do you ensure that only authorized users gain access to certain restricted functions?

These are just some of the considerations developers have to take into account when creating application components or web services.

Creating the Logical Design for State Management

A user session begins when a user logs into an application that exists on a server and ends after the user has disconnected from the application. One of the biggest challenges for handling two-tier and n-tier applications is managing user sessions. Generally speaking, the server-side components of these applications have to be able to handle hundreds of user sessions at one time.

Session state is a snapshot of all of the data in memory for a particular user session. If you can save the state for a session somewhere (for instance, in a database, on disk, or in a browser cookie), an application will then be able to safely remove that data from its memory in order to make room for another session. Later, that server component can read the old session state information from its storage location, place all that data back into memory, and continue the session as if nothing happened.

Exam Watch

The MCSD 70-300 exam requires you to understand the various ways application state may be stored in a distributed application environment, such as how application state should be stored for COM+ components.

Let’s assume you are developing a web-based e-mail system. Your application will be composed of one database, one web server (running your custom-developed ASP.NET application), and potentially dozens or hundreds of client machines using your application through a web browser. To keep this example simple, let’s assume that there will be only one server component available to respond to the user requests. So, if there are ten users currently using your web-based e-mail application, that single server component has to be able to receive and respond to requests from all of the ten clients at once.

Keeping the session state in memory for ten clients at once is not a big strain on resources. Assuming your e-mail application will ever need to keep only 1KB of data in memory on any particular user, ten sessions would mean 10KB of server memory used. These days, when servers regularly exceed 1GB of memory, 10KB will have no noticeable effect on server performance.

But what if user sessions take up 30KB of memory each, and your application might need to support 4,000 users at once? That would translate to over 100MB of memory in usage. That type of memory usage can have a serious negative effect on application performance. This situation is also not very scalable—any further increase in the number of concurrent users or the size of the data being kept inside the session state could cause the application significant problems.

There is another reason to support the idea of saving session state somewhere other than in memory—object pooling. Object pooling is the concept that a group (or pool) of identical components will provide better overall application performance than just having one component handle all the user requests by itself. For instance, if you created a pool of five identical e-mail application components running on the server to handle client requests, these requests will no longer need to line up waiting for the one component to be free. It’s the same concept as that where having five open tellers at the bank is faster for customers than just having one open teller. If you get one guy who wants to open a new account, taking up ten minutes or so of the teller’s time, everyone else in line suffers.

The reason why saving session state outside of memory helps with object pooling is that clients can then be serviced by any available component, instead of having to wait for one particular component to come free. If the session state data (or information on where to find it, such as a session ID) is submitted with each request, any component will have all the information it needs to resume the session right where the last component left off.

Scenario & Solution

To store a small amount of noncritical user data in an ASP.NET application,…

Use browser cookies.

To store data that rarely changes in memory so that all sessions in an ASP.NET application can have quicker access to it,…

Use a Cache object.

To handle more than just a few concurrent users in your ASP.NET application,…

Do not use the Session object.

To store data that rarely changes in memory so that all applications running on the server in ASP.NET can have quicker access to it,…

Use the Application object.

To store dynamic ASP.NET web pages as static pages so that they don't have to be recreated for every call,…

Use a page output cache.

To store parts of dynamic ASP.NET web pages as static so that they don't have to be recreated for every page that uses them,…

Use a page fragment cache.




MCSD Analyzing Requirements and Defining. NET Solutions Architectures Study Guide (Exam 70-300)
MCSD Analyzing Requirements and Defining .NET Solutions Architectures Study Guide (Exam 70-300 (Certification Press)
ISBN: 0072125861
EAN: 2147483647
Year: 2003
Pages: 94

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