Identifying
the Navigation for the User Interface
Identifying
Input Validation Procedures to Integrate into the User Interface
Evaluating
Methods of Providing Online User Assistance
Establishing
Appropriate Types of Output
Grouping
Data into Entities by Applying Normalization Rules
Choosing
a Foreign Key to Enforce a Relationship Between Entities to Ensure Referential
Integrity
Specifying
Relationships Between Entities
Identifying
Business Rules that Relate to Data Integrity
Incorporating
Business Rules and Constraints into the Data Model
Identifying
the Appropriate Level of Denormalization
Defining
the Attributes of a Data Entity
Developing
a Database That Uses General Database Development Standards and Guidelines
Evaluating
Whether Access to a Database Should Be Encapsulated in an Object
Designing
the Properties, Methods, and Events of Components
· The Three Tracks of Solutions Design
· Designing a User Interface and User Services
· The Significance of Metaphors
· The Value of Prototypes
· Developing Data Models: Database Design Activities
· Synchronizing and Coordinating the Three Tracks of Solutions Design
· Deriving the Physical Design
This chapter takes you through the Solutions Design model, and shows how it works with the Application, Team, and other models in the Microsoft Solutions Framework. We’ll discuss issues dealing with the conceptual, logical, and physical design of an application. We’ll also discuss user and programmatic interfaces, which are used by the applications and components you create.
Focusing on the design perspectives of the Solutions Design model, we’ll discuss data model development, and discuss issues dealing with database design. Because most applications running on Windows access data in some way, this is a particularly important topic.
Business solutions are based on the needs of customers and users. Solutions Design is a valuable model that provides different perspectives on how to design a business solution, and is essential in designing component-based solutions. As we’ve seen in previous chapters, the Solutions Design model is made up of three separate views:
1. Conceptual design, which identifies an application’s requirements through specifications and usage scenarios
2. Logical design, which maps these requirements to abstract business objects and the services these objects need to provide
3. Physical design, which maps the business objects and services to physical components
Although information from one
perspective is applied to other views, it’s important to remember that these
aren’t stages with clear cutoff points. Remember though, that you should
always start with conceptual design and then proceed through the other design
views, these perspectives will often overlap, and you may find the need to
return to a previous perspective. As you’re coding on one component of your
application, you may still be identifying requirements for another component in
an application. This is a benefit of the model: it is flexible and doesn’t
force you to complete one step before proceeding to another step.
The conceptual design process is made up of several tasks, which are used to determine and validate user needs and perceptions of what the application should be. These tasks consist of identifying users and their roles, gathering input from users, and validating the design. As we saw in Chapter 9, this includes creating user profiles, data gathering techniques, and documenting usage scenarios. Through these various tasks, you’re able to acquire, document, evaluate, and validate the user’s vision of the completed application.
The information obtained through conceptual design, that is used to create usage scenarios, is passed forward into the logical design of the application. Through this perspective, the structure and communication of elements in the solution are laid out. Elements like the user interface, logical databases, objects, and services are also identified and designed. The tasks that make this possible consist of identifying business objects and services, defining the interfaces, identifying business object dependencies, validating the logical view, and revision and refinement of the design. Each of these tasks is essential for the logical design to be completed, so that information from the design can be passed to the physical design.
The first of the five tasks in logical design is identifying business objects and services. Business objects are abstract representations of real-world things or concepts (such as orders and customers). You can consider something to be a business object if one or both of the following is true:
1. It is something (or someone) the system is required to know about.
2. It is something (or someone) the system gets information from, or provides information to.
Business objects are essential because they define what
data will appear in the finished application.
The second task of
logical design is defining the interfaces to be used in the product. When
defining interfaces in the logical design, you aren’t designing a user
interface that the end user interacts with, filled with buttons and textboxes
and so forth. Instead, you’re outlining what’s required to call on a
particular service. Defining an interface requires listing a statement of
preconditions and conventions (syntax, and input and output parameters) needed
to call the service. In doing this, you define what one component needs to do to
call on the services of another particular component.
The third task is
identifying business object dependencies. When one business object calls on
services in another business object, this is called a business object dependency. In other words, one business object
depends on the services and existence of another business object. For example,
let’s say you were designing a database application for a credit card company.
When a customer buys a product, the amount of the sale needs to be deducted from
their credit limit. This means the sale depends on the existence of the customer
account in the database. If the customer didn’t exist, then the sale
couldn’t be deducted from the credit limit.
The next task is
validation, where the work done to this point is compared to the conceptual
design. This ensures that the logical design still matches the requirements in
the usage scenarios. If these requirements aren’t met, then the logical design
is considered invalid.
Finally, revision and
refining of the logical design deals with any problems, and improves the design.
This can occur several times before the work performed in the logical design
perspective is applied to the physical design of the application. Through these
multiple iterations, any problems with the design can be hammered out. This
keeps errors in the logical design from being passed on to the physical design,
where they could adversely affect the finished product.
Physical design is
where the business objects and services defined in the logical design are mapped
to actual components that make up the software product. These abstractions of
business behavior are transformed into a design on how the system will actually
be implemented. While the conceptual and logical design perspectives are
technology- and vendor-independent, physical design applies the abstractions in
logical design to the physical constraints of technology. How the system is
implemented and how it will perform are both issues of this perspective.
In physical design,
business objects and their related services are mapped to physical components.
Components are created using development languages like Visual Basic, Visual
C++, Visual FoxPro, and Visual J++. In creating components, you encapsulate one
or more services into
1.
an executable, which has the file extension of .EXE
2.
a dynamic link library, which has the file extension of .DLL
Because these services
are encapsulated into the component, you need a way of accessing them. Services
available from components are accessed through programmatic interfaces. Using
standards like COM, DCOM, or ActiveX, you create one component that calls upon
the services of another component. The calling component is called a consumer,
because it consumes the services supplied by the other component, which is
called a supplier.
Components can be
reused in other projects that require the same functionality. For example, if
you had a component that calculated sales tax in one program, you could use the
same component in other programs that required the same function. This saves you
the trouble of having to rewrite the same code over and over in different
projects, or different areas of the same program.
In creating this network of consumers and suppliers of services, the Solutions Design model incorporates the use of the Application model. As mentioned in Chapter 6, Solutions Design ties together the Process, Team, and Application models. We’ll discuss Team roles in Solution Design later in this chapter, and we’ve discussed the Process model in previous chapters. When it comes to the creation of components, the Application model is valuable.
The Application model, which is also known as the Services model, organizes an application’s requirements into specific services. Generally, the requirements of an application fall into one of three tiers:
1. user services, which are associated with the user and/or programmatic interface
2. business services (and other middle-tier services, which can include such things as graphic services), which are associated with business rules and logic
3. data services, which are associated with the data accessed by your application
It is through the user services tier that the end user interacts with your application, through a user interface and/or programmatic interface, which is the user services tier. Through this tier, the functionality of application sequencing and display are handled. Business services, and other middle-tier services, control sequencing and enforce business rules and processes.
Data services store and manipulate the data, and handle data operation transactional integrity. It’s through the Database Management System (DBMS) in the data services tier that Create, Delete, Read, and Update services take place. When data is passed back up the tiers, business services transform the data into information, so that user services can properly display or use it.
The user interface provides the end user with the ability to view and manipulate data, through units of application logic. It is associated with the user services tier, which is also known as the presentation layer. The user interface can be an executable program that a user starts on a workstation or a separate component that’s placed on a container object like a Form. A Form is a container for other controls, which appears as a window to the end user when your program is compiled. For example, you could place an ActiveX control on a Form, which might allow the end user to view or manipulate data in a database. As we’ll see later in this chapter, there are many different controls you can use in a user interface for navigation or interacting with data.
The middle tier of the Application model is comprised of a number of services, but is primarily associated with business services. Business services apply business rules to tasks that an application performs, and are used to enforce transactional integrity, business rules, and control sequencing. For example, let’s say you were designing a banking program that allows people to withdraw money from an account. Before the money can be withdrawn, the application checks to see if there is enough money in the account to make the withdrawal. If there is, the transaction continues; if not, it is cancelled. In such an application, there is a business rule of needing to have more than the amount withdrawn. When business rules are added to a program, they are added at this layer.
The middle tier is also known as the application server tier. It is the layer between the user interface and a database. Generally, this is where a Web server will reside in Internet applications, and where business objects (COM components that retrieve and process data) are instantiated. Because business rules change more often than the actual tasks a program needs to perform, they are prime candidates for being a component of a program. By having such rules incorporated into components, the entire program doesn’t need to be changed, just a component of that application.
Most applications on the market today need to access some form of data, whether it’s in a database or some other data source. This makes the data services tier of the Application model important to most of the products you design. The data services tier is also called the data source tier, and is responsible for defining, maintaining, and updating data. It provides Create, Read, Update, and Delete services, as well as such retrieval logic as order and joins. This allows business services, which is the consumer of data services, to be shielded from having to know where data is located, or how to access and implement it.
When a request is made for data, data services are responsible for managing and satisfying the request. This ability to manage and satisfy requests can be implemented as part of the database management system (DBMS), or as components. The data is then passed back up to the middle tier, which transforms the data acquired from data services into meaningful information for the user. The data is then presented to the user through the user interface.
Imagine going to a library, and finding that the building has no windows or doors. While the books you need are contained inside, along with librarians and services for information, someone forgot to design a practical way of getting to these resources. Sound silly? Perhaps, but this scenario isn’t unheard of in application design. Teams can spend considerable time creating a functional database, and applying business processes to various components but if the product has a poorly designed user interface, it isn’t functional. The user interface is the way end users access information through your program. Having a poorly designed user interface is like building that inaccessible library; the system may technically work, but no one can access it.
In designing the user interface services for your application, it’s important to keep the end user in mind. The user should always feel in control of the application, rather than feel that the application is controlling him or her. The interface should follow the design methodology that’s common to Windows applications, so that if the user has experience with one application, they can quickly navigate and use the software you’ve designed. This means setting up menus, controls, and other forms of navigation in a fashion that’s similar to other Windows programs on the market.
If the user has difficulty with a control or feature, you should provide online user assistance. This includes implementing such things as ToolTips, help files, and status bars in your application. This enables the user to solve problems with the help features in your program, rather than bothering a help desk every time they experience difficulties.
It’s important to remember that the user interface is the “face” of your application. This is what the user sees, and is really an interface between the human and the computer. As such, you want to put your best face forward. It’s important to create an esthetically pleasing interface for the user, one which is both functional and friendly. For example, color schemes should not be hard on the eyes, navigation schemes should be consistent, and the controls and menu design should be intuitive. In addition, the controls you choose should be appropriate to the functions they provide. The design of your user interface and user services are the most visible display that you’ve designed a quality product, and helps to ensure the overall success of your project.
On the Job: It’s important to have a good design for your user interface the first time you release your product. Make sure the user interface is set up the way you want it, so you don’t need to drastically change it in future releases. If you have a peculiar way of navigating or the menus are designed differently from other Windows products, users may grow used to these peculiarities. When you try to correct the design in later releases, they may find it difficult to adjust to the new interface.
To work with a user interface, you need a way of accessing and navigating between different objects, like Forms and controls. Without a consistent and effective way of getting from point A to point B in a program, users are stuck looking at a single screen. Implementing navigation into your application is done with controls and menus. After adding these to a Form, code is then added to the control or menu item. Then a user is able to navigate through an application, and get to other Forms, dialog boxes, or applications.
Menus are common to user interfaces, with a menu bar displaying across the top of an application window, below the title bar. Menu bars contain menu titles, which identify groups of commands, called menu items, that have similar purposes. For example, under a Help menu there would be help items, and items under a File menu would do things like open and close files. When you click on a menu with your mouse pointer, a drop-down menu appears containing these menu items. Upon clicking on a menu item, program code associated with that item is executed.
What your menu bar and drop-down menus contain is highly dependent on the functionality of your application, and how the user will interact with your application. For example, if your interface doesn’t use multiple windows, you wouldn’t have a Window menu title. Similarly, if your application doesn’t require users to insert graphics, text, or objects into the interface, you don’t need an Insert menu title in your title bar. In determining the menu items that will appear in the drop-down menus, determine what commands will be provided to the user, and then organize them accordingly.
While the content of the menu bar and drop-down menus varies from product to product, there are certain conventions that you should adhere to. File should always be the left-most menu title on your menu bar, and contain the commands that allow the user to exit the program, close windows, and open or create new files. If the application requires editing features (such as cutting, copying, or pasting items from the clipboard), you should place the Edit menu title directly to the right of the File menu title. The right-most menu title on your menu bar should be Help, which contains online user help. Other menu titles appearing on the menu bar would be placed between these.
Command buttons are another common element of a user interface. They have the appearance of push buttons, and are used to begin, end, or interrupt a process through programming code that is added to the button. In other words, when the button is clicked, the code associated with that event is executed. In terms of navigation, you could associate code with the button to open a Form, so that users can move from one part of the application to another.
While it is important to provide users with the ability to invoke the commands associated with menu items and command buttons, it is equally important to know when to prevent a user from invoking a command. For example, let’s say you created a user interface that took a user step-by-step through the process of entering customer information. On the user interface, you placed command buttons with the captions Back and Next on them, which respectively moved the user back to a previous step or on to the next step. If the user were on the first step in the process, he or she wouldn’t be able to move back. As such, your Back button should be disabled or invisible. When a button or menu item is disabled, it appears grayed-out and nothing will happen when the user clicks on it. When it is invisible, the button or menu item doesn’t even appear on the screen. This keeps a user from trying to execute code associated with a menu or control, when you don’t want them to. By not implementing this into your design, users may think something is wrong with the control, or it may cause an error when improper code is executed.
When navigating to the objects on your interface, different users will use different methods. One user may use a keyboard, while another uses a mouse, while still another uses a pen. With these devices, the user is able to do the following:
· identify an object, through such things as ToolTips, which are discussed later in this chapter
· begin, end, or interrupt processes associated with objects through programming code.
· access an object, to do things such as enter text into a TextBox object.
Because different devices will probably be used to navigate your interface, it follows that this can affect how you will design it. You need to know what these devices are, and how they’ll be used to interact with your application.
Microsoft considers the mouse the primary input device for applications running under Windows. When a user moves the mouse, a pointer moves in the same direction on the screen. This allows the user to move the mouse up, down, and sideways to navigate to your menu and other objects on your interface. When the user reaches an object they want to access, the buttons on the mouse device are clicked or double-clicked. This invokes the click event of the object, so that code associated with that event is executed.
Using a mouse takes some coordination. New users often have trouble moving the mouse on their desk to get the pointer on the screen to go where they want. Because of this, new users will often use a mixture of mouse and keyboard input to get your application to do what they want.
Trackballs are another common input device, but are considered a mouse. While a ball located under the mouse device rolls over a pad, moving the pointer on the screen, a trackball looks something like a mouse turned upside down. The trackball device remains stationary on the user’s desk, and the user rolls their hand across a ball on top of the device. This results in the same behavior as when a mouse is moved. Buttons located on the trackball device allow clicking and double-clicking.
Pens are devices that allow the user to navigate as they would with a mouse, but also allows them to draw and write on the screen. When navigating, the user moves the pen without touching an input surface, and a pointer moves across the display screen. When used as a writing or drawing tool, the pen touches the input surface and this causes an action called inking. Inking is where the pen’s input causes lines to be drawn on the screen. While the pen allows the user to navigate as they would with a mouse, Table 11-1 illustrates how the behavior of the pen is different from that of a mouse. No clicking or double-clicking is used, because pens don’t come with buttons that provide the same functionality as a mouse.
Action |
Description |
Pressing |
Pressing the tip of the pen to the input surface identifies an action, which is similar to that of a mouse press. |
Tapping |
Pressing the tip of the pen on the input surface and then lifting it without moving the pen, results in an action identical to clicking button 1 (e.g., left mouse button) on a mouse. This is usually used to select an object, activate a button, or set a text insertion point. |
Double-tapping |
Tapping the pen-tip twice in rapid succession results in an action identical to that of double-clicking button 1 on a mouse. |
Dragging |
Pressing the tip of the pen on the input surface and moving the pen, you are able to perform one of two actions: dragging or drawing. During inking sessions, you can move the pen to draw or write on the screen. During non-inking sessions, you can use the pen to drag objects in a fashion equivalent to dragging an object with a mouse. |
Barrel tapping |
Holding down the barrel button of the pen while tapping has the same effect as if you were using a mouse and clicking mouse button 2. |
Barrel dragging |
Holding down the barrel button of the pen while dragging has the same effect as if you were using a mouse and dragging with mouse button 2. |
Table 11-1: Behavior of a Pen, and How It Is Similar to a Mouse Device
Pen devices are often used in settings that need the functionality of a drawing utensil and the navigation abilities of a mouse, such as in Graphic Art or Advertising departments. Because the pen is used as both a pointing device and a drawing or writing tool, there may be times when the user will need to switch between these operations. In other words, while they are drawing something in a window of your application, they may need to point to a menu or object on the screen. Because of this dual functionality, you should incorporate some way of switching modes of operation for the pen in your software. To do this, you could use timing, so that if the user holds the pen in the same spot for a predetermined time, it will switch modes. You could also place a button on the toolbar or a shortcut key that allows the user to change whether the pen is used as a drawing tool or pointing device.
Each of the devices we’ve discussed requires some sort of visual interaction. If the users of your application include visually impaired or blind users, they won’t be able to see (or may have trouble seeing) pointers appearing on the screen. In such cases, a keyboard will be the primary method of navigation.
This isn’t to say that keyboard navigation is used only by the visually impaired or blind. After the mouse, a keyboard is the second most common device used for navigation in Windows applications. The keyboard allows a user to move from object to object and across fields of text in an application.
By pressing the appropriate keys on a keyboard, users are able to move about the window, and/or jump from one object to another. On a keyboard, there are four arrow keys and the Tab, Home, End, Page Up, and Page Down keys. These are called the navigation keys. By tapping one of these keys, you move an increment. For example, by pressing the right arrow key, the insertion point moves one character to the right. If you press a navigation key and the Ctrl key simultaneously, this increases the increment. Pressing the right arrow and Ctrl key at the same time, moves the insertion point one word to the right.
In applications that use TextBoxes, control buttons, and other objects, users can navigate from one object to the next by pressing the Tab button. The order that determines which object you move to when pressing the Tab button is determined by the Tab Index property of that object. When you put a control on a Form, the Tab Index is set in an order corresponding to the order that the controls were placed. For example, let’s say you put a command button, a TextBox, and another command button on a Form. By default, when the user pressed the Tab button, they would move from the first button to the TextBox and then to the final command button (i.e., the order in which these objects were placed on the Form). To change the Tab order, you would change the value of the Tab Index. The value of the Tab Index starts at zero, so the first object you want the user to start from would have a Tab Index of 0. The next object they move to when pressing Tab should have a Tab Index of 1, and so on.
When setting the Tab order of objects in an application, you should set the Tab index of objects to correspond to the way a person reads. Since people who read English read from top-to-bottom, and left-to-right, the object at the top left of your application interface should start the Tab order. The last object you want the user to Tab to should have the highest Tab Index value.
You can also aid keyboard users by implementing access and shortcut keys in your application. Access keys allow a user to move to a particular menu item or object by holding down the Alt key simultaneously with another key. You can tell if a menu item or title has an access key used, because the letter for that access key (the one you press at the same time as the Alt key) appears underlined. For example, to access the File menu, you would know to press the Alt + F keys at the same time. This opens the File menu, allowing you to move to a menu item by using navigation keys or another access key. Shortcut keys are different from access keys, as you don’t need to navigate to a menu item to execute it. By holding down the Ctrl key and a specific key, you can invoke a command and execute code automatically. As we’ll see later in this chapter, access and shortcut keys are commonly used by experienced users of an application.
Exercise11-1: Identifying Navigation for a User Interface
Baltimore Access Technologies is a company that provides applications for the blind and visually impaired. They have asked you to design the navigation for the user interface of a database application that will be used by their clients. The application will be a Wizard, moving from one screen to the next. Audio instructions will be provided on each screen. Based on the user needs of this application, you will need to determine what types of user navigation will be appropriate.
1. Determine what tools for navigation will be used. Because the users will be blind or visually impaired, you could dismiss any tools that require visual interaction. For example, the mouse and barrel pens would be dismissed for navigation. Write each of the appropriate tools on a piece of paper.
2. Because you will be using a keyboard as the navigation tool, determine what forms of navigation will be appropriate. List each of the navigation methods that would be appropriate.
3. Determine which navigation methods will be appropriate, based on the type of application used. While a keyboard can access menus and menu items, such navigation methods may not be appropriate for the Wizard application that is being developed.
4. Review the navigation methods you’ve listed, and compare them again to the user and application requirements of the case above. If they meet the requirements, you’ve identified which navigation methods can be used.
No matter how intuitive you make your interface, one fact remains: people are unpredictable and imperfect. Users may make all sorts of mistakes. They can easily put the wrong information into a field. It’s easy to input a customer’s last name in a TextBox designated for customer first names, or leave an address field blank, making it impossible to ship orders or contact them. Worse yet, entering data into the wrong field could lock up your program, which could happen if a user entered a customer’s surname into a field that expected numerical input. Just imagine your application trying to add sales tax to the data input of “John Doe”.
Input validation procedures ensure that the correct information is put into fields, and fields that require information aren’t left empty. Such procedures check the input entered into TextBoxes and other fields before they’re processed. These procedures can be added to the object itself, and check input as it’s typed, or added to an OK button (or similar command button) that the user has to click on before the data is processed. If the information is not what’s expected, then a warning—such as a message box—should appear informing the user of the error. This provides as a failsafe, keeping incorrect or insufficient data from being saved to a database, or erroneously processed.
Exercise 11-2: Identifying Where Input Validation Procedures Should Be Used
Hard Exam Systems takes calls from people who want to become Hardly Certified Professionals. The exams they book usually cost $100. As a promotion, they offer coupons worth $100. Some exams cost more than others, so two coupons occasionally cover the cost of a single exam. At no time are more than two coupons allowed to be used. The order form interface is shown in the screenshot below. Users of this interface either type in an ID number or the customer’s first and last name to bring up an existing account when the OK button is clicked. ID numbers start with the first three letters of the customer’s last name, followed by a six-digit number. They then type in the exam number the customer wishes to take, which automatically generates the exam cost. The cost, minus the value of the coupon, is shown automatically in the total cost field. What input validation would you add to this screen?
Illustration 1
Looking at each individual field, and the criteria given in the explanation above, try to determine what type of input validation is required. On a piece of paper, write the field and the input validation it will have. Follow the steps below to determine what input validation is required for necessary fields.
1. Determine what conditions must be met for certain fields. For example, the first three fields (TextBoxes) have a common use.
2. Determine whether certain fields should reject certain types of input such as strings, integers, and currency.
3. Determine if any fields shouldn’t accept any type of input. Some fields only return information, and shouldn’t accept any input.
4. Determine which fields (if any) require input in a specific format. For example, in some applications, certain fields, such as zip code or postal codes, require a specific amount of information, such as five numbers for a zip code.
5. Determine what ranges of numbers are acceptable for certain fields; over a specific value or under a specific value could cause errors.
1. The first three fields have a common use, and require a related input validation. The user either enters the customer’s ID number or their first and last name, then presses the OK button. This means that the OK button should check to see that the first and last name fields have input and the ID number is empty, or vice versa. If both have input, the wrong account could be brought up, and an error would result.
2. None of the fields require input validation on the data type used in the field.
3. The last two fields, exam cost and total cost, shouldn’t accept input. The data is entered in these fields by the application.
4. The exam number field requires input in a specific format. If users entered more than three letters of the customer’s last name, or more than six digits after these letters, a warning should result. The wrong input could result in an error.
5. The coupons field can’t accept more than two or less than zero coupons.
Online user assistance is the answer to a user’s frustrated cry of “Help!” and an important part of software product design. There is nothing more frustrating and overwhelming to the user of a new application than trying to understand how to get your program to perform necessary actions, what certain buttons are for, and why a feature is even included in the software. Online user assistance allows the user to get the answers they need, without having to pick up a book or the phone.
You can provide many types of online user assistance. Some online help displays information automatically (based on the context of commands), while others require the user to make an explicit selection before the information is presented to them. Regardless of the type of user assistance you provide, the information should be presented in a simple, efficient, and relevant fashion, so that users won’t get lost in said the instructions. Once you’ve dealt with computers for any length of time, it’s easy to forget that not everyone knows as much as you do. Because of this, it’s vital that you relay the information in a clear and concise manner.
In evaluating the methods of online user assistance, it is important to know what information to include and what questions need to be answered. . For example, if a user were to move the mouse over a particular object, you wouldn’t want detailed instructions for that object to appear. In such a case, a brief explanation of what that object is, or what is used for, would be all that’s necessary.
In this section we’ll discuss three common types of user assistance: status bars, ToolTips, and Help files. These are basic methods of online help that you’ve probably seen in a number of applications. In covering them, we’ll discover how, where, and why they’re used, as well as discuss some common guidelines for what information should be contained in them.
You’ve probably seen status bars when using Microsoft applications, such as Word, Internet Explorer, or Windows Explorer. These are bars that reside at the bottom of the user interface, and contain information about selected objects, their context, or the status of an operation. Being a contextual form of user assistance, status bars answer such questions as what an object is, why that object might be used, or how your application is proceeding with a current operation.
Status bars can be used to display descriptions of a command or object. As illustrated in Figure 11-1, if you used your mouse to point to the Select All command in the File menu of Windows Explorer, the status bar would tell you this command “Selects all items in the window.” If the object or menu item contained additional commands, you should use the status bar to explain the type of commands contained in that menu or object. For example, in a word processing application, if you moved your pointer over a Format menu, your status bar should display something like “Contains commands for formatting text.”
Figure 11-1: Status bars provide contextual user assistance
As its name indicates, status bars are also meant to show the status of a current operation. For example, if you had a program that downloaded files from an Internet server to your workstation’s hard drive, the status bar could display the status of your download. In this case, when your application is downloading the third in a series of ten files, it might state “Downloading 3 of 10 files.” In showing the status of an ongoing process, you can also design the status bar to include a progress indicator control, or similar methods of providing feedback. This gives the user a graphical display of how much of a file has been saved, printed, or whatever the current operation is. While such information can be provided through dialog or message boxes, status bars allow the user to see how the operation is progressing, without having the current window obscured.
It’s important to provide constructive information in your status bars. This means not only providing descriptive information, but also explaining why a particular command is unavailable or disabled. If a user is attempting to use the Paste command in the Edit menu of your application, they may wonder why it appears grayed-out. In such a case, you could provide status bar information saying “This command is not available because no items have been Cut or Copied.” By providing such messages, you will enhance the user’s experience with your application, and save them from their own mistakes of overlooking steps when performing a task.
When writing status bar messages, you should avoid any jargon. There is nothing worse than help text that contains words a user may find difficult to understand. Remember what it was like when you first started with computers. Don’t use words that only a programmer or sophisticated user would understand.
On the Job: A good approach to writing online help is to write it as if it’s for a specific person. Think of a person you know who has little knowledge of computers or applications, and then write your text as if you were talking or writing to that particular person. Once you’ve approached it in this manner, then start your text with a verb and describe the action your command performs. For example, “Deletes the selected text.”
Because the status bar is located at the bottom of your user interface, and most (if not all) of your toolbars, menus, and other commands will be at the top of the interface, you should consider using a status bar as a secondary means of help. You should never use status bars as the sole or primary means of user assistance. Since the status bar is so far away from such commands, users will often not notice information displayed in the status bar. As such, you should implement other forms of online help, such as ToolTips.
ToolTips are small, colored boxes containing information that appears when your mouse pointer rests on an object. You’ve probably seen a ToolTip when you rested your pointer on a button in a toolbar, and the name of that control appeared in a small colored box. This is the most common use for ToolTips, although they can be used for any control. For example, you can use ToolTips to display navigational information, or indicate what action a particular control would take if it were clicked. As shown in Figure 11-2, you can use ToolTips to inform the user that clicking a Back button will take them to a directory they were previously in.
Figure 11-2: ToolTips are boxes containing information that displays when a mouse pointer rests on a particular object
You can add ToolTips to your user interface by using the standard toolbar control in Visual Basic or Visual C++. In using the toolbar control, support for ToolTips is automatically provided. You can also use a ToolTip control for use with other controls added to your user interface.
If you want to make your own ToolTip control, you should adhere to the way ToolTips are displayed with the standard control. ToolTips should display when the mouse pointer rests for a short period of time on a control, and should display after the pointer. When the user moves the pointer off the control, or after a specified timeout, the ToolTip should disappear. If the user moves the pointer onto another control, the first ToolTip should disappear and be replaced by the ToolTip of the new control. Be sure to follow the standards used by other applications so users will have better access to your ToolTips.
When people hear the words “user assistance,” they often think of Help files. Help files contain organized information that is displayed when the user presses F1, selects a Help feature from the Help menu, or performs another action that invokes a Help display. When incorporating Help files into an application, you provide the user with a source of reference or online documentation. This can serve as a user’s guide or documentation of the software’s features, containing text and graphics to enhance the user’s experience with your product, and lower the need for users to call help desks for assistance.
There are two kinds of Help files you can use for your software product: standard (which has the extension .hlp) and HTML (which has the extension .chm). Standard Help files are stored in a binary format, and are compiled with a special compiler. HTML Help files are created using the Hypertext Markup Language, using a text editor (like Notepad) or a graphical editor (such as FrontPage 98). Once the HTML document is created, a special compiler is used, such as the HTML Help Workshop that comes with Visual Studio 6, to convert the document into an HTML Help file. Once you’ve created your Help file, the file must then be associated with your application through whatever development program (e.g., Visual Basic or Visual C++). This is done by setting the Help properties of your application, and can be done at design-time (when you’re creating your application) or programmatically.
When designing Help files, and/or the interface they are to be displayed in, you should follow certain conventions and standards. These not only explain how to design the interface used to display your Help files, but how the information should be presented. By providing the user with Help files in a manner consistent with other Windows applications, you keep them from requiring assistance on how to use the Help features in your product.
If you wish to design an interface for your online Help, you should include features similar to those in Figure 11-3. While this figure shows two different interface designs, upon closer inspection you’ll notice similar features in each. The Help file is displayed in a main help window, and not in pop-up window. The top of the interface has a menu bar with File, Edit, and Help entries, as well as toolbars and commands for navigation and printing topics. “Bookmark” or “Favorites” features are also provided, allowing a user to mark particular topics that he or she uses frequently. Each interface also provides a method of accessing the Contents of the Help file, which list topics as a Table of Contents would in a book. In addition to these standard features, other functions may be added to the interface to assist the user in navigating to different topics.
Figure 11-3: Two examples of common interfaces that display Help files
When writing Help files, it is important to include a title for the topic. A title is used to identify the topic, and provides a landmark in Help for locating particular topics. Any title you choose should match titles used in the Topics section of your browser.
Hyperlinks can also be used in your Help file, to allow users to jump to other Help topics or provide additional information. When the user clicks on a hyperlink, information in the window changes to another topic, a topic in another Help file, or another area in the same topic. Hyperlinks appear as underlined text when the Help file is displayed, but you can also use graphics or buttons to provide the same functionality.
Exercise 11-3: Evaluating Methods of Providing Online User Assistance
Hard Exam Systems uses the GUI shown in the graphic below for booking exams. New employees are having trouble understanding what to do on the screen. For example, they don’t realize they should enter either the ID number or the first and last name (not both) to specify a customer account. They also don’t realize what the OK button is for (to bring up the user account after entering either the ID number or customer’s name). The two arrow buttons (for navigation) are another source of confusion. Truly baffled users would appreciate lengthy instructions on how to use the GUI. The company would like you to determine what forms of online user assistance to provide.
Illustration 2
1. Determine which type of online user assistance can best provide a brief description. This can be used to explain how the navigation buttons function.
2. Determine which type of online user assistance can provide brief instructions on how to use fields. These can be used to briefly explain what users should do. What is a drawback of this type of assistance?
3. Determine which type of online user assistance will provide longer instructions, and detailed help. Where should the menu to access this Help reside on a menu bar? What function key could be used to access it?
1. ToolTips is the better choice for explaining the purpose of the navigation buttons. It allows users to discover their function by resting their pointer on a button.
2. A status bar could be used to provide brief instructions. When the user clicks on either the ID number field or either of the name fields, an instruction such as “Enter ID or Name, then click OK” could appear. A drawback to this type of assistance is that status bars are on the bottom of the GUI and may be overlooked.
3. Help files can be used to provide detailed help. The Help menu should be placed rightmost on the menu bar. F1 could also invoke the Help file.
When computers were first becoming commonplace, they were predicted to save trees by the forest-load. After all, with data being stored electronically, there would be no need for things to be filed away on paper. As the sales of printers and plotters will testify, paper is still one of the most common forms of output in desktop and distributed applications.
When creating applications with Visual C++ or Visual Basic, you can implement a standard Print dialog box into your application. From information obtained from the operating system your application runs on, it can determine what printer to print a file to. It also allows the user to choose how many copies to print, format, and which pages. Code is added to the dialog box to print in the format selected.
Output isn’t limited to printers. In designing your application, you need to determine whether output needs to be sent to printers, routed to email, and faxed. You also need to investigate whether output from your application should be saved as a particular file type. For example, if output from the application would then be used by an off-the-shelf program, such as Microsoft Excel, you would need to save the output as an Excel spreadsheet. If output were to be displayed on the Internet, you would save it in an HTML file format. In designing your application, it is important to discuss how output from your program will be used, and what formats will be required.
Exercise 11-4: Establishing Appropriate Types of Output
Baltimore Access Technologies has a staff of 100. Fifty of these people are either blind or visually impaired, and “read” information through a Web browser on computers with voice synthesizers. Thirty of the employees are often on the road, and connect remotely to the network through the Internet. The remaining 20 staff members prefer to read information on paper printout, and require copies of documents to be filed on cabinets. A copy of the information needs to be archived on the intranet server. What types of output are appropriate for the application you’re designing?
1. The needs of the user, and those of the application, determine appropriate types of output. Determine what special needs must be met by your application.
2. Determine what types of output will address the needs of users.
3. Determine what special features can go into your application to address these needs.
1. Some users are connecting remotely, some users are visually impaired or blind, while others require hard copy that can be filed and soft copy to be archived.
2. HTML output could be used for both remote users, intranet archives, and blind/visually impaired users. Printer output will provide hard copies for filing. Audio files could be used, though they would take up more storage space than HTML.
3. Print preview and other print features, e-mail, browser functionality, and audio could be incorporated into the application.
A picture paints a thousand words, and therein lies the value of prototypes. Prototypes are used as mockups of what you propose the final product will look like. A prototype is a user interface with little or no code associated with the objects and commands of your interface. This allows end users, customers, and interested parties to have a visual representation of what you understand their needs to be and plan to incorporate into the user interface. Users and team members discuss elements of the user interface before the application is actually built. If any of these parties have a problem with elements of the user interface, they can bring them up during the discussion, allowing issues in the design to be addressed early in development.
As mentioned in Chapter 9, prototypes are used to validate application design. This enforces that the designer has actually understood what the business needs, as well as the needs of the end user. Because the user interface is how the end user interacts with the program, it is vital that any application you create has a good user interface. By demonstrating a prototype, you can say, “This is what it’ll be like,” and allow beta users to address what they love and hate about the interface.
In creating a prototype, you are basically building a smoke-and-mirrors version of your program. While it looks like an application, you don’t want to put very much code into it. After all, if the entire interface or parts of it are disapproved, you have to throw that out and start fresh. As such, you should only put the most basic code into it. Allowing the command buttons to navigate to other screens, or loading a canned graphic to show the results of a graph, will adequately demonstrate the functionality of the application without writing very much code. When creating a prototype, it’s important to remember that you’re building a mock-up of the application, and not the application itself.
If you don’t want to create a working prototype that has code written into it, you can still benefit from the simple display of what the interface will look like. You can create screenshots, print them out, or display them through a program like Microsoft PowerPoint, and allow users to view the proposed interface. By printing out the prototype, users can jot down their comments directly on the printout. However, no matter which method of demonstrating a prototype you use, you will almost always get valuable feedback from your intended audience.
On the Job: There have been more than a few occasions where a demonstration of a prototype meant the difference between landing or losing a software contract. When trying to pitch a business solution to a company, prototypes are great for demonstration purposes. Rather than proposing an application with a feature list, you can actually show them what they’re getting. By bringing printouts of the user interface, or a working prototype, you can quickly impress a client.
In constructing a prototype, your first consideration is determining what kind of prototype you want to create. Prototypes fall into two categories:
1. throwaway
2. evolutionary
A throwaway prototype is created for the sole purpose of getting feedback from users, and validating the design of the user interface. In other words, when you’re done with it, you throw it away. An evolutionary prototype is incorporated into the building of the actual product. This means you use the approved parts of the prototype as the user interface for the actual business solution.
Throwaway prototypes have virtually no code attached to objects and commands in the user interface. When a user clicks on a menu item, either nothing will happen, or a Form or pre-made graphic will appear. For example, let’s say you created a spreadsheet program. When you clicked a command button to transform figures into a graph, a simple graphic would appear. The prototype wouldn’t actually do any computations. Throwaway prototypes allow the user to see what the program is meant to do, but doesn’t actually do anything. After validating the design and getting the user feedback, the prototype is discarded.
Evolutionary prototypes usually contain more code than the throwaway type. This is because the team realizes they will build the actual program on top of the prototype. This isn’t to say they do loads of work writing code into the prototype, because any code written may be discarded if the prototype is disapproved. However, the evolutionary prototype often includes the basic code that’s easy to write and has little chance of being tossed away. Developers will often include features like Open, Close, and Exit that are basic to the operation of the application. There is little chance of such features being disapproved, and they will almost definitely be passed forward into the final product.
No matter which type you construct, it’s important to remember that you’re making a representation of the final product. As such, you apply the business requirements, user interface guidelines, and organizational standards that dictate the development of the final product. In other words, you follow the design as if you were creating the real thing. If security specifies that users shouldn’t be able to save data to their floppy, don’t display a Save to A: feature in the prototype. If organizational standards require a customer ID number for orders, show a field for this information on the user interface. If your prototypes are convincing, users can (and often do) think you’re showing the actual final product. They may get annoyed if their requirements seem to be disregarded in the prototype. It is vital to show an accurate representation of the final product through the prototype.
In the section on navigation, we discussed some of the ways in which you can establish appropriate and consistent use of menu-based controls. Menu titles and items should follow the layout used by other Windows applications, so the user isn’t confused by your menu layout. In addition, items should be placed under the appropriate menu title, so users aren’t constantly searching for an item.
Because a prototype is “smoke and mirrors,” you usually don’t need to apply programming code to the items appearing under menu titles. If a particular tool appears under the Tools menu title, you can have no code associated with that item, or have it open another Form that shows what the interface for that tool will look like. If you do attach code to a menu item, try to keep it as simple as possible. Remember, you may have to change that item, or throw out the interface once users have finished reviewing the prototype. The main point of using menus in your prototype is to show what the menus in the interface will look like, not to create the menu system for the finished product.
When users navigate from one Form to another, the setup of your menu should always be consistent. While some menu items or menu titles may not need to appear on certain Forms, those that do appear should be in the same place as other Forms the user has seen. For example, let’s say the first menu bar of your user interface has the following menu titles: File, Edit, View, Insert, Help. When a user moves to another window of your interface, the titles should appear in the same order, and not like this: File, View, Insert, Edit, Help. Mixing menu titles and items around is very confusing to a user.
Shortcut keys, which are also called accelerated keys, allow users to quickly access features of your product. Rather than having to navigate to a menu title, access the menu, and then select a menu item, users can press a combination of keys on their keyboard to access the same command. For example, let’s say you had an Undo feature under the Edit menu of your application. Rather than accessing this item from the menu, it’s common for applications to allow users to press the Ctrl key and Z key simultaneously. Ctrl+Z allows the user to undo their last action. This allows users who are more comfortable with their keyboards, such as power users, visually impaired or blind users, or users who grew up on DOS, to invoke commands without using the menu system, toolbars, or controls of your application.
Commonly used commands are prime candidates for shortcut keys, and they are easy to implement by using the properties of your control of menu system. Because it is easy to apply shortcut keys to commands in the user interface, you should consider implementing them in prototypes that evolve into the actual product. This keeps you from overlooking adding the shortcut key later, when code is being added to the user interface. When a shortcut key is applied to a menu item, the keys to use automatically appear to the right of the menu item. For example, a shortcut key to print would appear beside the menu item as Print Ctrl+P. This is useful in both throwaway and evolutionary prototypes as it shows the user that shortcut keys will be implemented in the final product.
To keep from confusing your users, you should use common
shortcut keys in your application, and not use those keys for invoking other
commands in your application. For example, Ctrl+Z is a common shortcut key to
undo a previous action in Windows applications. As such, you shouldn’t use
this combination of keys for other functionality in your application. Table 11-2
shows a listing of such common shortcut keys.
Shortcut
Key |
Description |
CTRL+C |
Copy |
CTRL+O |
Open |
CTRL+P |
|
CTRL+S |
Save |
CTRL+V |
Paste |
CTRL+X |
Cut |
CTRL+Z |
Undo |
CTRL+ESC |
Accesses the Windows Start menu. |
CTRL+F6 |
Displays the next child window in an MDI application. |
CTRL+ALT+DEL |
Reserved for system use. Examples of its use include bringing up the Close Program dialog in Windows 9x, and restarting the machine in DOS/Windows 3.x. |
Spacebar |
Equivalent to clicking mouse button 1. |
ESC |
Cancel |
F1 |
Display contextual help. |
Shift+F1 |
Display context sensitive help (i.e., “What’s This?” help). |
Shift+F10 |
Display pop-up menu. |
ALT |
Activate or deactivate menu bar. |
ALT+TAB |
Switch to next primary window or application, or bring up window to switch tasks. |
ALT+ESC |
Switch to next window. |
ALT+Spacebar |
Display pop-up menu for window. |
ALT+Hyphen |
Display pop-up menu for active child window in an MDI application. |
ALT+Enter |
Display property sheet for current selection. |
ALT+F4 |
Close the active window. |
ALT+F6 |
Switch to next window in an application (between modeless secondary windows and the primary window). |
ALT+PrtScn |
Capture a screenshot of the active image to the clipboard. |
PrtScn |
Capture a screenshot of the entire desktop to the clipboard. |
Table 11-2: Common Windows Shortcut Keys
Access keys are often confused with shortcut keys, but they are quite different. Access keys allow the user to access a menu title, item, or object by pressing the Alt key with another key. When an access key is applied to menu titles, items, and objects, the letter to press with the Alt key is underlined, such as File. In this case, you would press Alt+F to open the File menu. This allows keyboard users to quickly jump to this item without use of the mouse. In general, applications should be designed so that shortcut keys can be replaced by a sequential series of access keys.
In creating menu systems, it is easy to implement access keys by putting an ampersand (&) before the letter to be used as an access key. Due to this ease of implementation, you should incorporate access keys into the prototype. If they aren’t used, end users will usually jump at the fact that the interface doesn’t have certain letters underlined in the menu system. This gives an incomplete look and feel to the prototype, which is something you want to avoid.
Exercise 11-5: Constructing a Prototype User Interface
Jim Hardley and Bob Goode have hired your team to design and develop and application. A member of your team has created the prototype of a screen (shown below) in your application.
Illustration 3
1. Determine if the prototype uses menus appropriately.
2. Determine if the prototype uses shortcut keys appropriately.
3. What other changes would you make to improve the design of this interface?
4. Using the development tools you’re familiar with (i.e., Visual Basic and Visual C++), create a corrected version of the prototype with appropriate and consistent use of menus, access keys, and other elements of the user interface.
1. The menu system has inappropriate use of menus. The Help menu should always be rightmost. The File menu should always be leftmost. The Edit menu should be to the right of the File menu, with View beside that.
2. The Close menu item has the shortcut key Ctrl+Z assigned to it. This is a common shortcut key that undoes the last action performed, and should be changed.
A metaphor is a term or phrase that suggests a resemblance to something else. Metaphors convey an image. For example, “The Internet is a vast spider web with threads connecting people all over the world.” Metaphors can be used for objects in your application. You’ve probably noticed some metaphors in using Windows and Windows applications: for example, files holding data are stored in folders, which can be stored in cabinet files (like filing cabinets). This allows the user to associate such elements with non-computer items they’ve had experience with. Users are able to work with the object as a metaphor, relying on the representation and not knowledge of the underlying technology.
When designing your application, you should try to apply metaphors to the objects that are used. Icons used for toolbars should properly represent what they’re used for. For example, an icon of a trashcan represents deleting an item, a floppy disk represents saving a file, scissors for cutting, and a clipboard or paste can for pasting from the clipboard. This allows the user to automatically associate the metaphor with a distinct action. Any original features appearing in your application should also follow suit. In doing so, the user has a better understanding of how to use your software, without needing to constantly refer to user assistance.
A business solution that accesses data won’t be of much use if the database has a poor design. To design a database that works effectively with your program you need to determine and define the input data. This is what data modeling is all about. Data modeling is where you define the structure of your database, through a process of:
· identifying the data and data requirements of the business
· documenting this information
· implementing the requirements into your application’s design
Through this process, you’re able to gather and incorporate into your design valuable information that will enhance your application. This includes such things as data types to use in the database, data integrity, and, as we’ll see, other integral pieces of information necessary to the successful design of a database.
The first step in creating a data model is reviewing the existing data structures used by an organization. This allows you to see how data is currently stored and used. By reviewing this, you can determine if the current data models and processes meet the requirements of your application, or if a completely new data model needs to be created.
Identifying data and data requirements is an important first step in the design of your database. This looks at what data needs to be accessed and stored, and the associated processes going along with it. Identifying data and its associated processes can also affect such things as output requirements, and the design of certain aspects of your application. For example, if customers need to access the ordering system over the Internet, it will not only affect how security will be set up in the database, but also determine that the information will be accessed online. In this example, data accessed by these clients would include the product, price, and description data stored in the database. In addition, they’d need to input some sort of customer information. By evaluating the processes used to access data, and whether data needs are required but not being met, you can determine how your database should be designed.
When interviewing users and analyzing the structure of the current database, document what kind of data will be used in the new database design. Data describes the people, places, and things that will be stored in the database. These items can be customers, employees, cities, products, and so on. When documenting these items, you should include the following information, which will be used later in your design:
· The name of the data item, for example, company, city, and state.
· Description of the item.
· Data ownership, which explains who will be responsible for the data.
· Characteristics, which explain attributes of the data.
· Processes, relationships, and events, which explain how the data is created, modified, and used.
Through this information, you are able to combine these items into groups of data, identify how they relate to one another, and plan how they will be used.
Once you’ve identified the data that will be used, you need to organize it into an efficient database. After all, databases aren’t mishmashes of information. They consist of tables, keys, columns, rows, and relationships. A process called normalization is used to organize and refine the data.
Normalization is a set of rules that the logical database design should satisfy. These rules are called Forms, and they ensure the proper design of your database. These Forms include the following:
· First Normal Form, where you determine that there are no duplicated groups or multi-value columns in the database.
· Second Normal Form, where you ensure that the non-key fields in your database depend on the entire primary key, and not just part of it.
· Third Normal Form, where you determine that non-key fields don’t depend on other non-key fields.
· Fourth Normal Form, which requires that independent data entities are not stored in the same table when those entities have a many-to-many relationship with one another.
· Fifth Normal Form, which dictates that you should be able to reconstruct an original table from the tables created from breaking up the original table.
In the sections that follow, we’ll show how to design the logical database so that it adheres to the rules that make up normalization. We will only discuss the first three Forms, as the last two are often disregarded in database development.
Normalization starts with the data you identify, and groups it into elements that make up the database’s structure. This includes the following:
· Entities, which are representations of concepts or ideas, created from the values of its attributes. Of the specific types of entities, there are Associative, Kernel, and Characteristic. Kernel entities are entities representing core concepts. They are strong entities, and can exist in the database without the existence of other entities. Characteristic entities are entities that provide characteristics of another entity. It is a weak entity and thereby can’t exist in the database without the existence of a kernel entity. Associative entities (also called intersection entities) are entities that associate two or more entities. As we’ll see later, they are used to reconcile many-to-many relationships into two one-to-many relationships.
· Attributes, which are properties of the entity. These are the data elements that define the characteristics of the entity.
For example, an entity could be you, and the properties that make up you as a person would include height, weight, age, and sex. When applied to your database structure, the entity would be a table. The attributes would be the cells, fields, or object properties that make up the data entity.
In your database, you’ll need to choose a specific attribute, or a combination of attributes, that uniquely identifies that particular entity, and no others. This is called an identifier, but is also known as a primary key, key, or property value depending on the database management system that you’re using to create the database. Identifiers are used to allow entities to be unique from one another, as they can often have identical attributes. For example, let’s say you were creating a database of employees. Unless the company consists of two people with unique data, many of the entities making up the database will have identical attributes. Two or more people may have the same name, many will be of the same sex, others will work in the same department, and so on. To keep two or more entities from being confused with one another, an identifier is used. In this case, the identifier could be a social security number (or, for Canadians, Social Insurance Number), an employee number, or any other attribute that will be unique to any specific entity.
Database tables are then grouped into databases that are used by your application. To keep information from being repeated in your tables, you determine what information is repeated. For example, if you were creating a database of customers and orders, you would find that many customers are ordering the same products. These products could have attributes of a name, size, order ID, and so forth. To keep this same information from appearing over and over again in a table, you would separate the information into two tables: one for customer information, and the other for product information. Normalizing the one table, to create two related tables, keeps data from being duplicated.
While we’ll see how normalization is used to set up relationships between tables in the next section, it’s important to recognize the main purposes of normalization:
· It eliminates duplicated and redundant information from tables.
· It accommodates future changes to data structure.
· It minimizes the impact of these future changes on applications that access the database.
Because normalization eliminates duplicate information from tables, it creates an efficiently designed database for your application. However, normalization alone generally creates databases that are inefficient performance-wise. As we’ll see later in this chapter, denormalization is used to increase performance.
Exam Watch: Normalization is a relational database design theory that is fairly complex. It’s based on a branch of mathematics called set theory, on which entire chapters and books have been written. Fortunately, for the exam, you don’t need that level of in-depth knowledge of normalization. You do need to know how to use normalization to group data, understand the rules of normalization, and other concepts covered in this and other sections of this chapter. In addition, while being originally created as a theory applied to relational databases, it’s also common practice for indexed files.
Exercise 11-6: Grouping Data into Entities Using Normalization
Using normalization in
this exercise, we’ll break a database into different entities, attributes, and
tables. Because not everyone reading this book will have a DBMS, such as Access
or Paradox, you can use the tables below.
When interviewing the owner and staff of a local video store, you’re told that it is common for customers to special-order videos. In taking orders, customers are set up with their own customer ID number, and information on their name, address, and phone number is taken. The customer requests a particular movie, which is currently organized in a purchasing book by an order number, and has information on the movie’s name and price. As a service to our customers, we also want to be able to search the database for movies currently and previously ordered by the customer.
1. In the table below write one attribute in each column. This will identify the attributes you can group into entities.
Attributes |
||||||
|
|
|
|
|
|
|
By looking over the interview information, we can see that the different attributes consist of the customer ID, customer name, address, phone, movie ID, movie name, and price.
2. By identifying redundant information, determine which attributes can be grouped into entities. In looking at the information from our interview, we can see that customers will probably order more than one movie. This means if we were to use a single table, customer information would be repeated many times for the same table. As such, we need to break the single table into two tables: one titled Customers, and the other titled Movies. Do this in the tables provided below.
|
|||
|
|
|
|
|
||
|
|
|
By looking over the data from our interview, we can see that customers are one entity and movies are another. The customer ID number, name, address, and phone number would apply to the customer entity, while the order number, movie name, and price would apply to the movie entity.
3. Determine which attribute of the entity will be used as the identifier. In looking at the different attributes, we can see that the customer ID number can be used as the identifier for the customer table, while the order number would be the identifier for the movie table.
In the previous section, we showed how tables use identifiers to uniquely identify data entities. When one column in the table is used as an identifier, it’s called a primary key. If more than one column is used as an identifier, it’s called a composite or compound primary key. Whether one or more attribute is used, the primary key is used to identify the rows that make up a table.
In addition to primary keys, there are also foreign keys, which are columns or combinations of columns with values that match the primary key of another table. The values of a foreign key are often unique and copy those of the primary key in the other table. However, as we’ll see in the next section, this isn’t always the case.
Exam Watch: Don’t confuse foreign keys with primary keys. Primary keys identify rows that make up the table, while foreign keys are used in relationships to reference other tables.
Using the primary key of one table, and the foreign key of another table, you can link two tables together in a relationship. Relationships link two tables together, by having the primary key of one table referenced by the foreign key of another table. For example, let’s expand on the earlier exercise of the video ordering system. As you recall, we identified attributes, grouped them into entities, and split the data into two tables. We did this so that we wouldn’t have to constantly re-enter the customer information (name, address, and phone number) for every video that was ordered. In the customer table, we used the customer ID as the primary key. By setting up a new column in the Movies table called customer ID, we can use this new column as a foreign key. All customer IDs entered into the foreign key would match those of the primary key in the Customers table, through referential integrity. We’ll discuss referential integrity in greater detail later, but it should be mentioned here that when referential integrity is set on a relationship, you ensure that for every row existing in a foreign key, there is a corresponding row in the primary key. Depending on the DBMS used, a relationship is either set up automatically (as is the case in SQL Server), or you would need to manually set up a relationship between the two tables, by having the customer ID entered into the foreign key (the column in Movies) point to the primary key of the Customers table. When a staff member enters the customer ID into the foreign key, it references the information for a particular customer. In other words, if the customer ID entered into the foreign key is 21, it would reference the row of the other table that matches the primary key of 21. By having the relationship between the primary key of one table and the foreign key of another, we are able to reference information between them.
We’ll elaborate on the different relationships possible for tables in the next section, but this illustrates the importance of primary keys and foreign keys. The foreign key you create creates a link between the two tables. Whatever column or columns you choose to use as the foreign key need to have values that match the values entered into the primary key. Then, when you enter a value into one column, it can match it up with the column in the other table.
In setting up relationships between two tables, a possible problem arises. Since one table points to another, what happens when you delete information from one table that points to information in another table? For example, if you deleted a customer from the video ordering system we’ve been discussing, there would still be information on all those video orders in the other table. In other words, if John Smith special-ordered a video, and his customer account was deleted, the order would still be lurking in the other table. When the video came in, there would be no way to contact the customer, since his account was deleted. Another problem that could occur is someone entering a value into the foreign key that doesn’t correspond to a row in the primary key table. For example, the customer ID of 33 is entered into the foreign key of the Movie table, but there is no customer 33 in the primary key of the Customer table. To keep these problems from occurring, referential integrity is used.
Referential integrity is a system of rules that can be applied to relationships through your DBMS. When you set referential integrity on a relationship, you are ensuring that for every row existing in a foreign key, there is a corresponding row in the primary key. It also keeps related data from being changed or deleted, because you need to delete the relationship between tables before you’re able to delete the primary key.
To enforce referential integrity, several conditions must be met, as shown in the following checklist:
Checklist 11-1 Enforcing Referential Integrity
· The related tables must belong to the same database.
· The primary key and foreign key must have the same data type and size.
· When you set a relationship to a foreign key, the column must be a primary key or have a unique constraint. A unique constraint is a non-primary key with a constraint that ensures that no duplicate values can be entered in that column.
If one of these conditions isn’t met, then you won’t be able to set referential integrity through your DBMS.
As mentioned earlier, a relationship is a link between entities. This link is established through the primary key of one table and the foreign key of another table. By setting up a relationship between tables, you allow one table to reference information contained in another.
One issue dealing with relationships is what kind you will choose. While one table can reference another, you will need them to be referenced in different ways. For example, in a video database, one customer may rent many different movies. However, each movie will have only one director. This means that while the Customer and Movie tables will have one kind of relationship, the Movie and Director tables will need another kind of relationship. Because different tables are referenced in different ways, there are three kinds of relationships you can apply to tables:
4. One-to-Many
5. Many-to-Many
6. One-to-One
As we’ll see, the type of relationship you choose depends on how you want one table to reference another.
One-to-many relationships are the most common type of relationship used in databases. In a one-to-many relationship, a row in one table can have many matching rows in a second table, but the second table can match only one row in the first table. For example, let’s say you have two tables for a paternity database. One table has information on fathers, while the other table has information on children. While each father can have many children, each child can have only one biological father. As such, the table on fathers could have many matching rows in the table of children, but the rows of related children would match a single row in the table of fathers. In creating such a relationship, you would need to have a column in the fathers table (the “one” side of the relationship) being a primary key (or have a unique constant), while the other table would be defined as a foreign key.
Many-to-many relationships can have each table matching multiple rows in one another. To use the example of a video database, let’s say you had one table of actors and another table of movies. Many actors will act in a single movie, and each movie stars different actors. As such, each table will have many matching entries in the other.
To create a many-to-many relationship, you need to create an additional table, which is an Associative Entity. You may have heard this referred to as a junction table or link table. The Associative Entity is used to associate the two tables, and has a primary key that consists of foreign keys from each of the other two tables. To continue with our example of a video database, you would create two tables, Actors and Movies, which would have primary keys of their own. Let’s say the primary key of the Actors table is called ac_id, while the primary key of Movies is mov_id. You would then create an Associative Entity, whose primary key would be a combination of the ac_id column in Actors and the mov_id column in Movies. After creating these tables, you then create a one-to-many relationship from the Movies table to the Associative Entity, and another one-to-many relationship from the Actors table to the Associative Entity. In creating two one-to-many relationships from each of the two tables to the Associative Entity, you create a many-to-many relationship.
One-to-one relationships are the least used type of relationship. This is because one row in a table can match only one row in another table. For example, if a single ID card is assigned to a single person, you could create one table of people’s personal information, and a second table of ID numbers. Each person would be associated with only a single ID number, so a one-to-one relationship could be created. You could create the one-to-one relationship if both related columns are primary keys or have unique constraints.
While such relationships are pretty uncommon, they do have their uses. As we saw with the example of ID cards and numbers, you could use the one-to-one relationship to isolate sensitive information for security reasons. It’s also useful for temporary data that you plan to delete within a short period of time. If you have a temporary table that needs to be created, and is defined as temporary by the DBMS, the information you plan to delete can be removed quickly by deleting a table. If you are dealing with a table that has an incredible number of columns, and have trouble sifting through them, you could break up the table into two tables, and then create one-to-one relationships. This would allow you to keep all the data, but organize it more effectively. Such organizational reasons also apply when you’re storing information that applies to only a subset of your main table. In such cases, it’s often more effective to break up the table, and create one-to-one relationships.
When you have integrity, you control your actions in a correct and consistent manner. While this is something you should expect of yourself and the people you deal with, it’s also something that’s expected from a good database. While the work we’ve covered so far is vital to good database design, it’s useless if the values stored and retrieved by your application are invalid. After all, a database application is of little use if it can’t control data access in a correct and consistent manner. This is what data integrity is all about.
In designing your database, it’s important to identify business rules that can be used to ensure the integrity of your application's data. In doing so, you’ll be able to determine how and under what conditions the application will store and retrieve data. The business rules are identified through interviews and other techniques mentioned in Chapter 9, and the usage scenarios that are generated from these methods of information gathering. Through these sources of information, you can determine how, why, and when data should be accessed. You then apply the data access business rules to any of the following situations:
· When your application needs to inserts, update, delete, or view data
· Application-based referential integrity
· Data security
· Data validation
· Multi-file data access
As we discuss each of these situations individually, you should remember that you’re not limited to applying business rules to one or the other. In fact, many or all of these situations would arise on almost any project, and indicate that consideration needs to be given to applying business rules to data access.
The heart of a business solution is its ability to manipulate data. How this manipulation is performed is determined by the business rules that are applied to data access. When this is done, the data access business rules control how the business solution views, inserts, updates, and deletes data. For example, if you were creating a banking program that processed customer transactions, you would want to ensure that customers had money in their accounts before they were allowed to withdraw funds. In such a program, a business rule would automatically check the customer’s account balance before inserting the amount of the withdrawal into a debit column of the bank account, and updating the account balance.
Another common use for business rules is application-based referential integrity. Relational databases like Microsoft Access allow you to set referential integrity through the DBMS. The information that handles referential integrity is itself stored within the database file. However, indexed files like VSAM don’t have this capability; they’re generally just storage engines for raw data. As such, referential integrity is handled through business rules that are incorporated into your application’s code. In your application you create custom code procedures that determine how primary keys, foreign keys, constraints, and other issues will be dealt with.
This isn’t to say you can use application-based referential integrity only in indexed databases. There may be times you want to enforce the referential integrity of relational databases through your application. This commonly occurs when the limitations of the database create a situation where triggers, constraints, and stored procedures are insufficient. When this happens, you need to enhance referential integrity through the code of your application. Another common occurrence is when the DBMS makes it too complex to effectively implement referential integrity, and it’s easier to enforce through code in your application. Because of this, it is important to determine the limitations and complexities of the relational database you’re using, and see if it is expedient to enforce referential integrity through your application’s code.
As we saw in Chapter 8, security is an important issue in many of the applications you design. Business rules can be used to determine who gets access to your data, and how they can use it. By implementing business rules into your application’s code, or by having your application work with other programs (such as SQL server), you can protect data by limiting who has access to the data, how they can manipulate the data, and what features of data manipulation they can use.
Data validation ensures that the values users type in are correct and accurate, by validating the data in one of several ways:
· Data type validation
· Range checking
· Code checking
· Complex validation
Each of these types of data validation is important to an application. If a user inputs incorrect information, errors can result, which could possibly lock up the application, or return incorrect information.
Data type validation looks at the type of data a user inputs, and determines if it is the correct type. For example, if the user tried to type his or her name into a numeric field in a calculator program, it would result in an error. To avoid this, data validation looks to see whether the field accepts numeric, alphabetic, or some other type of data.
Range checking is a type of validation that looks at the range of a particular data type. As we’ll see later in this chapter, each data type has a minimum or maximum value. For example, if a field holds integers, it can hold any value between -32,768 to 32,767. If a user tried to type a number below or above this range, an error would result. Range checking is used in applications to check whether a value falls within the range of the data type.
In a number of the applications your create, code checking may be used to determine whether certain actions are taken. For example, in creating a retail sales application, different products may be taxable and nontaxable items. Depending where the application is used, different taxes may be applied. To resolve how products are taxed, retailers generally use tax codes. The code is typed in, and depending on this value, taxes are automatically applied to the sale price. Applications commonly use lookup tables or validation tables for this code checking. Input is looked up on the table, so the appropriate action can be performed.
In addition to the previously mentioned forms of data validation, which check the basic input of the user or lookup values, there may be times when more complex validation procedures are required. A good example of this would be an application used by an insurance company. With health insurance, you’re allowed to claim a certain number of dollars for medical care each year, and a certain number over the lifetime of the policy. Because of this, the application would have to compare the amount currently being claimed to see if it’s over the yearly limit, and then determine if the policy holder has gone over the policy’s total limit. If it were over, the claim would be denied. If it were not over the limit, this complex data validation routine would commit some other action.
Moving away from data validation, another important use of business rules is multi-file data access. This occurs when your application needs to process a series of records as part of a decision process. To use the previous example of a medical insurance program, your application would need to review the policy holder’s previous claims, to ensure that a fraudulent claim isn’t being submitted. After all, there are only so many heart transplants a policyholder will undergo. The business rule goes through the chain of records, and repackages them so that the agent can use the information provided.
When incorporating business rules into your data model, it’s important to remember that the business rules for your application aren’t the only game in town. Consideration should be given not only to how your application works with the data, but also how business rules belonging to other applications will affect the data, and how often the business rules change. Business rules should keep your data accessible, correct, and secure. They shouldn’t become problems for other applications and a hindrance for change.
When incorporating business rules, you need to look at the business rules of other applications. If other applications are using an older business rule, or one that contradicts the business rules in your application, it can affect the data. While your application performs its actions correctly, it may seem to be causing errors because of the business rules in the other application. In addition, you should determine whether other applications would benefit from using the business rules you’re incorporating. Business rules change, and you should consider how your implementation of them would affect the ease or difficulty of modifying them later. When business rules are made part of an application’s code, it can be difficult changing the business rules later. You’ll need to change the code, recompile, and then reinstall on every workstation that uses the application. If the business rules are the only change to the application, this is unproductive. If business rules change frequently in an organization, it can also be frustrating.
Because of changes in business rules, and the need for other applications to access them, you should consider implementing business rules into COM components, such as ActiveX components. By incorporating them in this fashion, they are separate from the code of your application, and can easily be changed without having to change the code and recompile the application. By exposing properties and methods of the COM component, other applications can benefit from the business rules.
In addition to business rules, you can also incorporate constraints into your database. Business rules, also known as business logic, are the policies and procedures that dictate corporate behavior. Constraints, on the other hand, are business requirements that enforce what a user can input into specific columns of your database. Because constraints limit the values entered into a field, they keep t users from entering data in a format incompatible with other values held in that column. They are also another way of enforcing referential integrity of data.
Despite the ability to put business rules and constraints
into the data tier, it’s important to remember that business rules/logic and
requirements predominantly belong within the middle tier of your application.
Whenever possible, the business rules and requirements for your application
should be put into the middle tier, and avoid placement in the data tier.
Check constraints can be incorporated into a data model to specify what data formats and values are acceptable. For example, let’s say you had a field for Canadian postal codes, which are a combination of letters and numbers, such as N5X 2L8. With a check constraint, you can keep users from entering only letters or only numbers into that field. With American zip codes, you could apply a constraint that accepted only a specific number of digits. If a user typed in 90210, the constraint would keep users from entering more than five numbers in a field for the zip code. You can apply check constraints to different columns of your database, or you can apply one or more constraint per column.
Default constraints are used to enter a specific value when a user doesn’t enter anything into a field. If a user skips over a field, a default value is automatically entered for them. This can be a comment, such as “To be filled in later,” or another value that reflects a common or expected answer. For example, if you were creating an application for subscriptions to a men’s magazine, you could expect that most of the people ordering subscriptions would be male. As such, you could have a default constraint used to enter “Mr.” unless another explicit value (i.e., Miss, Ms., or Mrs.) was entered.
Unique constraints ensure that only unique values are entered into columns that aren’t primary keys. Just because a column isn’t a primary key, it doesn’t mean that duplicate entries can be allowed. Imagine if your application issued two people the same security ID, Social Insurance number, or Social Security number. Allowing duplicate entries could cause problems later. If you have a specific column that requires a unique value, this constraint will ensure that no duplicate value is entered.
Primary key and foreign key constraints can also be applied to a database. Primary key constraints ensure that duplicate values aren’t entered into primary key columns. Foreign key constraints ensure that the value entered into a foreign key column match a value in another table’s primary key column. Such constraints also restrict NULL values, thereby forcing the user to enter some value into the field.
While rules of normalization are vital to good database design, it’s important to know when to break the rules. There are times when a severely normalized database will decrease performance. By rearranging your database, and pulling away from the rules of normalization, you may be able to make your database work faster. By identifying an appropriate level of denormalization, you’re able to address such performance considerations.
Denormalization allows you to selectively identify which tables and columns can break away from the normalization techniques you’ve used in your database. In other words, you intentionally violate the rules of normalization as a tradeoff for performance. This means that you must first start with a normalized database, and then select areas that will benefit from denormalization. At no time should you ever denormalize the entire database, or not bother to use normalization at all. Denormalization enhances performance, but shouldn’t lower the security or functionality of the database in any way.
Earlier in this section, we mentioned how important it is to identify and define the characteristics or attributes of the data to be used in your design. Data reflects the people, places, and things a business needs to record facts on, which are used to run the business. Because the data entities in your application will reflect different items, it follows suit that these items will have different characteristics. One may reflect a location, such as an address or country; while another may reflect measurements, such as height, weight, and so forth. Other characteristics may be of value, such as currency or productivity; while still others may be conceptual (names or identification numbers) or relational (such as units within departments, which reside in organizations). No matter what data entity you encounter, each will always have attributes that define them.
The attributes of the data entity identify its data type. As shown in Table 11-3, different data types are used to store different kinds of data, and each kind uses varying amounts of storage space. This shows us that when creating your data model, it’s vital to determine the kinds of information that will be stored in the recordsets of your database. If your database has the wrong data type, it can affect performance and limit user input. Imagine a customer service rep attempting to enter a customer name into a field that only accepts numbers, or needing to enter a number that’s too large to input into a field, and you’ll see the dilemma. In developing a data model it’s important to define the data that’s used, and determine the type, size, and default data that will be entered.
Description |
|
Boolean |
Can accept values of True or False. Storage space: 2 bytes |
Byte |
Numbers ranging in value from 0-255. Storage space: 1 byte |
Currency |
-922,337,203,685,477.5808 to 922,337,203,685,477.5807 Storage space: 8 bytes |
Date |
Represents dates ranging from 1 January 100 to 31 December 9999. Storage space: 8 bytes |
Double |
-1.79769313486232E308 to -4.94065645841247E-324 for negative values and from 4.94065645841247E-324 to 1.79769313486232E308 for positive values. Storage space: 8 bytes |
Integer |
-32,768 to 32,767 Storage space: 2 bytes |
Long |
-2,147,483,648 to 2,147,483,647 Storage space: 4 bytes |
Object |
Used to refer to objects. By using the Set statement, a variable declared as an Object can then have any object reference assigned to it. Storage space: 4 bytes |
Single |
-3.402823E38 to -1.401298E-45 for negative values and from 1.401298E-45 to 3.402823E38 for positive values. Storage space: 4 bytes |
String |
Codes in the ASCII character set (the first 128 characters on a keyboard), and special characters (such as accents and international symbols) making up the remaining 128. |
Variant |
Default data type. Used when no data type has been specified. . It represents numeric values ranging from 1.797693134862315E308 to -4.94066E-324 for negative values and from 4.94066E-324 to 1.797693134862315E308 for positive values. Storage space: 16 bytes |
Table 11-3: Data Types
When you’re developing a database, you should use general database development standards and guidelines. This means designing the database using the concepts we’ve covered so far, and first determining whether data for your database already exists in a different format. In the logical database design, this introduces the need to decide whether to use existing data, attach or import it into another database, or not use it at all. It also introduces whether certain guidelines and standards must be used. Depending on the database product you use to create your database, different guidelines may be suggested and offered.
Regardless of the type of database you create (e.g., Access or Oracle), there are certain guidelines and standards you should follow. Naming schemes are important to use in developing database applications. You should always keep the names of data objects short and descriptive. This will make it easier to remember the name of a data object during the design and development of the database. If columns have long and/or difficult names to remember, and that don’t reflect their purpose, you’ll find that you’re spending considerable time looking up those names.
You also shouldn’t use the same name for multiple objects or fields in your database. This can lead to confusion for developers as they may refer to the wrong object if both have the same name. Similarly, if you have more than one field with the same name, it’s very easy for developers to use the wrong field for data access. For example, if you have a column called Name in a table of publishers, and another column called Name in a table of authors, it is possible that the wrong attribute will be used in your application. The developer will see that the Name field needs to be used on a Form, but could use the wrong one.
Standard naming conventions should be used for your database application. In Appendix D of this book, the Hungarian naming convention is discussed, and it is suggested that you use it. If you choose not to use this naming convention, you should create your own naming convention or use the one currently in use by your organization. Also, it’s important to note that some database products have well-defined naming guidelines, and you should follow those. The naming scheme should be decided on during the design of the database, and then used during development.
As we saw earlier in this chapter, the Solutions Design model is made up of three perspectives, which are used by your team to design business solutions. These three perspectives consist of conceptual, logical, and physical design. Although you start with the conceptual design, and work your way through to the physical design of the application, there is often overlap between each design phase. There’s no clear cutoff point in moving from one perspective to the next, and you may often find that you’ll revisit or redesign different parts of your project, while others are being finished. There is a considerable amount of work in designing a solution, and no one person in your team can do it all. Therefore, synchronizing and coordinating the different tasks that make up the Solutions Design model requires putting the right person on the right job.
At each point in the design process, each role in the Team model has specific duties to ensure the success of the project. These duties vary as the design of the business solution moves through the conceptual, logical, and physical design phases. While a team member is responsible for performing one activity in the conceptual design, that responsibility may change as the business solution progresses through the logical and physical perspectives.
Throughout the different processes of conceptual, logical, and physical design, one thing remains constant: Program Management has ownership. This role is responsible for driving the overall design process, and has the responsibility of coordinating and synchronizing the other members of the team. As other roles perform activities that vary from one perspective to another, Program Management is always in the position of being accountable for the overall success of the business solution’s design.
During the conceptual design of the product, Program Management and Product Management have the greatest responsibilities. Program Management owns responsibility for the conceptual design’s success, and drives the actual conceptual design process. Product Management is responsible for gathering the information used in conceptual design, and has responsibility for driving the validation of usage scenarios created at this phase in the Solutions Design process. As seen in Table 11-4, members in each of the other team roles have their own responsibilities. Each team member addresses issues that align to their particular role in the Team model, but the major duty of each role is to identify risks in their area of expertise, which may have an impact later in the Solutions Design.
Role |
Conceptual
Design Responsibilities |
Product Management |
Gathers user input, and has responsibility for driving the validation of usage scenarios. |
Program Management |
Has ownership and responsibility for driving the conceptual design process. |
Development |
Aids in the evaluation of current and future states of the system. Analyzes business policies, and helps identify risks that may arise from the conceptual design in the logical and physical design stages. |
User Education |
Looks at usability issues that appear in the conceptual design. Analyzes usage scenarios to determine training and other user education required from changes to the current system. |
Testing |
Validates usage scenarios and determines changes required for the system to be compliant with user requirements. |
Logistics Management |
Responsible for rollout and infrastructure issues resulting from changes. |
Table 11-4:
Team Roles and Their Responsibilities in the Conceptual Design Process
Microsoft's Solution Framework provides numerous models that apply to almost any type of application development project in existence. Not all models, or roles defined within the Team model for that matter, need to be leveraged or implemented. In the case of the roles listed as a part of the Team model, often times, numerous roles will be assumed by the same person. Be careful to avoid grouping roles that have inherently different goals in mind during certain aspects of the design phase. Strive to fully implement roles whose absence has the potential for causing the biggest negative impact.
In regards to the exam environment, be fully aware of the subtle, or not so subtle differences between the roles, and their respective responsibilities in each phase of the application design and development process. Understand the differences between roles. Understand when and where inherent differences will arise in the focus of the roles, and the ramifications of failing to implement a given role, or the impact of assigning certain roles to the same individual. Pay careful attention to the differences between the roles of Product and Program Management. These can be difficult to distinguish.
In keeping the focus on roles, ensure that the primary roles in each phase of design (conceptual, logical, and physical) are able to fully perform the desired responsibilities. Most importantly, the conceptual phase can provide a hotbed for issues down the road. For this reason, full and strong fulfillment of the Program Management role can be vital in ensuring that the foundation for the resulting application is strong and able to support future enhancements, scalability concerns, and efficient design.
— by Michael Lane Thomas, MCSE+I, MCSD, MCP+SB, MSS, MCT, A+
Activities and information gathered in the conceptual design process are applied to the logical design of the application. The usage scenarios that are created in conceptual design are used to derive the business objects and related services used in the solution, and specify interfaces between the system and other elements (such as other users, systems, and components). It is here that the structure of the system is laid out, and it is determined how components will communicate with one another. Once the tasks involved in logical design are completed, the results are applied to the physical design.
With all this talk of components and systems, you might have guessed that Development plays a vital role in the logical design of a product. While Program Management still retains ownership over this part of Solutions Design, Development has the responsibility of deriving the business objects and services from the information provided in usage scenarios. In doing so, Development defines the objects and their related services, and ensures that there is sufficient detail. If the object and service definitions are incomplete or inconsistent, Testing, who is the other major player in logical design, catches it. Testing evaluates these definitions, ensures the logical design is valid, and also looks to see if the logical design as a whole is testable.
The other roles in the Team model aren’t greatly involved during the logical design of the application. As shown in Table 11-5, Product Management looks at the services that evolve from the logical design to ensure that they accurately reflect the perceptions and requirements of the user. UserEducation looks at these same objects and services, to identify areas of the design that will require training, documentation, and other methods of user education. Finally, Logistics Management ensures that the services derived from the logical design can be applied to the available technologies and infrastructure.
Role |
Logical
Design Responsibilities |
Product Management |
Looks at the services derived in the logical design, to ensure they reflect user needs and views. |
Program Management |
Has ownership of the logical design, and drives the logical design process. Also coordinates the efforts of the other team members. |
Development |
Defines the objects and their related services, and ensures that there is sufficient detail. |
User Education |
Analyzes the business objects and services to determine areas that will require training and materials for user education. |
Testing |
Ensures that object and service definitions are complete and consistent, the logical design is valid, and that the logical design as a whole is testable. |
Logistics Management |
Analyzes the services derived from the logical design to ensure whether they can be implemented into available technologies and infrastructure. |
Table 11-5: Team Roles and Their Responsibilities in the Logical Design Process
Once the tasks associated with these roles have been completed, the results are passed forward to the physical design perspective of the Solutions Design model. The abstractions of how the system will behave are transformed here to show how the system will actually be implemented. It’s here that the physical constraints of technology are applied to the logical design, business objects and services are applied to components, and implementation and performance issues become paramount.
As with the other two design perspectives, Program Management has ownership of the physical design. In addition to driving the process and coordinating activities, Program Management keeps the lines of communication open between team members. If there are any issues dealing with whether the application design complies with the enterprise architecture, Program Management needs to ensure these issues are discussed and dealt with. Because the work performed on the logical design is applied to the physical design, Program Management also has the responsibility of ensuring that the integrity of the logical design is maintained.
Of the different roles in the Team model, Development bears most of the responsibility in physical design. This is because what goes into the physical design directly affects what coding will take place and how the application is built. By specifying how components will be packaged, and applying the logical design to the constraints of the physical environment, Development provides a majority of what goes into the physical design.
Testing also has a primary role in the physical design of a product. During this phase of the project, Testing develops the test procedures and criteria that will ensure the product works to specification. It also looks at the components that Development proposes to include in the finished product, and determines whether these components can actually be tested. If they are not testable, further work on the component will need to be done by Development. Along with Product Management, Testing looks at the physical design to ensure that the requirements still adhere to those in the usage scenarios.
In addition to the work performed by Testing, Program Management, and Development, the other roles of the Team model perform their own activities, which either apply to the finished product or validate the physical design. This is shown in Table 11-6. Product Management looks at the physical design to determine whether it addresses the requirements and perceptions that were identified in usage scenarios, which were created in the conceptual design of the product. User Education takes advantage of the physical design perspective to plan the necessary training and user education materials that will support the product. Finally, Logistics Management plans the delivery, setup procedures, and other requirements for the product. These plans are passed onto the operation and support groups in the organization, and discussed so that the product will have a smooth rollout.
Role |
Physical
Design Responsibilities |
Product Management |
Ensures that the physical design addresses the needs and views of usage scenarios. |
Program Management |
Has ownership of the logical design, and drives the physical design process. Ensures that the integrity of the logical design is maintained, and also coordinates the efforts of the other team members. |
Development |
Bears the greatest responsibility for the physical design of the product. Determines how components will be packaged, and how services will relate to the system. |
User Education |
Responsible for planning the training and other user education services that will support the product. |
Testing |
Plans test procedures for the product, and aids Product Management in ensuring that physical design still addresses the needs and views that were outlined in usage scenarios. Also works with Development to ensure that components are testable. |
Logistics Management |
Plans delivery, installation, and requirements necessary for the product, and discusses these plans with the operation and support groups in the organization. |
Table 11-6: Team Roles and Their Responsibilities in the Physical Design Process
The physical design of your application is derived from the work done in the logical design. It’s here that you determine how the logical design will develop based on the set of technologies you choose. While the logical design is technologically independent, the physical design applies the services, business objects, and logical database design to specific types of hardware and software.
As we saw in the previous section, each member of the team has a role in the physical design of the application, with Program Management, Development, and Testing taking on the primary responsibilities. The major activities performed during physical design include defining the interfaces to be used in the application, component packaging, and distribution. In performing these activities, the abstract business objects and services of the logical design are translated into physical components of the system.
Moving the logical design into a physical design is a step-by-step process, that involves the following:
· Allocating services to components
· Deploying the components across a network
· Refining the packaging and deployment of components
· Specifying interfaces
· Validating the physical design
As we saw at the beginning of this chapter, a component encapsulates services that are accessed through its interface. Though each component works as a separate entity, and other programs can access its services, they are part of your application as a whole. Using the steps provided by the physical design process, you’re able to achieve a stable and effective physical design for your application.
The first step in the physical design process is allocating services to components. The business objects from the logical design are translated into the components that will make up the application. The business objects are grouped by their related services. Depending on the service contained in the business object, it is grouped into user, business, or data service components. By separating the services in this manner, you determine what components will be created by the services they contain.
The next step is taking your components from the previous step, and determining how they’ll be deployed across the network. This designates where components will be distributed on the network. If the application is for a single desktop, all components will reside on a single machine. If there is only one server on the network, components that provide services may reside on that server, while components to access the services will reside on each workstation. By determining the deployment of components across the network, each component is assigned to a specific node or machine on the network.
In determining the deployment of components on the network, there are a number of factors to consider. These include locality of reference, the interoperability of components, and data distribution issues that affect how components will work together, and where they will be placed. Support and reliability should also be considered, as you don’t want components placed on unreliable servers or areas that will be difficult to access. Finally, you should also look at issues dealing with the security of your application, ownership, and the user interfaces when determining how components will be placed on the network. Each factor will influence how you decide to deploy components on the network. Such decisions will affect how well your application performs, and whether deployment will adhere to the needs of your users. These factors are discussed in the paragraphs that follow.
Of these different factors, locality of reference can have a big effect on how well your application performs. Despite being a rather cryptic phrase, locality of reference is a rather simple concept. It means putting a component in a location where it will be used, or near to where it will be used. For example, let’s say you were creating an application for a large corporation, with offices in Tokyo and New York. The networks of these offices were connected by a WAN (Wide Area Network) link between two servers. If users in New York were going to use specific components, you would put them on the New York server. The same goes for applications on a LAN (Local Area Network), where components are placed close to the users who use them. This decreases the amount of network use, and allows users to have faster access to services provided by the components.
Security is often an issue that must be addressed in application design and it affects deployment. If your application depended on the security of a Windows NT server, you wouldn’t want to deploy components to a Novell NetWare server. As such, security should be addressed when deciding where to put components on the network.
While the previous step is where preliminary decisions on component packaging and distribution are made, the next step refines these determinations of physical design. Performance and optimization are major issues of this step. Here you look at how the components are deployed, and determine whether they meet performance requirements. The refinement process also determines the size of each component (granularity), and how components should be assembled. It also looks at reusability issues, which affect whether other applications will be able to use the component.
The fourth step in the physical design process looks at the interfaces that allow interaction with the component. This can be a programmatic interface, which other components and your application will use, or a graphical user interface, which users can interact with. In creating these interfaces, components are able to consume the services supplied by other components.
The final step in the physical design process involves validating the work done in the previous steps. It’s important that the services provided by components can be traced back to services in business objects. For every component in the physical design, you should be able to map its services to the services of business objects in the logical design. If you cannot do that with a component, then the physical design of that component is invalid, and you’ll need to redesign it.
Encapsulation is like a multivitamin capsule. Once you’re satisfied with the contents of the capsule, you simply take one to access the vitamins inside. The same occurs when you encapsulate data access procedures or business logic in an object. You can create components that shield the user from the steps required to access data from specific data systems. Rather than a user needing to know how to view tables, manipulate data, stored procedures, and so forth in a SQL, Oracle, Paradox, or other system, they merely access the database through the component that’s been created for them. They access the methods or properties they need in the component, and the component does the rest of the work for them.
Encapsulating access to a database is useful because the code used to access the database is kept separate from the actual application’s code. The component exists as a separate entity, that is accessed through the properties and methods that are exposed to the calling code of the application. Code within the application accesses the functionality of the component. If the developer decides to change code within the component, the application on the workstation remains unaffected.
Encapsulating data access is particularly useful when dealing with legacy code. If you are creating a new application to access an old data system, you can encapsulate the procedures that access the old database. This saves users from having to know the commands for the older system, or needing to be retrained on how to use the archaic system.
When business rules change frequently in an organization, it’s also wise to create components that contain business rules. You can control how data is accessed without having to rewrite the code of the actual application. Any procedures that control how data is accessed and manipulated, security functions for data access, and so forth are controlled through the component. This is accessed by code in the application that calls on the properties and methods of the component.
Any component you create contains basic parts that make up the component, and determine its functionality. When you create COM classes to make up your COM component, you use properties, methods, and events to make up the characteristics of the class, which will subsequently become the characteristics of your component. Properties are used to read and set values for a specific attribute of the component. Methods define an interface for the component, and are used to invoke actions that the component can perform. This could include such things as adding items and printing. Events are the actions that are recognized by an object. Together they provide the functionality of the component, which the user or other components work with.
When designing the properties and methods of COM classes for your components, it’s important to keep in mind that any developer who uses the component must know what properties and methods are provided. This means that class/type libraries should be used, so the developer can use the Object Browser to see a listing of properties, methods, and descriptions of each. Otherwise, or in addition to, you should provide documentation that outlines what properties and methods are provided, and what they are used for. In doing so, developers wishing to use the component can incorporate code into an application that calls on the features of your component.
A property is an attribute of your component. For example, the color of text is a property, and the Visible property of an object provided by your component determines whether it can be seen when the program runs. In designing the properties of your component, you need to decide on what properties you want the user or other components to access and change.
A user can access the property of a component as they would the property of any other object. They’re accessed through a public property procedure or a public variable that you’ve declared, and can include property values, property arrays, and read-only properties that are written in the code of your component. Any objects you provide to the user through your component should be implemented as a property procedure. This is because if you provided the object through a public variable, the value of the variable could be set to NULL. This could destroy the object, and cause runtime errors in your code. Properties should have a default value, and can be change either programmatically, or through an interface (such as a property sheet).
Methods are actions that an object can perform. Like the properties you design for your component, the methods of a component are invoked like the methods of any other object. Code is added to the application, which calls on the method of the component. The method then performs whatever action it has been programmed to perform.
A method is a Public Sub or Public Function procedure that’s declared in the component, which is used to define your class. An example of this is the PrintForm method of a Form object in Visual Basic. When you use the PrintForm method in your programming code, the Form you specify will be printed. For example, let’s say you had a Form named Form1 that you wanted to print. The following code would print it to the local printer:
Form1.PrintForm
In using this code, we have invoked the PrintForm method of the object Form1, and a depiction of our Form will be printed.
When you declare methods in your component, you should declare all of the arguments used as explicit data types. As we saw earlier in this chapter, certain data types are different sizes. Implicit data types, which don’t have a data type attached to the argument, will by default be of the variant data type, which uses considerably more space than most other data types.
Arguments that take object references should have those references declared as a specific data type. This is done by declaring the type of data used in the argument, such as As MyObj rather than As Object or As Variant. This may not always be possible, but as a general rule you should try whenever you can. By declaring arguments as explicit data types, errors have a better chance of being caught by the compiler because of early binding. This will allow the error to be caught during compiling, rather than appearing as a runtime error when the user invokes the method.
Events are actions that are recognized by an object. An example of an event is when a Form loads into memory (i.e., the Load event), or when a user clicks on a button (i.e., the Click event). As you can see by this, some events are triggered by user interaction, while others are triggered by the application itself.
By default, any class you add to a Class module in a Visual Basic project will have two events associated with it: Initialize and Terminate. A Class module is a template for creating objects programmatically. The Initialize event occurs when an instance of a Class is created, and before any properties are set. It is used to initialize any data used by the Class, and can be used to load Forms used by the Class. Terminate occurs when the object variable is set to nothing or goes out of scope, and is used to save information, unload Forms, and any other tasks required to be done when the Class ends. Initialize is the first event that occurs between the two, and Terminate is the last.
Events can be added to any class in a component. All events are public, and can contain arguments like any other procedure. The difference between arguments in procedures and those in events are that events can’t have named, optional, or ParamArray arguments. In addition, events can’t return values. If you need a value returned, you should design functions, which return values, that can be used by the user or programmatic interface.
What is the purpose of a prototype? |
Prototypes are used to validate the design of an application, and allow users and customers to actually see what the interface of your application will look like. In doing so, you will get better feedback on different aspects of the design early in the design stages. |
Who has ownership of the design process? |
Program Management has ownership of the conceptual, logical, and physical design. |
Why would I want to enforce referential integrity in my database? |
Referential integrity is used to ensure that for every row existing in a foreign key, there is a corresponding row in the primary key. It also keeps related data from being changed or deleted, because you need to delete the relationship between tables before you’re able to delete the primary key. |
The Solutions Design model is comprised of conceptual, logical, and physical design perspectives. It also ties together the Application and Team models. The Application model breaks your application into distinct types of services, which consist of user services, business services, and data services. As we saw in this chapter, using these models allows you to design component-based solutions that are integrated into a successful software product that meets the requirements of users.
Throughout the Solutions Design process, each team member has specific duties. While Program Management retains ownership throughout the conceptual, logical, and physical design perspectives, the responsibilities of other team members change. At no time is any member of the team left out of the design process.
Because the user interacts with your product through the user interface, there are specific design issues that must be considered when creating the interface. This includes such things as navigation and input validation, and establishing appropriate means of output. Should the user experience problems using your application, online user assistance is implemented into the user interface, to provide clarification on the difficulties they are experiencing.
Prototypes provide a way of generating feedback from customers, end users, and other interested parties. Evolutionary prototypes are built on, and used in the construction of the end product. Throwaway prototypes are discarded once they’ve been used to validate the design and generate feedback. In constructing either kind of prototype, it is important to follow user-interface standards, organizational rules, and other elements that are part of the end product’s design.
Database design is a complex process that consists of identifying, documenting, and implementing the data requirements of the business. Normalization is part of good database design, and reduces data redundancy. Business rules and constraints can be used to enforce referential integrity, and control what data a user can enter. Denormalization pulls your database back from the rules of normalization, enabling it to work faster. Through the techniques used in this chapter, you can design an efficient database that meets the needs of the user.
Physical design takes the abstract business objects, services, and logical database design and applies them to the constraints of the physical environment. Here, technological constraints are applied to the logical design. The physical design consists of a process of allocating services to components, deploying components on a network, refinement, specifying interfaces, and validation of the physical design.
· Solutions Design is a model that provides different perspectives on how to design a business solution, and is essential in designing component-based solutions.
· Solutions Design model is made up of three separate views: conceptual design, logical design, and physical design.
· Business objects are abstract representations of real-world things or concepts (such as orders and customers).
· The requirements of an application fall into one of three tiers: user services, business services, and data services.
· The user interface provides the end user with the ability to view and manipulate data, through units of application logic.
· The data services tier is also called the data source tier, and is responsible for defining, maintaining, and updating data.
· When one business object calls on services in another business object, this is called a business object dependency.
· Prototypes fall into two categories: throwaway and evolutionary.
· A throwaway prototype is created for the sole purpose of getting feedback from users, and validating the design of the user interface.
· An evolutionary prototype is incorporated into the building of the actual product.
· Data modeling is where you define the structure of your database, through a process of identifying the data and data requirements of the business, documenting this information, and implementing the requirements into your application’s design.
· Normalization is a set of rules that the logical database design should satisfy.
· Primary keys identify rows that make up the table, while foreign keys are used in relationships to reference other tables.
· Referential integrity is a system of rules that can be applied to relationships through your DBMS.
· One-to-many relationships are the most common type of relationship used in databases.
· Many-to-many relationships can have each table matching multiple rows in one another.
· One-to-one relationships are the least used type of relationship. This is because one row in a table can match only one row in another table.
· Data validation ensures that the values users type in are correct and accurate, by validating the data in one of several ways: data type validation, range checking, code checking, and complex validation.
· Data type validation looks at the type of data a user inputs, and determines if it is the correct type.
· Range checking is a type of validation that looks at the range of a particular data type.
· In a number of the applications your create, code checking may be used to determine whether certain actions are taken.
· In addition to the previously mentioned forms of data validation, which check the basic input of the user or lookup values, there may be times when more complex validation procedures are required.
· Business rules, also known as business logic, are the policies and procedures that dictate corporate behavior.