Professional Visual Basic 6 Project Management
Professional Visual Basic 6 Project Management
Visual Basic
Project Management
Jake Sturm
All rights reserved. No part of this book may be reproduced, stored in a retrieval system or transmitted in
any form or by any means, without the prior written permission of the publisher, except in the case of brief
quotations embodied in critical articles or reviews.
The author and publisher have made every effort in the preparation of this book to ensure the accuracy of
the information. However, the information contained in this book is sold without warranty, either express or
implied. Neither the authors, Wrox Press, nor its dealers or distributors will be held liable for any damages
caused or alleged to be caused either directly or indirectly by this book.
Credits
Jake has always viewed programming and project management as a creative process, no different from an
artist creating a sculpture or painting. Visual Basic, combined with Microsoft’s BackOffice products, allows
the developer to create a masterpiece.
Presently, Jake is working for Microsoft Corporation as a Consultant. His email address is: [email protected]
and his personal web site address is: http://w3.gti.net/jakes. He lives in New Jersey with his wife, Gwen,
her two daughters, Jill and Lynzie, his son, Will, and his daughter, Maya.
Jake will be setting up a web site devoted to the Visual Basic language, Enterprise development and the
people who use Visual Basic. This site will be up in late October and will have a url of
http://www.realworldvb.com.
Dedication:
This book has to be dedicated to my wife, Gwen, my three daughters, Jill, Lynzie and Maya and my son
William. This book has consumed most of my time for the last several months. They have all understood
the importance of this book and have waited patiently for its completion.
Acknowledgements:
I must begin with my wife, Gwen, who once again has spent long hours editing and reviewing these
chapters. She has cleaned up many of my grammatical errors, snapped my run-ons into smaller sentences
and kept my writing clear.
The team at Wrox has been an incredible help, working long hours on massaging my text into the final
polished work you see before you. Thanks go to the editors Chris Hindley, Julian Skinner, Tony Davis,
Claire Fletcher and Dominic Shakeshaft.
I would also like to thank all of the reviewers who have spent their time reading the chapters and making
comments. They have worked hard to make this book what it is. I would especially like to thank Kathleen
Peters. Her comments have shown an incredible depth of knowledge of project management and the Visual
Basic language. Her comments have been to the point, sometimes humorous (definitely something an author
needs as they are going through pages of comments) and always accurate. She has added much to this book
and deserves special mention.
I also want to thank my readers. May this book give you the knowledge you need to properly manage all of
your Visual Basic projects and help you make all of your projects successful.
Table of Contents
Introduction 1
Why Do We Need To Know About Project Management? 1
Who Is This Book For? 2
What You Need To Use This Book 2
What's Covered In This Book 2
Conventions Used 4
Source Code 5
Tell Us What You Think 5
Development Phase 22
Milestones and Deliverables 22
Deployment Phase 23
Deliverables 23
Team Roles for the Cyclic Methodology 24
Team Member Involvement in the Four Phases 25
Summary 27
Chapter 2: Teams 29
The Big Development Team Myth 30
The Autocratic Manager 30
Problems of Autocratic Management in a VB Project 31
Self-Directed Work Teams 32
Team Structure 33
Visual Basic Software Team Roles 36
Project Manager 36
Envisionment Phase 37
Design, Development and Deployment Phases 37
Product Managers 37
Envisionment Phase 37
Design Phase 38
Development Phase 38
Deployment Phase 38
Component Managers 38
Envisionment Phase 39
Design Phase 39
Development Phase 39
Deployment Phase 39
Developers 39
Envisionment Phase 39
Design Phase 40
Development Phase 40
Deployment Phase 40
Testing 40
Envisionment Phase 40
Design Phase 41
ii
Table of Contents
Development Phase 41
Deployment Phase 41
Logistics 42
Envisionment Phase 42
Design Phase 42
Development Phase 42
Deployment Phase 42
User Education 42
Envisionment Phase 43
Design Phase 43
Development Phase 43
Deployment Phase 43
End Users 43
Envisionment Phase 43
Design Phase 44
Development Phase 44
Deployment Phase 44
Stakeholders and Sponsors 44
Envisionment Phase 44
Design, Development and Deployment Phases 44
Team Skills and Abilities 44
Communication 45
Making Decisions 47
Proper Planning 49
Solving Problems 52
Creativity 54
Resolving Conflicts 55
A Passion for Building Enterprise Solutions 57
Focusing On the Client 58
Team Spirit 60
Leadership 61
Accomplishing Goals 63
System Management 64
General Team Skills 65
Summary 67
Skills References 68
iii
Table of Contents
iv
Table of Contents
v
Table of Contents
Resources 149
Personnel 149
Project Manager 150
Cost Controls (Methods are in place to control costs) 150
Team Member Skills 150
Client Expectations 150
Workflows 151
Consensus on the Goals 151
Well-Defined Goals 151
Long-Term Results 151
Milestones 152
Goals that Meet Corporate Needs 152
Corporate Standards and Vision Statement 152
Changes in Corporate Vision 152
Well-Tested Technology 152
Testing 153
Unit and System Testing 153
Stakeholders and Sponsors 153
Team Members Commitment 153
Roles and Responsibilities 154
User Contribution 154
User Interest 154
Built With Cycles 154
Scope 154
Building Reusable Components 155
Change Control 155
Documentation 155
Definition of Goals 155
Methodologies 155
Example Risk Document 156
Change Control 156
Funds 156
Goal Measurement (Milestones) 156
User Contribution 156
Creating Risk Metrics 157
Creating Plans to Eliminate or Reduce Risks 158
Risks that Cannot be Eliminated or Reduced 158
Risk Tracking 160
vi
Table of Contents
vii
Table of Contents
viii
Table of Contents
ix
Table of Contents
xi
Table of Contents
xii
Table of Contents
xiii
Table of Contents
xiv
Table of Contents
xv
Table of Contents
xvi
Table of Contents
xvii
Table of Contents
xviii
Introduction
This means that much more is expected of modern applications, making them a serious and complex
undertaking. The people working in a project team must have an understanding of what it is they are to do,
but they must also understand what everybody else is doing. Project management must be a team effort,
with every team member contributing to the success of the project.
This coordination of efforts needs somebody to manage it and make sure that the project is achieving its
aims. However, project management is not, and can never be, just about one person arbitrarily taking
control of project activities. There should not be one autocratic manager - this is hardly a good grounding
for a comfortable team environment!
Tied in with this is the fact that projects are not just about getting the code written and tested (although this
is very important!). There are a number of other, non-technical skills that are important within project
work, such as communication, leadership and problem solving, amongst others, which are all part of
making a project successful.
Introduction
There are many ways in which a project can be structured; the emphasis on modern-day projects is that they
are built so that some parts are reusable and can be utilized in future project undertakings. This is the
essence of the object-oriented programming approach; code is written so that it has everything it needs to
be able to work - in this way, the code can be moved into other projects without causing a major rewrite.
For the examples in later chapters and appendices, it is assumed that you have extensive knowledge of
Visual Basic. The book as a whole, however, is not aimed specifically at Visual Basic developers (some of
you may be pleased to hear!).
http://www.microsoft.com/office/98/project/trial/info.htm
For the later chapters of the book, you will need to have Visual Basic 6.0 and also Visual SourceSafe to be
able to try the examples found here.
Section 1. Introduction to project management, teams and schedules in Project 98. (Chapters 1, 2
and 3)
Section 2. The four phases of the cyclic methodology:
Envisionment (Chapters 4 and 5);
Design (Chapters 6, 7 and 8);
Development (Chapter 9);
Deployment (Chapters 10 and 11)
Section 3: Source Control (Chapter 12) and Scheduling (Chapter 13).
2
Introduction
Throughout the book we will illustrate the development cycle of a DNA project. DNA stands for Windows
Distributed interNet Application Architecture and involves programming using Internet techniques, but
does not necessarily involve developing Internet applications. Our DNA project will be built on the
Northwind company - the end result will be a new order entry application; however, the company wishes to
move into electronic commerce, or e-commerce, and also wishes to reuse some of their existing order entry
components. You will see many references to this project throughout the book.
Chapter 1 serves as an introduction to project management, object-oriented programming and the cyclic
methodology. It explains more about why we need project management and tells us why good project
management is especially important in object-oriented software projects. This chapter also introduces us to
the four phases of the cyclic methodology.
In Chapter 2 we look at teams and team structure. There are a number of different team configurations: we
are concerned with the self-directing, goal-oriented team. This chapter also provides a comprehensive list of
each team member's role in every phase of the cyclic methodology. Listed also are a number of non-
technical skills that are important to team work, as well as information on how to improve these skills.
Chapter 3 is a tutorial on Project 98. Using a Visual Basic developer as the main focus, we create a number
of goals, showing how to enter them into Project 98, allocate time and resources to each goal and looking at
how each goal is represented on a Gantt chart. This chapter results in a personal schedule, or timetable of
events.
The Envisionment phase of the cyclic methodology is the emphasis of Chapter 4. Here, we learn what
activities must take place in the initial stages of a project and what goals must be achieved in this phase, as
well as discovering the milestones and deliverables for envisionment, and understanding why these must be
agreed upon by all team members.
Chapter 5 examines the concept of risk management, showing us how we can identify risks. It provides us
with a list of possible risks, saying how they could affect our project and includes a sample risk document.
To manage risks, we need to be able to measure them and track them - this chapter shows us how, giving us
also a sample risk-tracking document.
In Chapter 6 we look at the Design phase, or, more specifically, the conceptual stage of the design phase.
This involves interviewing the users to find out exactly what it is our application must do, and also to find
out exactly who our users are! This chapter includes a discussion on Unified Modeling Language (UML)
diagrams, work flows and business rules, which are all needed to understand what our system should aim to
do.
The emphasis of Chapter 7 is the logical stage of the design phase. Here, we learn about the structure of our
application: what components it must be made up of to meet business needs. This stage builds on the
information we have gained from the conceptual phase. This chapter also discusses the different
frameworks available for our application, along with Microsoft Transaction Server (MTS) and prototyping
the user interface.
3
Introduction
Chapter 8 concerns the physical stage of the design phase. This is where we actually define how our
application is going to be built in Visual Basic. This chapter builds on the groundwork we have carried out
in Chapter 6 and Chapter 7 and includes a discussion on mapping out code using activity diagrams. This
chapter also covers ActiveX Data Objects (ADO), Remote Data Services (RDS), Distributed Component
Object Model (DCOM) and the importance of designing as a team.
In Chapter 9 we move on to the Development phase. This is where we actually begin to code the
components we defined in Chapter 8. It suggests guidelines for coding our project and discusses the coding
of a business services component and a server component. It also stresses the importance of coding our
project so that we can reuse sections with ease in future projects. This chapter also touches upon Active
Server Pages (ASP) and Dynamic HyperText Markup Language (DHTML).
Chapter 10 moves swiftly on to testing and debugging our components. It discusses the different ways to
test our components; usability, which is testing the user interface, and functional, of which there are a
number of different types (two of which are stress and performance testing). This chapter then goes on to
discuss debugging Visual Basic MTS components and also logging information.
In Chapter 11 we examine the final phase of the cyclic methodology, the Deployment stage. In this chapter,
we will discuss the activities involved in the deployment of a project, such as Beta testing, user training and
project documentation. This chapter then goes on to describe the different deployment strategies available
to us, before explaining the importance of the final sign off of the project.
Chapter 12 discusses the notion of protecting the integrity of our source code by using Visual SourceSafe to
perform version tracking, source control and change management. This chapter discusses why we need
different versions of our project, and introduces some scenarios where Visual SourceSafe could be used to
protect our source code.
The final chapter provides an example schedule based on the project discussed throughout the book.
Chapter 13 covers all four phases of the cyclic methodology and tackles the issue of resource allocation
head-on.
Conventions Used
I have used a number of different styles of text and layout in this book to help differentiate between the
various types of information. Here are examples of the styles I use along with explanations of what they
mean:
4
Introduction
Program code appears in a number of formats. Blocks of code that are to be keyed into Visual Basic or
other programs appear in a gray block like this:
Code that appears in the body of the normal text looks like this: Adodc1.Recordset.MoveNext.
The code with a white background is code we've already looked at and that we don't wish to examine
further.
Source Code
All the code given in this book can be downloaded from the Wrox websites at:
http://www.wrox.com
http://www.wrox.co.uk
5
Introduction
6
Introduction to Project
Management
Complex software projects have always been notoriously difficult to manage successfully. Current projects
are required to work across numerous platforms, use multiple databases and operating systems and have to
be able to adapt to rapidly changing technology. The complexity of the modern software project has
resulted in over half of them either failing completely or not working as planned. There is a desperate need
for a structured, clear methodology for building software projects.
Visual Basic has evolved through six versions to become a very powerful programming language. The types
of applications we build with Visual Basic have also evolved from monolithic applications, through two-tier
applications to DNA applications. As the language has evolved, new features have been added that have
made the language more complex. This complexity can make it impossible to build efficient complex
enterprise systems using Visual Basic products if you do not properly manage the project. However, in
exchange for this added complexity and difficulty, we now can build complete, powerful Visual Basic
components within our enterprise systems. These projects can bring the entire enterprise together in a way
that could not be imagined just a few years ago. These unifying Visual Basic applications will allow
corporations to survive in an ultra-competitive and ever-evolving environment well into the twenty-first
century.
An object-oriented programming approach has become the most prominent technique of creating and
managing software projects. Over recent years a development model has emerged, encompassed by Unified
Modeling Language (UML), which provides a uniform mechanism for the efficient and effective design of
object-oriented projects.
Essentially, UML is a set of standard models used to design object-oriented projects (it is
not a description of actually how to implement those models). A brief overview of this topic
is given in Appendix A. For comprehensive coverage I would refer you to VB6 UML Design
and Development, also published by Wrox Press.
Chapter 1
The goal of this book is to show how these excellent design principles can be incorporated into a clear
methodology which will ensure the efficient and successful undertaking of the project, not just during the
design of the object-based Visual Basic application, but right through from initial conception to deployment
of the enterprise system.
We have already used terms such as product, project and system on several occasions so it’s probably a
good idea to set down a few firm definitions so that it is very clear exactly to what we are referring:
A project is defined by a clearly visualized goal e.g. to develop the network and intranet components of
a new order entry system for company xyz.
A product is the software delivered to the client or customer, possibly consisting of numerous
components, which will satisfy the goals set out in the project.
A system is every component of an enterprise project, including Visual Basic components, infrastructure
components such as the physical servers or databases, third party components, etc. It includes everything
required to fulfill a certain set of business requirements.
Companies today operate in an ultra-competitive marketplace in the face of rapid advances in technology.
In order to prosper, they must constantly review and reassess the technology they have in place and the
manner in which they conduct their business. A company may be involved in a continuous process of
updating its enterprise systems. This cannot be carried out in a haphazard fashion. The company must be
very clear what it wants to achieve and why. Goals must be analyzed closely and prioritized. Each project
undertaken in the enterprise development must encompass a clearly defined goal. The project must be
carried out with a view to producing a final product that is of the best possible design, embraces all of the
required functionality, and is delivered on time.
The best way to achieve this, in my view, is to break each project into well-defined, but often overlapping,
phases. These phases, considered together, form a cycle - since they can be repeated endlessly as the
enterprise system evolves. Thus we have the cyclic methodology that is at the heart of my Visual Basic
project management philosophy.
This cyclic methodology shares many features with other methodologies based on repeated
stages, such as the Microsoft Solution Framework.
Of course, project management is not just about having a good methodology in place. A methodology is
only really as good as the team that implements it. Even relatively simple sounding projects, such as the
design of a new order entry system, can be very complex. Such a project may involve:
A new Visual Basic application which will enable the order entry clerks to enter orders by phone
A new Internet site that can display products to clients over the Internet, and allow these clients to place
orders
A set of Visual Basic components to move the data from a database to a data warehouse
A new set of programs to perform analysis on the data
8
Introduction to Project Management
In a sense this illustrates some of the key advantages of projects based around a Visual Basic object-
oriented approach:
The project is easier to break down into component parts, which may be completely different in nature.
This is known as modularity.
Such projects lend themselves very well to a team-based methodology. Small, closely integrated
development teams could work on the creation of different product components, either in parallel or
sequentially.
In practice this is more difficult than it sounds. Design work on one component almost always impacts the
design of others. This is one of the reasons that small, tightly integrated design teams are almost always
more desirable than large teams so that the communication between team members during the highly
changeable design phase can be fast. Even having said this, it is very clear that without proper management,
the project could very quickly spiral out of control. Effective project management is an essential function
within every project. It helps to coordinate the work of every team member, not only so that the work gets
done and the project is brought to completion, but also so that every team member will know what he or she
has to do, why they have to do it and when they have to do it by. Project management is not just performed
by the project manager: every member of the team is responsible for the successful management of the
project, and so every member of the team should know what good project management entails.
Managing a Visual Basic project can be compared to driving a car. By following a certain set of rules,
carefully planning where you are going, keeping an eye out for road signs and road hazards, and responding
to them when they arise, your chances of getting to your final destination without having an accident
greatly increase. While you can easily find a book on the rules of driving, it is very difficult to find a book
explaining all of the rules one must follow for managing a Visual Basic software project. This book is
specifically written to provide a methodology for developing Visual Basic products that will be part of a
larger enterprise system project. The cyclic methodology I discuss in this book will allow you to see the
road signs and road hazards that may “total” your project if you miss them, show you how to respond to
them, and how to plan your entire project for maximum success.
While this book is written with the project manager in mind, it is also for all members of a Visual Basic
team. In the cyclic methodology, everyone shares responsibility for the project and for making the project
succeed. This book will provide the project manager with all of the information they require to oversee the
project and the team. The project manager can also share this book with the entire team to provide them
with the information they need to know to enable them to be part of a team in which every member works
toward the success of the project.
Visual Basic project managers often lack technical knowledge. Their ability to lead
effectively may be hampered by a lack of credibility within the team if they are not
able to understand and discuss critical design issues. They may not understand the
impact that the particular technology chosen for the solution has on the manner in
which the developers go about their coding. Without this knowledge they may be
unable to properly coordinate the efforts of the team and will be less likely to be
able to make realistic estimates of schedule and resource requirements etc. This
book aims to build a bridge between project managers and developers. It will give
project managers a fundamental understanding of some of these issues.
9
Chapter 1
Before we discuss object-oriented programming, project management and the cyclic methodology, we must
first expose and dispel a few myths associated with managing projects.
Company Size (in Successful Projects over budget Projects 100% or more
dollars of revenue) Projects or schedule, or over budget or schedule, or
delivered with impossible to complete
incomplete
functionality
500 million or greater 9% 62% 30%
200 to 500 million 16% 47% 37%
Less than 200 million 28% 50% 22%
This high rate of failure has been validated in more recent studies. It would seem that the larger the
company, the more likely it is that the project will fail. This may be due to the fact that larger companies
attempt larger, more complex projects than smaller companies - as size and complexity increase, so does the
chance of failure. Nevertheless, the table presents some frightening statistics.
Are software projects doomed from the beginning, or is there a way to improve the chances of your project
succeeding? To answer that question, we need to look at the reasons for these projects failing. The top four
reasons for failure were as follows:
If you follow the techniques of project management discussed in this book, you will be in a better position
to manage and probably reduce the risks posed by of all four of these problems.
10
Introduction to Project Management
The study also found the following reasons for project success:
Finding a way to achieve these essential elements of a successful project will be a central focus of this
book. While there may be several ways to manage a project so that it will contain these essential parts, with
this book I aim to demonstrate that one of the best ways to achieve them is to build your Visual Basic
project using the cyclic methodology.
Adding a single module to the code, and making this module work with the rest of the code, could take
weeks. Each step forward is now a slow, and very painful process. The last third of the project may take
longer than the first two thirds of the project put together. More often than not, a Visual Basic project will
die a painful death at this point. Everyone walks away cursing Visual Basic, when, in reality, all of this
could have been prevented if everyone had spent a few days or weeks designing the development of the
project thoroughly.
The cyclic methodology detailed in this book allows the developers to design a set of components that will
fulfill the goals of the project as specified by the end users and management. The cyclic methodology
requires the developers to be creative and use all of their skills to come up with the best possible design for
the components within the scope of the project. Designing these components, and basing them on the needs
of the end-user and management, is the first goal of the developer: in fact, every member of the team must
keep the user, and their needs, in mind at all times, as this methodology is very user-centric. Actually
building the components is the second, and most important, goal of the developer. In this way, the
developers create their own goals based on the goals of the end users and management.
11
Chapter 1
The final design is detailed enough to say what the code in the components should do, without specifying
the exact details on how the code will be written. Thus, the creativity of the developers will once again
come into play when they implement the design into actual coded components. We will discuss the
importance of creativity of all team members throughout this book.
Every object has characteristics or properties. For example, some characteristics of a computer are its
dimensions, its weight, its color, etc. In object-oriented terms, the computer object would have properties of
size, weight, color, etc. Objects are also able to carry out actions - these are called methods. Using our
computer object, we can see that one method could be called SaveFile, which would allow the computer
to save files, whereas another method could be called ChangeColor, which would change the color of
text on the screen.
Another example would be to use the order entry application. The application can use a Customer object.
This Customer object will have methods that perform services, such as updating a customer’s information
to the database or deleting the customer. The Customer object will also have properties, such as the
customer’s name, address, phone, fax, etc. These properties can be set to new values or be used to retrieve
the current values of these properties.
All objects belong to a class. A class is a template for a particular type of object; in real life terms, a class
would be, for example, the blueprints for a computer. From the blueprints we could see that they
represented a computer - however, it wouldn’t be an actual computer. To make a computer we would have
to take the blueprints, get some materials and build a computer. In object-oriented terms, we would have to
take the class and ‘build’ an object, or, in other words, make an instance of a class. So, when we make an
instance of a class, we get an object. If we make multiple instances, we get many objects. One important
point to note is that, even though each object is built in exactly the same way from the same class (or same
set of blueprints), each object exists in its own right - it is not the same as all the other objects.
12
Introduction to Project Management
Abstraction allows us to view things in general terms and not get weighed down with details. If I ask “what
is a computer?” you will instantly know what a computer is. I don’t have to tell you that a computer is a
box with a processor and memory and a monitor and an input device, etc. So, a computer is an abstraction -
we know that a computer is a collection of other objects, but we don’t need to know every single object,
just the fact that they are included in the description of a computer. Abstraction allows us to make sense of
our code - if we have somebody in the order entry system who can choose a product, place an order and pay
for an order, we don’t want to have to go through every item when we want to describe the main object. If
we call this person a customer and say that it can do these things, it will be easier to explain to everybody,
and people will know exactly what you mean without you having to go through every single detail.
Building Components
When we are actually making our Visual Basic project, we will use components. Components are simply
sections of precompiled code relating to a specific topic - for example creating a new customer or adding an
order. Because a component is precompiled, it does not matter what programming language it was created
in. During the course of the project, we will be using components that are already built, such as a text box
or a form, and other components that will have to be built from the beginning, such as the customer or order
components. When we have to build our own components, we will use one or more Visual Basic classes to
make the component. For example, we could build a customer component from two classes arranged in a
hierarchy. The bottom class will contain the properties for the component. The middle class will manage the
bottom class by retrieving instances of the bottom class and providing methods to create new customers,
delete customers, etc. These two classes will be joined together to create a customer component. When the
application is running, this component will allow you to retrieve, add or delete customers, and also to get or
set information on a customer.
When we build an object, we should consider it as making a contract. This contract says what services
(methods) the object will provide, what properties are available for reading (that is, which properties we
can get the values of), and what properties are available for writing (that is, which properties we can set).
The contract will also state if there are special conditions for reading and writing properties, such as only
having write privileges when adding a new object. When making objects, the contract is officially signed
when the classes are compiled into a component. Once the contract is signed, we agree not to change any of
the existing properties or methods.
Unofficially, the contract is created when the design of the component is created. Once the design is
complete, and the methods and properties of the component are determined, other components will be
designed and built based on this design.
13
Chapter 1
If you should change any of the methods or properties after the design is complete, you will have to
redesign and rebuild all of the components that use the redesigned component. Even worse, if you change
the component after it is compiled, you will have to un-register the original component, register the new
version, and make all the changes to the dependent components. Both of these scenarios could take days or
weeks of work, putting the project behind schedule and budget. This is why we should view the design of
our components as a contract. The way to make sure we can honor the object contracts is by carefully
designing our components.
It is true that building object-oriented products using the cyclic methodology will require developers who
understand how to build object-oriented components, but this is only one requirement for building these
products. You do not just have to know how to build object-oriented products to undertake an object-
oriented project: the development of an object-oriented product will also require a special team structure,
management technique, and design method.
A detailed design methodology is critical for object-oriented products: without detailed design, even the
best object-oriented developers will fail to build good products. With the cyclic methodology, design is just
one phase in a carefully orchestrated process and, like the others, is a stage that involves everybody within
the project team, not just those who will go on to develop the actual code for the component. Every member
of the team will contribute to the success of the project, creating a team of peers. This is a critical element
in a successful object-oriented project. This book will discuss all of these issues.
During the envisionment phase the entire system is defined. It is a very thorough assessment of what the
company wishes to achieve and why. The goals of the entire system are defined and prioritized. This
provides a direction for all of the projects that will need to create the system. The scope of each individual
project is also carefully defined. The design phase defines the components and services that are required to
meet the requirements set out in the envisionment phase. During the development phase the components
are built, unit tested and assembled into a final, compiled application. The deployment phase focuses on
testing the final complete project and finding and fixing bugs.
14
Introduction to Project Management
We can see the advantages of the cyclic methodology (married with object-oriented programming) when
applied to vast enterprise projects, as well as to projects to create a single product (such as new company
web site). As was mentioned earlier, enterprise projects may totally redefine the manner in which a
company goes about its business and can evolve over many years. The approach I have outlined has several
advantages:
The pace of technological advance is rapid - new versions of software appear with alarming regularity.
Rebuilding the corporation in relatively short, well-defined cycles allows the corporation to quickly
adapt the business processes to a rapidly changing market.
In large projects it is likely that by the time the development of the last product component has been
completed, several years may have passed since the first of the components was begun. By that time, it is
fairly certain that the technology and Visual Basic will have once again evolved and changed. While it is
impossible to predict what those changes will be, and what opportunities they may open for this
company, developing object-oriented components makes it much easier to add new functionality.
Adding new functionality is never as simple as it seems - there are many areas to consider,
such as possible rewriting and probable retesting of the component: all areas which will be
explained in more detail later in the book
Bear in mind also that the very nature of certain products (e.g. web sites) requires that they be built in
cycles. The first cycle may create the initial site with the basic required functionality. Based on close
analysis of how the site is used, the cyclic methodology allows the scope of the product to be continuously
refined so that it always uses the most up-to-date and efficient technology.
Each of our four phases will have a set of goals. Each goal should have:
Each phase of the methodology is associated with a set of deliverables. These are the tangible results of the
work that has been performed. A deliverable may consist of UML diagrams (you will see more on these
later), code modules, risk documents, master schedules, etc. These can be given to all members of the team
for review and approval.
The completion of each of the four phases will be a well-defined, measurable point in the project, known as
a milestone. As each milestone is reached the team must assess whether the customer’s requirements are
being met and whether the project is on schedule. It is highly recommended that each milestone has one or
more associated deliverables. The deliverables will be signed off by the project manager and can be used to
determine whether a project is on schedule. When the milestone for a phase has been reached, (which means
that the deliverables have been created and completed) you may move onto the next phase. There are no
entry requirements for moving into a phase, except that the last phase’s milestones must have been
completed. Thus, when the final milestone of the first phase is complete you can then move the entire team
onto the second phase.
15
Chapter 1
An example of a milestone is as follows: you say that three months from the beginning of the project (or
any other pre-determined date) you will have a certain set of documents completed. The documents are the
deliverable. At the end of the three months, you either have a completed set of documents signed off by the
management, developers and end users, or you do not and the project is behind schedule. When something
is either true or false, it is called binary. All of your milestones should be based on binaries so that we can
determine the progress of the project. These milestones are essential for a software project. Each of the four
stages will have milestones marking the end of the stage, as well as several milestones within the stage to
monitor progress. Each of these milestones will either have happened by the pre-determined date, or they
will not have happened. If they have not happened, the project is behind schedule, and the entire schedule
may need to be reassessed.
Once one project cycle completes, the cycle of the next project cycle will begin. When all of the initial
development projects are complete, you will then move into the maintenance stage.
When maintenance needs to be performed on the project, another new cycle will be created. Maintenance
will usually occur because of some new requirement that did not exist when the project was originally
created. For example, an order entry project made four years ago would not have included e-commerce. It is
likely, however, that the order-entry application would need to be expanded to also allow orders to be
placed by the client over the Internet, in order to remain competitive. This additional Internet component
would need to be developed within the four phases. In this way, the cycles never end: the product is always
evolving and changing to meet current business requirements.
16
Introduction to Project Management
Envisionment Phase
During this first phase, the entire system is defined, and vision and scope statements are created. A vision
statement states the goals of the entire system and provides a direction for all of the products that are
needed to create the system. The scope defines the limits of each individual project. Thus, the vision may
be to create a revised order entry application (either for use internally or for an external customer) that
works on the Internet, an intranet, over the network, is capable of increasing sales by 100%, and able to
provide detailed information on sales for management. The scope of the first project might be to create the
network and intranet components of the application and increase sales by 40%. Future projects may exist
that will fulfill the complete vision statement and additional features can be added at a later date.
Vision and scope statements make sure that the right problem is being solved, which will allows the
company to properly plan the rest of the project. Without knowing what the project is supposed to be doing,
and why the project is doing this, it is impossible to design or build the project. While this may seem
obvious, projects often begin without any clear definition of what they are supposed to be doing, and end up
moving haphazardly until either a clear definition is created or the project fails. A project without a clear
scope will also suffer from feature creep - features being added throughout the development of the project,
rather than being part of a new project. A clear scope freezes the features of the project at the very
beginning.
To be able to identify the vision and scope, this phase must go through the following steps:
The sponsors, who are the people who will provide funding for the project, must be involved from the
beginning. It is important to understand their vision and scope of the project, and to make sure that they are
committed to the project. Standards for the project must also be defined. If the sponsor is unwilling to get
involved or is not interested in the project, there is virtually no possibility the project will succeed. If the
sponsor does not feel the project you are building is the correct project for the system being created, it is
also likely to fail.
17
Chapter 1
A consensus meeting is where all members of the team are brought together to discuss the project. It is
essential that these meetings involve the entire team, including the end users. If possible, the sponsors and
the stakeholders should also attend. If the sponsors and stakeholders cannot attend, a summary of the
meeting should be presented to them to review and approve the results of the meeting.
A consensus meeting should be held at the beginning of the phase to discuss what the vision and scope
should be. Goals, resource availability and deliverables are part of this discussion. Another meeting would
be held once the vision and scope documents are complete to make sure all team members agree with the
contents of the document. If all members of the team agree with the vision and scope documents at the
second meeting, this phase is complete.
The primary purpose of the envisionment phase is to reach a vision and scope that all members have agreed
upon. The vision will describe what will be in the entire application. The scope will put limitations on the
project vision, and define what part of the vision this project will create. There should also be a clear
explanation of why the project is being built. The reasons should be focused on the business processes and
goals of the corporation.
Enterprise Architecture Document: Before the project can begin, you must take a look at the current
status of the enterprise. This document will detail what the enterprise consists of before the project is
undertaken. This will determine if there are the financial, technological, and people resources for the
project.
The primary deliverable is the vision and scope document. The vision document should contain the
following sections:
The vision statement of the project: The vision should be stated in terms of goals of the project.
The scope statement of the project: The goals that will be accomplished by this project, that is, this cycle.
This should define what will be done in this project and what will be delivered at the end of this project.
Team Responsibilities: A list of responsibilities of all the team members should be created during this
phase. The list should detail when specific responsibilities need to be completed, (a list of important
deadlines) and provide a list of risks to the project that may occur if each team member does not complete
their agreed upon responsibilities.
Risk Assessment: A complete list of all risks to the completion of the project should be carefully
documented. Examples of some major risks are:
18
Introduction to Project Management
The vision and scope document represent a view of what the goals of the project are, why the system is
being developed, and how these goals will be reached. These documents must be accepted and signed off by
the entire team, including end users and sponsors.
Design Phase
This phase consists of creating a set of documents that define the user requirements, defining the
components and services that are required to meet these requirements, and documenting a detailed design of
these components. The design phase will make sure that we have properly defined the solution.
We know from our earlier discussion that we must be able to create reusable components, build one part of
the system at one time and build another part either in parallel or later. The system must also be able to be
upgraded so that it can include future changes that we cannot predict. The way to do this is to build object-
oriented projects: We will now discuss the special design considerations of such a project.
This enterprise solution will be built from components. If, at some later time, a component of the system is
found to be based on an outdated form of technology and needs to be upgraded, this component can be
redesigned and replaced without redesigning and rebuilding the entire system. If a new component needs to
be added, it needs to be added to the project design, built, and added to the project without affecting the
existing components.
Parts of the system that are critical for the corporation can be built in the first project cycles (as defined in
the envisionment phase). Less critical components can be added to the system in later cycles. As new
business requirements evolve, new components can be designed and added to the system, but always as part
of a well-defined cycle with carefully analyzes goals. This type of enterprise solution can adapt to any
changes in the market place or technology. As we have said, the best way to build a project with
components is to create an object-oriented project.
19
Chapter 1
This type of design will result in a user-centric approach that means that the project takes advantage of all
of the available technology and will be built from components. The most critical components can be built
first, and more than one component can be built at any given time (as each component is a separate entity).
This will also create a design that takes into consideration the needs of the users, the needs of the
developers, and the possibilities and limitations of the technology.
Once the conceptual design reaches a point where it seems to meet all of the users’ requirements, the design
of the project moves into the logical design stage. It is possible that during the physical design stage a user
requirement will be discovered that was overlooked in the conceptual design phase. These missed
requirements must be added to the conceptual design, refining it even more.
The logical design phase will consist of mapping out all of the services the components must perform. Each
service can be traced to one or more business needs. The initial logical design may only include some high
level services for the users, such as getting customer or product information. The logical design stage can
then be refined by adding the services that will not be visible to the users, such as retrieving data from a
customer object. The logical design will also be subject to much refinement.
When the logical design seems complete, the physical design begins. A thorough review of the current
technology is made. The technology solutions that will create components that will perform the services
efficiently must be chosen. Often, several small test applications will be created to find the best technology
for a particular project. Test applications can also determine the most efficient way to use the best
technology. An initial concept of the physical design is created and numerous tests will refine and define
the physical design. It is likely that there will be missed services that will have to be added to the logical
design during the physical design stage.
The completion of each stage of the design phase represents an interim milestone: a measurable, definable
point in the project. When the conceptual design milestone has been reached there will be a clearly defined
non-technical description of the product, the functionality it will include and the manner in which the users
will interact with the system. The deliverables for the conceptual stage will include a set of documents
describing the users’ goals for the project, which will most likely be a set of UML use cases.
Use cases are documents that explain how a particular group of users, called actors,
will use the system to perform a particular task. You will see examples of these in
chapter six.
20
Introduction to Project Management
When the logical stage milestone is reached, the deliverables will include a set of documents that identify
the components, and the services the components will need to perform, to fulfill the users’ goals for the
project.
Since it is the goal of the developer to actually build the components, and it is also the
developer who will fill in the details of these diagrams, it is important to remember that such
diagrams define the developer's goals.
The most common way to document these goals is with UML Sequence diagrams. Sequence diagrams
show the requests for services between the users and the system and between one component in the system
to another component in the system, over time. Sequence diagrams convert the verbal Use Case into a
visual diagram. You will see more of these in chapter seven.
In addition to these documents, the following deliverables may also be part of the logical stage:
A user interface prototype (how the user will use the system)
An evaluation of the user interface prototype
A user interface specification
Small test applications to test new technology and new solutions
An evaluation of the test applications
When the physical design stage milestone is reached we will know exactly what components are required
and how the components will be coded, built, and distributed. These components should fulfill the goals of
all members of the project. The deliverables of this stage will be a set of documents detailing this
information. The usual method of documenting this is by using UML class and activity diagrams:
Activity diagrams can be used to map out the code steps a component must take to fulfill a request to
perform a service. The steps are written in pseudo-code (each step is described in plain English rather
than actual code).
Class diagrams are a set of diagrams that provide a pictorial description of a set of objects with the
same attributes, operations and relationships. You will see more on these in Chapter 8.
In addition, another possible deliverable for the physical stage is a document analyzing which components
should be built in-house, and which items should come from a third party.
At each stage in the design process the following additional deliverables will be developed and refined:
21
Chapter 1
The end of design phase milestone, most importantly, should encompass a fully integrated design that
reflects the needs of the users, fulfills essential business requirements of the corporation, and puts
reasonable demands on the developers. The design must fit into the existing enterprise solution as well as
being able to help create the future enterprise solution. The design must also result in a system that is
scalable and extensible
At the end of the design phase all team members should have a clear sense of purpose. There should be a
common understanding of what is required of the product, what their responsibilities will be, what
resources are required and on what timescale they are expected to complete their work (a realistic project
schedule should be in place). Each of these issues will be discussed in detail in the corresponding chapters.
I would like to stress again at this stage that good communication will be the most essential ingredient for
success of the project. Communication will have to flow between managers, developers and users. A set of
documents that include design specifications and UML documents can form the basis of good
communication. Communication also includes learning certain skills. Some important communication skills
include: interviewing users, explaining the conceptual design to the users, and getting management
involved in the project. All of these skills will be required to be a team member of an object-oriented
project. We will discuss team characteristics later in this chapter.
Development Phase
The development phase consists of the building and initial testing of the components and the assembly of
these components into a final, compiled application. This phase is complete when all new development is
complete. This phase will allow you to implement the best possible solution. After this phase is complete,
any additions to the product will result in a new project (a new cycle beginning). It is likely that there will
be future additions, as the vision statement extends beyond this project, which is limited by the scope
statement. In this way, there are many cycles as the product evolves.
This phase will consist of building the components based on the design made in the design phase.
Components will be built at the same time or sequentially. After each component is complete, it will be
tested by itself (unit testing), and then within part or all of the system (system testing). The testing will be
based on a careful plan made by the testers based on standards created by Quality Assurance. Before the
components can be built, the design of the system, the schema for any database, and the design of the user
interfaces must be frozen. This will prevent feature creep, and also prevent rebuilding entire components.
Changes that are made once the coding has started are more expensive than making changes before any
components are actually built. It is fairly easy to change a design document. The further along you are in
coding a component, the more expensive any changes become. This is why it is essential that all team
members sign off the design before coding begins.
22
Introduction to Project Management
There are many interim milestones and associated deliverables in this phase, including:
In the development phase developers must put to good use the design documents that reflect the goals of the
entire team and must find the most effective and efficient way of building the project within the limitations
of the current technology. It will be important that standards created in the conceptual design phase are
followed, especially coding and user interface standards. The development phase is where the project is
actually coded and built. The bottom line is that the final outcome of this phase must be a project that
reflects the best possible solution to improve the business process.
Deployment Phase
When the development stage is finished the project moves into what is termed a “stabilization” phase as the
team works toward the release milestone when the product will be shipped and deployed. The deployment
phase is where the final testing is completed. The developers fix any problems with the project as they are
discovered. Thus, the primary focus of this phase is finding and fixing bugs. Debuggers, and possibly the
end-users, will be testing the project, and the developers will be fixing any problems they find with the
product. As the release milestone approaches all training aids and help files must be completed and the
infrastructure for the new product must be in place.
When the project is complete, stable and there are no longer any problems with it, the project is turned over
to the end-users and to the operations and support groups. The completed project is the final deliverable for
this phase. It is sometimes called the golden release, essentially being the master copy of the final solution.
Deliverables
There are several deliverables that will occur in this phase. A few of them, not listed in the order they will
be completed, are as follows:
23
Chapter 1
There are six different roles in the software development team, some of which have been touched upon
already. People from the developer group will most likely fill the first four roles - development, testing,
logistics, and user education. The last two roles, product and component management, will most likely be
filled by people in the management group. A definition of the six roles is as follows:
Development: The team members in the development role are responsible for building the components
defined in the logical stage of design, as well as creating test applications during the logical stage of design.
Members in this role will also make sure that the components are built according to user requirements,
make recommendations for technical solutions and coding standards, review testing plans, keep the project
within schedule, repair bugs in the components, and integrate the components into a working whole.
Testing: The team members in the testing role will make sure that all of the components function
appropriately and that there are no bugs in the code. Other responsibilities include making a test plan that
will test each component separately and within the entire system, building test cases, developing automated
tests, documenting all bugs, and helping to build a high quality product.
Developing test cases is a very important activity. They specify how a product will be tested
in the next phase of the cycle and, critically, ensure that the product complies with the
required quality and performance standards.
Logistics: The team members in the logistics role are responsible for integrating the finished product into
the enterprise system and the movement of the product into the support and operations groups.
User Education: User Education team members will make sure that the users understand how to use the
application, provide training for the user, and work towards making the application easier to understand and
use. These team members will be responsible for creating user interface prototypes, setup programs and
help files, training aids and all user documentation.
Product Management: The product management team members will create a vision of the project, turn the
users’ requirements into a coherent set of UML use cases, create the conceptual and logical views, and
make sure that the client's requirements are being met. Other responsibilities include making business
projections, estimating the cost of the project, and defining key business goals and requirements.
Component management: The team members in this role will be responsible for making the critical
decision necessary to create the right project at the right time, ensuring that the project maintains enterprise
standards, managing the master schedule, and managing and documenting project changes. They will also
work with other team leaders to create the logical and physical views.
24
Introduction to Project Management
Project Manager: In large projects with many teams, the ultimate responsibility for the success of the
project may rest with a specifically designated project manager. They would coordinate the efforts of every
other team member. For smaller projects this responsibility will rest with a component manager
(alternatively referred to as a program manager).
End Users: These are the people who will be using the project’s final deliverable (the finished product) on
a day-to-day basis.
Sponsor: This will include anyone responsible for the funding of a project. Ideally, this should be one
person, but it can include several people.
Reporting Manager: This is the manager who will evaluate the performance of team members and create
evaluation reports. However the reporting manager has nothing to do with making project decisions and is
not necessarily part of the project team.
Failure to view the end users, sponsors, and stakeholders as members of your team will almost guarantee
the failure of your project. Members of all three general groups - management, development, and end users
- need to be involved in the project from the beginning to the end and sign off all documentation.
If the project includes building a database, you will also need to add data modeler and database
administrator roles. These two team roles will be involved in the design of the database, the structure of the
database, finding ways to optimize database components and the design of the data components.
25
Chapter 1
If there are only a few developers for a project, it is possible that one member can play more than one role.
Some roles, though, conflict with each other. We will discuss this in more detail in the chapter on teams.
Several small teams, consisting of a component manager, developers, testers, and a person from the user
education team, can be used to build these components either at the same time (in parallel) or sequentially.
Developers, testers and user education team members should share information with their counterparts in
other teams to create a uniform set of components. The number of testers to developers can range from a
1:1 ratio up to a 1:3 ratio, depending on the project. The project manager will determine the best ratio for
the project. To better help testers understand the user requirements the testers should join the project from
the beginning, if this is possible. The project manager will coordinate the teams and will also put together
the vision and scope statement based on the consensus meeting. The component manager is responsible for
putting together the documents for the conceptual and logical design views based on documents created by
the smaller teams. The project manager will be in charge of the master schedule.
Using small development teams allows for better communication between team members, low management
costs, faster implementation of the various components and a higher quality product. Creating the physical
design for these components, and building these components, will be the responsibility of the small
component groups. Each component group must build their component so that it exposes the methods and
properties specified in the logical view. The internal workings of the components, as well as every
deliverable of the whole system, should be based on enterprise wide standards of coding and design.
These component teams should be a team of peers. Every member should be equally responsible for the
quality of the component, meeting schedules, understanding the client’s needs, and contributing to the
design and building of the component. The entire team should be focused on fulfilling the users’
requirements, identifying risks, keeping the project within budget and time constraints, and making the best
component possible. Each team member will have a well-defined role and will submit a schedule for their
component, which will become part of the master schedule (you will see more of this in later chapters).
26
Introduction to Project Management
Summary
Visual Basic projects have become more complex as the language has become more powerful and as more
complex products are being created with the language. To build efficient Visual Basic projects that meet the
needs of the enterprise we need to find an effective methodology to control them. This book will cover the
cyclic methodology, which will empower you to build powerful Visual Basic products that will bring the
enterprise into the twenty-first century.
The cyclic methodology is based upon the idea of breaking the project into four phases: envisionment,
design, development, and deployment. The design phase can be further divided into three small stages:
conceptual, logistical, and physical. The members of the team building projects that use the cyclic
methodology will all equally share the responsibility for building and creating the project. Everyone on the
team has input on the outcome of the final project. By using the cyclic methodology we can build Visual
Basic projects that:
In the next chapter we will discuss the roles of the individual team members. As each team member will
share the responsibility of managing their own time and resources, and also need to be able to contribute to
the documents and communicate effectively with other team members, all of these topics will also be
discussed in the next chapter. The rest of the chapters will cover the four phases of project management and
also cover tools for scheduling, risk assessment and bug tracking.
27
Chapter 1
28
Teams
A Visual Basic software team consists of a group of people who work together to fulfill a set of goals that
represent the needs of the client and their business. As we will show in this chapter, if you are working on a
Visual Basic software team within the cyclic methodology outlined in this book, you will:
This type of team does not focus on who is in charge. Instead, a set of team roles is created. Each role will
have a well-defined set of responsibilities. Instead of having an autocratic project manager who dictates
what everyone in the team is doing, we will now give each team member a set of responsibilities that they
must accomplish. The project manager has the responsibility of reviewing the recommendations of the team
members, putting together a schedule for the complete project, based on the schedules submitted by
individual team members, and of producing overall, unified documents, such as the vision/scope and design
documents, based on input from all of the team members. The project manager will also manage the
resources and make sure all of the critical goals are being accomplished.
When working within this team structure, it is likely that there will still be a reporting manager who will
evaluate the performance of team members and create your evaluation reports. However, the reporting
manager may not be a member of the software team.
Chapter 2
The job of the reporting manager is to make sure that everyone has met their responsibilities for the projects
they have been part of. If the reporting manager is part of the project team, he or she can make this
evaluation directly; otherwise, the reporting manager will have to speak to the project manager.
If you successfully meet your responsibilities, you can continue in the role you are in, or move up to a role
with more responsibilities. If you are not able to meet your responsibilities, then it is likely you will either
require more training, coaching, or perhaps even need to be placed in a role with less responsibility. As
long as you are willing to put the time in, to learn new skills and improve the ones you have, you should be
able to remain in your current position or advance. Ideally, if you are a regular employee, your company
should allow a certain number of hours every week in your schedule for training. With the constant changes
in Visual Basic, Microsoft Back Office and Enterprise technology, it is essential that all team members be
given some time to train in both technical and non-technical skills.
The reporting manager has nothing to do with making project decisions, and only
evaluates whether or not the team members are fulfilling their responsibilities. A
reporting manager is part of the organizational chart of the company and has
nothing to do with the structure of the software team. Team members can come
from many different parts of the company and can belong to completely different
groups in the corporate structure.
This chapter will list some important non-technical skills that you will need to be a successful member of
this type of team. We will also provide you with suggestions on how to improve these skills.
In this chapter you will learn about the roles within a software team, skills you will need to possess to be a
successful member of this team, and how to manage and schedule your time.
30
Teams
They were experts on the system they managed. This type of manager would know exactly what to do to
speed up or slow down one part of the line, how to improve quality and where costs could be cut. These
managers could walk past a machine, hear a squeak in the machine and know if that was normal or
abnormal. If it was abnormal, they would get advice from the floor mechanic, and then make a decision on
whether a repair was needed. This decision would be based on a full understanding of how taking this
machine offline would affect production and whether it was serious enough to do so. These capabilities
were based on years of working with the same machines and the same processes.
We can see from this example that since autocratic managers have full decision-making power, they need to
be expert in the system they manage. They need to know how to improve the system, how to make it work
better, more cheaply and more efficiently. They also need to know when they should ask a question and
when something is not serious enough to get advice on. To do this, they need experience based on years of
working with the system.
While I have worked with SQL Server for four years, the majority of what I knew about administering a
SQL server database became redundant with the release of version 7.0. The file systems in this version are
completely new, and version 7.0 has added Data Transformation Services. Can anyone claim to be an expert
in a technology that is less than a year old?
Two years ago Visual Basic programmers were making two-tier monolithic applications. Over the last two
years, Visual Basic developers have started to abandon this method of programming for three-tier object-
oriented programming with Windows DNA. While I may have six years experience as a Visual Basic
programmer, my experience as an object-oriented Visual Basic programmer only extends back a few years,
as these methods did not exist prior to a few years ago.
There are a few basics of development that will never change, such as coding standards and methods of
project management. However, most of what is done in a Visual Basic project is less than two years old and
a good portion of it is less than a year old. Many developers are working on the cutting edge with
technology and techniques that are one to six months old.
In any Microsoft development project, an autocratic manager will usually fail. No single person can
possibly have the wide range of expertise and knowledge required to make the appropriate decisions. Even
worse, they will often have no idea that they need to get advice from their subordinates. This means that
they may not properly manage risks to their projects.
31
Chapter 2
When placed in charge of development teams, autocratic rulers will usually rely on what they know and are
familiar with. Unfortunately, this is likely to be outdated technology, and this has resulted in many IT
departments developing solutions that do not meet the business needs of the corporation. In the long term,
this causes the corporation to become uncompetitive and eventually to fail. As the technology evolves past
their expertise, autocratic managers do not know how to identify risks properly in these new situations and
often miss important warning signs. Only when a crisis has been reached does the autocratic manager
realize there is a problem, and by then it is usually too late. Even when a project can be saved, it usually
leads to a development team jumping from one crisis to another. Hours become long, extending into late
nights and weekends in order to deal with the latest crisis. Team members burn out and move on.
Some autocratic managers struggle to master every element of development and spend every minute
studying, reading and learning. A few of these succeed in mastering the breadth of knowledge for
development work, but most of them do not. It is not impossible to be an autocratic project manager, but it
is extremely difficult. If you are a project leader and are looking for a better way, this book will show you
one.
This chapter will describe the fundamental characteristics of a Visual Basic self-directed work team. This
chapter, and the entire book, is not written just for the project manager. It is written for the entire team, as
everyone on the team must contribute to managing the project, managing their time and managing the risks
to the project.
While this idea may seem radical, it is just good common sense. You only need to look at any corporation
that teaches a project management discipline to all of the team members to see how successful this method
is. I know of one major consulting firm that went from doing no development work to over ten million
dollars' worth of development work in a little over one year, and from a staff of four to forty in that time.
This company has not had a single project failure and has been successful with numerous large, complex
projects. What was the key to their success? Every new employee received extensive training in the
methods of project management that the company used, even the new programmers.
A common way of doing this is what is called "training the trainer". In this system, a select group of people
is given training, and in turn they train others in the corporation. I know of one Fortune 500 company which
trained its project leaders in a project management methodology; they then went on to train the rest of the
team.
32
Teams
If you are a project manager, read this book from cover to cover. Learn this way of managing a project, and
then pass this book around to your team members (or get them a copy). Every team member should
understand his or her responsibilities, how to manage risks, how to manage a schedule and what is expected
from them during each phase of the project. Once they have this understanding, they can begin to contribute
effectively to a collective knowledge base which the team can use to work together to find solutions with
rapidly changing technology.
Team Structure
You, and every member of the team, will be responsible for the success of the project, meeting the client's
needs, improving your skills, scheduling your tasks, and meeting your schedule. The tasks you will perform
will depend on the role you assume in the team. The roles for the software team, as we listed them in
Chapter 1, were project, product and component management, development, testing, user education, and
logistics. Product management, user education, and logistics will all work with the client.
The client can be either external to the corporation or internal to the corporation. There is
little difference between these two situations. Therefore, when I refer to client it can mean
either an internal or external client.
Component management, testing and development will have relatively little one-on-one contact with the
client and will focus on creating the project components. However, team members in these roles will be
involved from the very beginning of the project in meeting the needs of the client. They will have contact
with the client during meetings to discuss design and other issues.
The number of people within each role will depend on the number of people available, the size of the
project, and the number of end-users and stakeholders. It is best if there is only one stakeholder, so that
there is one person who can make final decisions. In this case, one product manager for the project may be
sufficient. As we said earlier, a one to one ratio between developers and testers is best. For smaller projects,
or when the team is shorthanded, there may be two to three developers per tester. To properly use these
testers there must be a good testing plan in place. The number of logisticians and educators depend on the
number of end users and what will be required to set up the final project.
When a team is very shorthanded, certain team members can play more than one role. Some roles conflict
with each other and so the same person should not be in both roles. An example of this would be the tester
and developer (though one developer testing someone else's code will probably not be a problem). Other
roles, such as educator and tester, can be performed by the same person. The following lists give some
guidelines on which roles are incompatible and which may be held by a single person.
33
Chapter 2
Roles that have no conflicts but would be difficult for one person to do both:
The advantage of creating a team from roles is that you can build a team from a group of people who have a
wide range of skills and still have everyone find a role that they can perform well in. As each role has a
well-defined set of skills, team members can easily determine what skills they will need to assume any role.
Once the team is assembled, decisions are made on a group consensus. If the members of the development
team cannot reach consensus, the component manager will make the final decision; where the disagreement
is between teams, rather than within a single team, it will be the project manager who must make the
decision. Where consensus between the client and the software team cannot be reached, the stakeholder or
the product manager will make the final decision. This means every member needs to understand how to
make decisions, and how to participate in group meetings and discussions. Decisions do not always have to
be made in formal meetings: a discussion can be started by an email sent to all members of the team. Each
person can add to this email their ideas and suggestions, including the previous responses in their reply.
The email will become a living document, containing the input of the entire team. Eventually, the
discussion will lead to suggestions or solutions and (hopefully) a consensus on which is the best solution.
Everyone on the team shares the same responsibility for making the best product within budget and time
constraints. Every team member has a right to contribute to the group and to group discussions.
34
Teams
As team members assume responsibility for their tasks and the project, they will begin to identify with the
product. They will feel that the quality of the product represents them. This will lead to better work and a
more productive work environment.
Large projects will be big enough to have several component teams, consisting of a component manager,
developers, testers, logistician(s) and educator(s). The logisticians, testers and educators may belong to
more than one team or they may be roles filled by someone who is also in another role. The software team
will work in an autonomous manner, coordinated by the project manager. This is possible because the
software team will be building components. As long as the component supplies the appropriate public
properties and methods, it will fit in with the rest of the project. Thus, each team can build their component
separately from the other groups. Of course, best coding methods, techniques, changes in the design of any
component, client issues, etc. must flow through the entire team and to all software groups.
The logistics and component management roles will be filled by one person (who will function as the
project manager), as will the product management and user education roles. Operations support is the
client's infrastructure support personnel.
In a larger project
where there are many
people to fill all of
the roles, the project
team may look as
follows:
There are no direct lines connecting the component teams to the client groups, as members of the
component team will usually communicate to the client through the appropriate liaison. However, if a
member of the component team needs to speak directly to the client, this should be possible. If this does
happen, the appropriate liaison should be informed of what was discussed. Communication can flow from
any member of the team to any other member of the team.
35
Chapter 2
Remember that this is not a hierarchy. This figure shows the flow of communication through the group; it
does not indicate that any role is above any other. Again, the testing and development roles are likely to be
filled by more than one person.
Project Manager
The project manager is the person who coordinates the project and bears overall responsibility for it. It must
be stressed that the project manager should not be the 'boss' of other team members, and, as we have seen,
the team should be self-directed. However, every project does need someone who is able to take a broader
view of the project as a whole, and who can coordinate the efforts of other team members (otherwise, there
is the danger of developers adding functionality to show off their favorite coding techniques, rather than
concentrating on meeting the critical goals of the client.)
The primary task of the project manager is to coordinate the component managers of each individual team.
For example, each component manager will draw up a schedule for the team, and the project manager will
compile from these a master schedule for the whole project. In this sense, the project manager acts like a
higher-level component manager, and in a small project this role and that of the component manager will
probably be merged. However, when a project is large enough to incorporate many teams, it will be
necessary to include a project manager who can take an overview of the entire project.
While the project manager does drive the development process, he or she is not the
'boss'. The project manager will, though, have final authority on disputes within the
team.
36
Teams
Envisionment Phase
During this phase, the project manager will take an active part in identifying the more general, top-level
goals of the project (the component managers will be more heavily involved in identifying the lower-level,
more specific goals). The project manager will also be involved in identifying risks which apply to the
entire project (for example, the failure of a piece of key software to work as planned) and managing such
risks (in this case, by contacting Customer Support of the software vendors). Another task will be to
incorporate the schedules of the individual development teams into a master schedule for the whole project.
Product Managers
Product managers provide the channel for liaison with the stakeholders and sponsors. Because they are
working with the client's management, it is particularly vital that they have a good understanding of the
business processes of the client. The product manager works with the rest of the team to make sure that they
also understand these business processes. Product managers do not have to be developers; they only need an
understanding of the business processes of the client and have the ability to communicate and work with the
client. The product managers for a project will work with all of the component teams in the project, usually
through the component managers. A component team consists of the component manager, developers,
educators, testers and logisticians. The educators and logisticians will usually belong to several teams.
Envisionment Phase
During the envisionment phase, the product manager will be responsible for overseeing the analysis of the
corporation and the development of the Enterprise Architecture Document. This document will contain
an overview of the structure of the client's enterprise, including an analysis of the current software systems,
a description of the different business processes, and any other factors that may have an impact on the
project. This document can be used to develop a vision and scope of the project that suits the current state
of the enterprise, instead of creating a solution that is separate from the current system. In our discussion of
the envisionment phase, we will give a detailed discussion of how to create the Enterprise Architecture
Document.
In the envisionment stage, the product manager primarily works with the stakeholders and the sponsors to
help create a project vision and scope that fulfills the critical business goals of the corporation. They will
also make sure that the expectations of the stakeholders and sponsors are documented, realistic and
understood by the entire team. Product management also creates the Total Cost of Ownership (TCO) and
Return On Investment (ROI) estimates with the help of the logisticians, negotiates the contract, and makes
any client demonstrations that are required.
37
Chapter 2
The final contribution of the product manager in this stage will be the documentation of the risks of
building the product. All team members will contribute to the risk document and be able to review the risk
document; each member will also need to be fully acquainted with the potential pitfalls described in the
document.
Design Phase
The product manager will be in charge of the conceptual stage of the design phase. The product manager,
working with the educators, will determine the different types of end users that will be using the final
project defined within the scope document, set up interviews with representatives of these groups, and
either perform the interviews or assign another team member to perform them. When the end-user
interviews are complete, the product manager will put all of the use cases together in one document, review
them for accuracy, and then make arrangements for them to be reviewed by all members of the project
(including the end users).
Development Phase
During the development phase, the product manager will help answer any questions the developers may
have about the client's requirements. They will also give reports to the stakeholders and the sponsors on the
current status of the project. The product manager will be the customer advocate, and help negotiate the
removal (or addition) of goals to the scope of the project.
Deployment Phase
In this phase the product manager will find end-users who will perform beta testing (testing of the software
before it is officially released). They will do this with the educators. Once the end users for beta testing
have been identified, the product manager will coordinate between the testers and the end users doing the
beta tests. The product manager will also get the final acceptance of the project from the client.
Component Managers
The component manager's responsibilities will focus on overseeing the development process. A component
manager will be in charge of a component team that will include developers, educators, testers and
logisticians. The testers, educators and logisticians may belong to more than one team. The project manager
will coordinate the component managers within the project.
The component manager will make sure there is open communication within their team, and communicate
directly with the product manager. The component manager's responsibilities include: managing the master
schedule for the team, keeping the project on time and within budget, and overseeing any design changes.
The component manager is the leader of the development process, the facilitator of communication, and the
coordinator of the component teams. The product manager must oversee the risks documented by the team
and make sure that resources are properly allocated to reduce or eliminate the risks.
38
Teams
Envisionment Phase
During envisionment, the component managers will work closely with the product manager to establish the
design goals of the project. The component manager will define what factors and metrics will be used to
determine the success of the project, help set up the project infrastructure, and help define the scope of the
project. During this time, component management will also set up schedules and determine the software
tools that will be used for the project. They will also be responsible for the project's risk management and
version control (allowing access to all versions of the code, even after changes have been made and a new
version has been created).
Design Phase
The component managers will be responsible for bringing the design phase to the final completed design
document milestone, which is at the end of this phase. The component managers will work with the product
managers during the conceptual design stage, and will also be responsible for working with the developers
to turn use cases into sequence diagrams in the logical stage. They will also oversee the developers creating
the final set of documents in the physical stage.
Development Phase
The most important job for the component managers during the development phase is keeping the project
on schedule by properly allocating resources. The component managers will keep the schedule for their
team, monitor the milestones to make sure they are being reached on schedule and report project status to
stakeholders and sponsors. Toward the end of the development phase, the component managers may begin
working out the beta testing plan. If there are many teams, each with its own component manager, the
project manager will act as a higher-level component manager, who will oversee all of the development
teams' component managers.
Deployment Phase
During deployment the component managers will oversee the beta testing program. They will work with the
end users that the product manager recommends for beta testing and with the educators and testers.
Developers
Developers take every critical goal of the client and find a programming solution for that goal. They work
closely with the component manager to design and build the final business solution. The ideal developer is
a person who is creative, is good at problem solving, and is also able to communicate with other members
on the team. Developers are the technical experts for the team. Of course, not all developers have these
qualities; the component managers and the project manager should encourage developers who do not meet
these standards to take courses to improve their technical and non-technical skills. Otherwise, they may
have to be assigned to other parts of the team, such as testing, user education or logistics.
Envisionment Phase
In the envisionment phase, developers will help identify possible risks in the development of the project,
research existing software components, and determine how feasible the goals of the client are. Risks to the
project will be placed into risk documents and recommendations will either be made at a meeting of the
whole team or passed on to the project manager.
39
Chapter 2
Design Phase
During the design phase, the developers will work together, coordinated by the component managers, to
convert the use cases into sequence diagrams in the logical stage, and convert the sequence diagrams into a
final design in the physical stage. The developers will also give estimates as to how long it will take for
them to build the components they are responsible for during the physical stage. Developers will also build
test applications to make sure that new technologies or new coding methods work correctly and efficiently.
Development Phase
Development will build the project during the development phase. They will do this based on the design
documents created in the design phase. Each developer will be responsible for building components or parts
of the components. The developers will be coordinated by the component manager, and complete their tasks
according to a schedule which they create themselves. If a developer falls behind in their schedule, he or
she will need to readjust their schedule. The component manager may then need to readjust the entire team's
schedule based on these changes, and this could mean that the schedule for the entire project will have to be
amended. Thus, when you are involved in this type of team, it is important that you make accurate time
estimates of your work.
Deployment Phase
During the deployment phase, developers will focus on fixing any bugs that are found by testing or beta
testers. Development will work with logistics to prepare for the final rollout.
Testing
Testing will make sure that all problems, bugs, and risks to the project are known and documented before
the final release of the project. Testers will develop a test plan, implement the test plan, track all bugs,
create bug reports, and maintain the bug-tracking database. The test plan must make sure all interfaces and
components work properly, and also make sure all of the goals of the project are being met. The bug-
tracking database will be used to determine risks to the project and create reports.
Quality Assurance (QA) is not testing. Testing is based on a test plan that is specific
to the project, whereas QA is concerned with complying with standards and is
usually a corporate function. QA may also create documents that illustrate best
practices for the corporation and develop standards for the development team.
Envisionment Phase
Testing will assess the goals with regard to how they can be tested, and what factors are critical for the
success of the product, as well as identify any major risks associated with testing. They will also raise any
issues connected with the vision or scope which may result in a risk to the project.
40
Teams
Design Phase
During the design phase, the testers will define testing strategies for every goal and create methods and
procedures to track problems, bugs and disagreements between members of the team (which includes the
client members of the team). We will discuss how to do this in more depth in the testing chapter. Based on
the testing strategies, a testing plan and schedule will be created and documented. Testing will also evaluate
the overall design, assist in building applications to test new methodologies or technologies, and select
appropriate testing software.
Development Phase
During the development phase, testing will make sure that all issues are documented, and known by the
entire team. Any bugs that are found by the testers must be documented so that the developers can fix them.
The primary focus of testing at this point will be documenting the specifications for testing and designing
tests for each goal of the project. The actual tests conducted during the development phase will consist of
testing all parts of the components, including private methods and properties, which are used only by the
component itself.
If there are enough testers, a one-to-one ratio of testers to developers can be used. In this case, the
developer and the tester will work together. The developer will write the code and the tester will test the
code as parts of the component are completed. Working with the developer, the tester can create individual
test functions for all of the parts of the component the developer is working on. Thus, if the developer is
creating a component built out of a two-class hierarchy, when the first class is complete, the tester will
create a function to test the class. When the second class is complete, another function can test the second
class, and a third function can test both classes together.
Even with the best planning and the most skilled developers, there will often be many small coding
mistakes that these tests will uncover. As each mistake is found and documented by the tester, the developer
can make the appropriate fixes to the code. Once the component has been completely tested, it will undergo
further testing as part of the entire application at the end of the development phase and in the beginning of
the deployment phase.
It is important to understand that testing of the component does not begin when the
component is completely coded and assembled. Testing occurs simultaneously with
development - as each part of the component is completed, it is tested. In addition,
the design of the components should also be tested, so testing really begins in the
design phase.
When there are not enough testers for a one-to-one ratio, one tester can be used by several developers.
Ideally, one should not go beyond a ratio of four developers to one tester, but of course in the real world
many teams are too small even for this ratio.
Deployment Phase
The deployment phase will be led by the testers and the logisticians. The testers will be responsible for
managing the final testing, the release of the product and making sure that the product meets the goals of
the project. The testing will focus on testing the goals of the project and stress-testing (performing tests
under stressful conditions, for example by simulating a large number of concurrent users) instead of testing
individual components.
41
Chapter 2
For example, during the development phase of an order entry application, the testing may focus on
components such as the order component, the customer component, etc. During the deployment phase, the
testing will focus on general goals (for example, placing an order), which will include a set of smaller
goals, such as being able to begin the order by selecting the customer, selecting a product, or adding a
customer, which will itself have a set of smaller goals.
Logistics
The logistician's role is to ensure that there is a smooth rollout and installation of the final project.
Logistics will work with the client's operations and support groups, and act as their advocate in the project
team. Operations and support will be focused on managing and supporting the final project. Therefore, the
logistician will be involved in the addition or removal of any goals that involve the maintainability or
supportability of the project. The logistician will help to transfer the project from the control of the
developers to the operations and support groups.
Envisionment Phase
The logistician will make a substantial contribution to the assessment of infrastructure for the Enterprise
Architecture Document. They will also provide documentation on how manageable and supportable the
goals of the project are. They will also work with the product manager to determine the TCO of the project;
in this process, those parts of the vision that will not be fulfilled by the end of the project will be included
in future maintenance plans.
Design Phase
Logistics will look at the completed design and will document what will be required to maintain and
support the project once it is complete. They will also refine the TCO estimates at this point.
Development Phase
During the development phase, the logistician will work as the operations and support advocate. They will
bring any issues that operations and support have to the attention of the team and provide reports to
operations and support on the status of the project. The logistician will negotiate any issues dealing with the
maintenance or support of the project. By the end of this phase, the logistician will make sure that any
infrastructure required for the release of the project has been procured.
Deployment Phase
During deployment the logistician will work closely with the testers to get the product through a series of
beta tests until a final release candidate is created. The logistician will help to organize the beta sites and
deploy the beta versions, and to prepare signoffs from the operations and support groups.
User Education
The educators will work with end users to make sure the final product improves their work performance.
Once the project is complete, the educators will help the end users understand how to use the final product
in the most efficient way possible. This will reduce the amount of support calls by educating the end users
on the appropriate use of the project.
42
Teams
Since the educators will act as an advocate for the end user, they will oversee the building of user interface
prototypes, the design of setup programs, and the creation of user documentation and training materials.
When making the user interface prototypes, the educator will work closely with the developers and the
component manager involved with these developers. They may also work with the product manager to
interview the users.
As changes are made to the goals of the project, the educators will make certain that these changes are
reflected in the user documentation. They will also make sure that the users are aware of these changes.
Envisionment Phase
The educators will work closely with the product manager to determine the different types of users during
the envisionment phase. The educators will also work with the end users to ascertain their general goals,
and to make sure that any recommendations from the end users on ways to improve their performance are
included in the goals of the project. Towards the end of the envisionment phase, the educators will provide
the component manager with an estimate of the cost for training and documentation of the project. Ideally,
these estimates should include a range of options so that the product manager, working with the
stakeholders and sponsors, can choose an option that fits within the budget and time constraints of the
project.
Design Phase
The educators will perform an analysis of the users' needs and create a document based on this analysis.
They will work on the design of the user interface with the users and developers. The educators will review
the design to determine how usable the project will be, and make recommendations on how to make the
final product more efficient for the end users. Towards the end of this phase, the educators will make a
more refined estimate of how long it will take to build the end-user documentation and training materials.
Development Phase
During the development phase, the educators will make all of the end-user documentation and training
materials, including the online help files. It is important that the design is locked down before this is done,
so that nothing has to be redone.
Deployment Phase
In the deployment phase, the educators will be training the users and finishing the user documentation and
training materials.
End Users
The end users will contribute ways to improve the efficiency of any business processes that they work with
and which are included in the scope of the project. The educators will be the primary members of the
software team working with the end user.
Envisionment Phase
During the envisionment phase, the end users will discuss with the educators general goals for making a
business process more efficient. They may be involved with the creation of the Enterprise Architecture
Document. However, if it is necessary to re-engineer business processes, this will be carried out chiefly by
the stakeholders and high-level management.
43
Chapter 2
Design Phase
The end users will allow the educators, product or project manager or developers to interview them to
determine the best way to perform their business processes. The end users will also review user-interface
prototypes and make recommendations on how to make the interface more efficient. They will make sure
that the interface allows them to fulfill all of their goals for this project.
Development Phase
This stage will require beta testing of all the individual components and a review by the users to make sure
they meet the goals of the end users.
Deployment Phase
The end users will be involved in beta testing the final releases of the product.
Envisionment Phase
Working with the product manager, stakeholders and sponsors will create the vision and scope of the
project. They will review the TCO estimates and determine what goals can be included within the project.
They will be involved with the creation of the Enterprise Architecture Document. Stakeholders and high-
level management may need to become involved in re-engineering business processes.
44
Teams
While the first level has been termed 'basic', this may include many skills that you
are not likely to have learned. It is unlikely that a current college graduate would
have most of the basic skills. It is important that your team provides an
environment where all team members, new and old alike, can work towards
improving themselves and their skills.
While it is important that every team member should strive for as high a level as possible on every skill, it
goes without saying that certain skills are more important to certain roles. All team members should try to
reach basic level for all skills, but I will indicate which team members really need a higher level for each
skill.
Communication
Without a doubt, one of the most essential skills you need to develop is the ability to communicate. You
must master both verbal and written communication. You should be able to create well-written documents,
as well as speak clearly and concisely to a group. Communication also includes the ability to listen to
others.
When working on a project, communication will be the most important skill for making a contribution to
the team and becoming part of the collective knowledge base. Communication will impact on your ability to
add risks to the risk document, to explain your ideas on design and development and make it possible for
you work directly with the client.
The three levels of communication are as follows:
45
Chapter 2
All the roles will require good communication skills. Whether it is speaking to a client, another team
member, documenting risks, writing emails or contributing to a meeting, good communication skills will be
required.
This skill is perhaps the most important for all team members, and everyone in the team should try to reach
as high a level as possible. If every member of the team can reach at least the basic level skills for
communication, this will make the entire team more productive as information will flow freely. Those in
management roles in particular (the project manager, component managers and product managers) and the
user educators should aim to possess communication skills to an intermediate or advanced level.
Good communication involves being able to speak publicly with confidence and to write well, but also, in a
less formal context, ensuring that information flows smoothly between team members, so that each member
can contribute to the knowledge base of the entire team.
The following suggestions may help you to improve your speaking skills:
Practise giving a talk to a friend and have the friend make suggestions.
When asked questions, pause a moment to think about your answer, then begin your answer by
paraphrasing the question to give you time to think and make sure you understood the question.
Show enthusiasm when speaking and do not talk in a monotone.
Eliminate annoying words such as "um".
Watch your audience, involve them in your talk, and be aware when they seem bored.
When giving a presentation, anticipate the questions that may be asked and prepare answers to these
questions.
Make eye contact when speaking or listening to someone.
Rehearse any presentation you are going to give; if possible, videotape it and review it.
Use visual aids as an addition to a presentation, but do not let them become the presentation.
Keep the length of your answers between ten and forty seconds.
Stay focused on the topic.
Being able to write effectively is also essential when you are part of a team. Whether it is writing an email,
adding a risk to the risk documentation or writing design documentation, you must be able to write clearly
and effectively. The following are some suggestions on how to improve your writing:
When you are writing letters or emails, consider what the recipient already knows and concisely provide
them with information they do not yet know.
No matter what you write, whether it is an important report or just a memo, read through it at least once,
preferably three times. As you read through it, check the flow of the sentences, the grammar, how clear
your sentences are, and whether the document actually means what is intended.
Write on the level of your readers: do not use technical words when writing to someone who does not
have a technical background.
46
Teams
Keep a dictionary handy (or have one on your computer or use Internet dictionaries); do not guess at
words and do not use words repetitively in a sentence.
Organize the information in a way that is easy to read – lists of information can become bulleted lists,
structured information can be put into tables, etc.
Use spelling and grammar checkers, but do not rely solely on them, as they can be wrong.
Paragraphs should deal with one idea and not be too long.
Keep a book on grammar close by when you have questions on sentence structure.
Identify the mistakes you commonly make in grammar and spelling and watch out for them.
Communication must flow through the team. Following the suggestions below will help to ensure that
information is passed through the entire team:
Making Decisions
Making decisions is another essential skill you must have to work successfully on the team. We generally
think of management decisions as the major decisions that cause the project to succeed or fail, such as what
the vision and scope should be. However, in reality every person on a team is faced with making decisions
that can have a serious impact on the project's success.
For example, when you have a multitude of tasks that need to be performed, such as answering and reading
email, meeting the project goals, attending meetings, etc., deciding on how to manage your time will
determine whether you meet your goals or fail to meet them. We will discuss time management towards the
end of the chapter.
Every member of the team will have to make day-to-day decisions based on their roles. The developer will
have to decide the best way to code a module. The tester will have to decide what is the best way to test a
module. The educator will have to decide what is the best way to interview and work with the users. The
educator, the developer and the tester are not management roles, but they will have to make decisions that
can affect the success or failure of the project every day. Every member of the team assumes responsibility
for the success or failure of the project. Good decision-making skills are essential for every role and this is
something that the entire team should work on.
47
Chapter 2
This skill is most important for the project manager, who will have the final say on most decisions in the
project, and therefore should aim to possess this skill to the advanced level. However, the component
managers will also have to make many decisions which affect only their team, and should possess this skill
to intermediate-to-advanced level. Imagine one of our developers, who is writing an ASP page which will
act as the client-side interface for our order entry application, falls ill. The component manager has to
decide whether to cover for the absent developer from within the component team, wait until he returns to
work, or ask for cover from outside the component team. To draft in cover may require another developer to
be trained in ASP, which could easily take longer than the ill developer's recovery. On the other hand, a
lengthy delay could set back the whole project. The project manager and component manager will therefore
need to find out if there is a developer who could take over this goal at short notice, without lengthy
training in ASP. They will need to consider the impact that removing a developer will have on that
developer (who may find it an annoying distraction) and on the team from which he or she is removed. To
find the best solution, they will therefore need decision-making skills to the most advanced level.
The first step in making a decision is to gather information and analyze the facts. To get some practice on
gathering information, you could try either of the following:
Research your company's (or your client's) competitors, create a profile on each of them, and see what
you can learn from these companies to create improvements and to compete more effectively.
Research your company's policies and procedures. If there is a policy that everyone complains about
because it is not efficient, try to find a better policy than the one currently in place.
48
Teams
Proper Planning
With the type of self-directed teams being discussed here, each member will be assigned a task and will
have to give an estimate as to how long it will take to complete the task. Therefore, each team member will
have to make a plan for the tasks to which they are assigned. Anyone who has not done this before will
probably need to get help from someone who has. Once you have made a few plans and estimated the time
to complete several tasks, you will start to make better and more accurate plans.
While planning is a skill learned with experience, one can learn a great deal by reviewing previous project
schedules. This is one of the reasons that proper documentation is so essential: it provides a library of
documents. Estimates usually work best when they start at a fine grain and work upward.
It may be very difficult to estimate the time to build and test a complete server component for an order
entry application. Imagine that the server component design is broken down into a design that includes
three classes. The class designs are broken down into a design for the methods and properties for the class.
Looking at the designs for the methods and properties, each developer should be able to estimate fairly
accurately how long it will take for them to code and test each method and property. By summing the times
for all of the methods and proprieties you have an estimate for the classes, and summing the times for the
classes gives you the components. Good design not only helps you build your project, but also helps you
plan it. Make sure you add some extra time for unexpected problems, as these are always going to happen.
49
Chapter 2
Since all members of the team will need to create their own schedule, everyone will need this skill to at
least the basic level. The company should provide software, documentation or training, or a combination of
the three, for the members of the team. We will discuss products for drawing up schedules in later chapters.
If your company does not provide training, it would be well worth your time to read a few books or even
take a course. Several titles are listed at the end of the chapter.
Because the major end product of the project is the code produced by the developers, it is important that
this code is completed on time. For this reason, the developers who write the code and the testers who help
to ensure that it works as stated should all aim to be on the intermediate level. Even more importantly, the
component managers, who create the schedules for the component teams, and the project manager, who
draws up the master schedule for the entire project, must be on the intermediate level, and should aim for
the advanced level.
50
Teams
Once you create a plan, periodically check to make sure the facts you based your plan on still apply. If
they do not, revise your plan.
Break tasks into smaller tasks. Make a detailed plan for the tasks you will complete in the near future
and a fluid general plan for the tasks that are in the far future.
Identify the three to six critical tasks that you must complete to meet your goals and focus on making
plans to achieve these.
Have other people review your plans.
Periodically review your plans and add more details as you gather more information.
Set aside some time each day to review your plans.
There's no point in drafting an impeccable schedule if you don't adhere to it. The following guidelines on
how to manage your time more efficiently should help you ensure that you don't waste time needlessly:
51
Chapter 2
When you read a document, letter or email, etc. if a response is necessary, respond immediately, if it
needs to be filed, file it; you should strive to look at things only once.
Evaluate your tasks in regards to how they will help you accomplish your goals, the goals of the client,
and the consequences of not doing the task. Critical tasks are ones that are necessary to accomplish your
goals and the goals of the client, and will have serious consequences, such as missing a deadline, if you
do not do them.
Allocate a time in your schedule for returning phone calls.
When responding to paper documents, if possible make a copy of the document and put your answers on
the document. When responding to email, include the sender's message in your response, but put your
answer at the top of the email, not mixed in with the sender's message.
Every morning look at your schedule and create a set of tasks you will complete during the day.
Do not keep useless documents.
Arrange your office so that things that you use most often are within reach, things used less often are
further away.
Solving Problems
Solving problems is an essential skill for a member of a software team. Everyone can learn how to solve
problems.
As a member of a Visual Basic development team, you will find yourself constantly find yourself facing
problems that need to be solved. The typical questions facing developers include how to code a module or
how to ensure the best performance.
Some of the most intense problem solving is trying to figure out why something does not work, especially
when it should work. Trying to track down a problem requires a careful process of elimination until you
have found the cause of the problem. Sometimes you may find the cause, but there may be no logical
explanation. While searching for solutions may be fun, it can be very expensive in terms of time. If a
solution cannot be found in a reasonable time, contact Microsoft support. If it is a bug, they will not charge
you for the call. For the most part, a support call will cost one or two hours of a developer's time. It is not
just money, though. If you turn a problem over to support, while they are searching for a solution your
developer can now work on other parts of the project until a solution is found.
Often, the most difficult part of problem solving is not finding the solution, but finding the question.
Sometimes you will have to spend hours or even days doing enough research to understand what questions
you need to ask. Once you know the questions, it is usually not too difficult to find the answers. With new
technologies you usually know the questions only after you have written a few test applications to see how
the technology works.
52
Teams
Obviously, the developers will need this skill to a particularly high level, since programming is essentially
a problem-solving activity: developers are presented with a problem (such as how to allow a customer to
enter an order over the Internet), and must find the best solution to it. They should therefore possess this
skill at least to intermediate level. The project and component managers should also possess this skill to
intermediate or advanced level, since they must be able to solve administrative and managerial problems.
Since the problems faced by the developers, if they are not solved, could cause the entire project to be
delayed, these problems are ultimately also issues for the project manager, and may have to be resolved by
finding more resources (such as a more experienced developer).
Some things you can do to improve your problem solving skills are:
Write down the problem, all the information you have gathered on the problem, and then read through
everything you have written.
Play strategy games such as chess or pinochle.
Discuss the problem with others to help you define the problem.
Seek advice from people who have had similar problems in the past.
Work on puzzles or play games in your spare time that require you to solve problems.
53
Chapter 2
Creativity
Creativity is very important for the Visual Basic developer. From finding solutions to design problems to
determining the best way to code a module, creativity will help you come up with the answer.
I think that there's an expression, "Get out of the box". This means that you must not get stuck in the box of
standard solutions, but instead must look beyond what others have done, and what is usually done, and find
a new solution. Whenever you are stepping out of the box, you are being creative. Whenever you tell
yourself that this has not been done so I cannot do it, then you not being creative. Sometimes there is no
way out of the box, but often there is a way out, it's just that no one is creative enough to find the solution.
Creativity does, though, have to be within the scope of the project and resources. Solutions that create
unacceptable risks or break good standards should be avoided. Like everything, the risks of your creative
solutions should be investigated and you should determine whether they are within acceptable limits.
Creativity is particularly essential for developers, who must devise the best solution for each situation,
rather than relying on the standard solution; they should therefore possess this quality to the intermediate-
to-advanced level. Testers will also need to think creatively in building functions to test components, and
should aim to reach the intermediate level.
54
Teams
Although we may usually think of creativity as an innate quality, which cannot be learned, there are in fact
a number of ways you can increase your creative potential:
Believe in yourself and your ideas. Do not discard an idea until you have explored it and seen that it will
not work. Even then, you may find it works for a different problem.
Learn to walk away from a problem for a while when you get stuck. An answer will often come to you
later.
Create as many options as possible for each problem. If you are not good at this, take a problem, analyze
it by yourself, and then talk the problem over with other people and see how they would solve the
problem.
Do not always just ask "Why?" but also sometimes ask "Why not?"
Evaluate the risks and be willing to choose decisions that have a reasonable risk.
Put some time aside where it is quiet and you can just think.
Talk your ideas over with someone that will help you get more insight into a solution.
The more senses you use to solve a problem, the easier it is to find a solution. Trying to just visualize a
solution in your mind is the hardest way to solve a problem. Drawing pictures and writing down
information adds vision, talking adds hearing. Doing all of these will help you find better solutions.
Do not always accept your first ideas; try to see if you come up with other ideas, too. Try seeing the
problem from different perspectives.
Talk to people to see if they have had a similar problem and can share with you how they solved the
problem.
Record all of your ideas, even if you are not going to be using them currently.
Try to find something that makes you relax and think creatively, such as music.
Create imaginary problems and try to find solutions to them. Do not be afraid to come up with fantasy-
type questions, such as: "What will life be like in one hundred years?"
Do things that use the creative part of your brain. For example, take a class in drawing even if you
cannot draw.
Try to work in a creative environment. Often, when being creative you can get lost in your work and lose
your sense of time. Working where you have constant distractions prevents this. If you are working in
cubicles, see if there is any way you can get your company to relocate its "creative" workers, such as
developers, into quiet areas, preferably in offices.
Resolving Conflicts
Conflicts can arise in many different ways within a software team. The most common is the conflict caused
by the client's desire for as many features as possible versus the constraints of time and budget. Members of
the software team must diplomatically work with the client to determine the critical goals of the client and
remove the non-critical goals from the project scope.
Within a team there will often be differences in opinions. If you want to hear a heated discussion, put ten
Visual Basic programmers in a room and start a conversation on the best coding standards for a Visual
Basic project. Creating any standard will result in discussion and compromise.
55
Chapter 2
There will also be differences in personalities, viewpoints, etc. which can create tension between group
members. Learning how to resolve these conflicts is an important part of being a member of a team.
Everyone working in a team will need some ability to resolve conflicts. In our software team, those with
particular need for this skill are the product managers, who act as the link between the team and the client,
and who will have to resolve any conflict between functionality that the client would like to be provided
and what the developers believe is possible with the given resources. The project and component managers
will also need this skill to a high level, since they are the ones who must ultimately resolve the issue.
Making a decision without first resolving the conflict could fan the flames of any nascent personality clash.
The following tips will be useful for resolving - and even better, avoiding - conflicts:
56
Teams
Perhaps one of the most difficult tasks for a project manager is to nurture a passion for developing solutions
in the team. There are many reasons why the team may lack enthusiasm. Team members who are not happy
in their job and are dissatisfied will rarely show a passion for anything work-related. The team can be
encouraged to give confidential evaluations of the team or team leader to see their perception of how well
the team is working. If the same problem is mentioned by a majority of team members, this is a problem
that needs to be resolved. One can also have regular discussions on ways to improve the team, or simply
have a place to post suggestions.
Another problem is that developers can easily feel isolated and separate. Most development teams get
together for short discussions on the project, but then will go off to their cubicles or offices and work alone.
Making the project a team effort and bringing the entire team together to find solutions builds team spirit
and helps reduce the isolation. The more the team members feel they are part of something and the more
they feel that their input is valuable, the more passionate they will become in accomplishing the team goals.
One other possibility is to get your team members to give classes on topics which are important to the team.
These classes should not be boring lectures, but should show innovative ways of using Visual Basic or the
latest technology, how the technology solves problems, etc. You can even have weekly or monthly contests
to see who can come up with the most innovative test project for a particular technology or Visual Basic
feature. An award should be given for all entries, and a special award for the best project. This motivates
the developers to learn new skills and to take an interest in the technology.
57
Chapter 2
It is of course particularly important for the developers to feel this passion, and they should strive to reach
the intermediate level, but all team members should reach a basic level with this skill. It is particularly
important that the project manager and component managers also feel this enthusiasm, since they should be
able to instill it into the other team members. Product managers should also emanate a passion for building
solutions in their dealings with the client: the client must see that the team is committed to finding the best
solution for them.
Visual Basic, combined with Microsoft Back Office, allows one to solve almost any type of enterprise
project. Often, the greatest limitation we face is not the Visual Basic language or the Microsoft products,
but our own imagination. Microsoft has provided us with a set of products that allows us to define the goals
of the client and then find ways to fulfill those goals. Putting together a solution for a client, regardless of
your role on the project, should be viewed as an exciting, creative process. If you find working on a Visual
Basic software team boring, you should perhaps reassess your role on the team, or try to spend some time
working on different aspects of development until you can find a niche that you enjoy.
The following suggestions may help to increase your passion for building enterprise solutions:
Try to get involved in challenging projects that will require you to make significant contributions.
Talk to others about the latest features in Visual Basic.
Work with other team members to learn about new features in Visual Basic, Back Office or other
technologies that you work with.
Become a specialist in developing Visual Basic applications, but also have understanding of the
Microsoft Back Office products.
Try to work with someone who is an expert in the areas you want to learn about.
Make contacts with people who will be able to give you advice.
There is no better way to learn than to teach. Present a class on one of the new features in Visual Basic
or give a class on programming, such as optimizing Visual Basic middle tier components.
Attend conferences such as VBITS (the Visual Basic Insiders' Technical Summit) whenever possible.
Read magazines, such as Visual Basic Professional Journal (VBPJ), to keep up with the latest Visual
Basic versions.
Work as a team to find the best way to build enterprise applications using Visual Basic and Microsoft
Back Office.
Develop plans to incorporate the new Visual Basic features.
58
Teams
While the product manager, educators, and logisticians are the primary liaisons to the client and should be
at the intermediate or advanced level for client focus, all members of the team should be able to discuss
issues relating to meeting the client's needs with the client when necessary, and should aim to reach the
basic level at least.
The following suggestions should help to ensure that you remain focused on the client and attentive to their
needs:
59
Chapter 2
Team Spirit
Team spirit helps bind the team together and helps the team achieve its goals because of its members, not in
spite of them. Team spirit allows you to look beyond your own personal needs and work toward the goals of
the entire team. We have discussed a few possibilities in the section on passion for enterprise solutions.
While team spirit is not technically a skill, it is an essential requirement for anyone who has to work in a
team.
Other possibilities include activities that you do as a team outside of work, such as a picnic, conference,
etc. These can also be done during work hours.
Be careful with out-of-work plans. While some married people might enjoy some time away from the
family, the majority of people with families prefer to spend time with them. If possible, include family
members in out-of-work activities. I have known some large corporations to have morale-raising events in
one central location, flying all their employees into the event from around the world. While it may be fun
for some people, others have responsibilities and may find that this event is an inconvenience rather than a
morale booster. Make sure you are choosing activities that everyone will enjoy.
Also be sensitive to ethical, cultural and religious customs. Many people have special dietary needs. It may
seem like a great idea to order a pizza for a lunchtime meeting but some of the team members may for one
reason or another not be able to eat the pizza. Be sensitive to these issues when you plan such activities.
60
Teams
Everyone working in a team (and not just a software team) should aim to develop their team spirit skills,
and should have most of the basic level qualities. The project and component managers will need to foster
these skills in the other team members, so should strive to reach the intermediate or advanced level.
Work with your team members to solve problems and achieve goals.
Create a team vision.
Make a list of the strengths of the members of your team and utilize them in these areas.
Ask your team members which areas they feel they are not strong in and help them improve themselves
in these areas.
Show appreciation to all the people you come in contact with, including those who are not on your team,
such as the administrative people.
Show appreciation for team members who help achieve the team goals.
Try to make shy members more comfortable and try to help them talk and contribute.
Listen to your team members.
Do not judge team members.
Be open-minded about team members.
Enjoy your job.
Leadership
While leadership is essential to be in a management role, it is also important for all team members.
Knowing how to lead is something that you can learn with experience. As you will be taking responsibility
for accomplishing your goals, it is important that you develop some leadership skills. The three levels of
leadership are as follows:
Although not a traditional 'boss', the project manager has ultimate responsibility for the project, so should
aim to possess the advanced level for this skill. The other managerial roles, the component and product
managers, should also aim for a high (intermediate to advanced) level of leadership.
61
Chapter 2
62
Teams
Accomplishing Goals
Everyone on the software team needs to know how to accomplish goals, as each member is responsible for
accomplishing the goals that are assigned to them. The three levels of accomplishing goals are as follows:
You stay focused on goals until You get other team members You meet goals even when
they are accomplished to define their assigned tasks there are difficult problems or
in terms of goals to be obstacles
You take pride in your work accomplished
You take responsibility for the
You are willing to take on You help other team most difficult goals of the
difficult assignments to help the members to define critical group and complete them
team accomplish its goals goals and stay focused on
accomplishing them You perform effective risk
You take appropriate action analysis and prevent problems
when you are diverted from You help other team from stopping the team from
your goals members work through achieving your goals.
difficulties
You accomplish the assigned You are always looking for
task even when it requires extra You acknowledge when other ways to improve the team
time and energy to accomplish team members fulfill their
the task goals within schedule
You turn all assigned tasks into You create high but realistic
personal goals standards
You create realistic schedules You feel your work
based on assigned tasks and represents you
goals
You learn how to prioritize
You do not quit when things go your goals
wrong or become difficult
You are able to help other team
members when they need
assistance
You are willing to do routine
tasks when they are required
Since the project depends ultimately on the developers producing working code on schedule, this skill is
particularly vital for them, and they should aim for the intermediate to advanced level of this skill. The
code will also need to be tested on schedule, so the testers too should try to reach at least the intermediate
level. The component managers and the project manager will need to ensure that the goals of the entire
team are achieved, so should ideally possess this skill to the advanced level.
63
Chapter 2
Below are some suggestions which might help you to ensure that you accomplish the goals which are
assigned to you or which you set for yourself:
Do not give up; often one must work hard and keep trying to accomplish a goal.
Use the 80/20 rule, which states that you should try to accomplish 80% of your goals in 20% of your
time.
Reevaluate your goals periodically and adjust your goals as circumstances change.
Do not focus on the negative.
Do not work the clock; work toward accomplishing tasks.
Focus on how to do something; do not focus on why you think it cannot be done.
Find the goals that are critical and focus on them.
Create rewards for yourself when you accomplish your goals.
Accomplish your goals so that you can take on more responsibilities.
System Management
Certain roles in the team, such as product management, require a good knowledge of enterprise systems.
The three levels for system management are:
These skills are chiefly important for the product managers and logisticians, who should all aim for
intermediate to advanced level for this skill.
64
Teams
65
Chapter 2
Below are some suggestions on how to improve your general team skills:
66
Teams
Summary
A Visual Basic team should be comprised of a group of people who are assigned to roles based on their
skills and the responsibilities they can assume. The skills for each role should be well-defined, so that team
members can develop the necessary skills to succeed in their role and so they can work toward moving into
other roles.
Ideally, a company should put time aside for workshops with its employees to train them in non-technical
skills. These non-technical skills are as important as the technical ones. Team members should have the
skills to manage themselves and also be able to help the team reach its goals.
67
Chapter 2
Skills References
Below is a list of books on topics covered in this chapter. I would recommend that any large company
should have a library with both technical and non-technical books that can be borrowed by team members.
The following books should be part of any library for a Visual Basic team.
The Art of Communicating by Bert Decker. Crisp Publications, Inc., ISBN 156052409X
You've Got to Be Believed to Be Heard by Bert Decker, James Denney. St. Martin's Press, ISBN
0312099495
People Smarts: Bending the Golden Rule to Give Others What They Want by Tony Alessandra,
Michael J. O'Connor. Pfeiffer & Co, ISBN 0883904217
The Human Touch : Today's Most Unusual Program for Productivity and Profit by William W.
Arnold, Jeanne M. Plas. John Wiley & Sons, ISBN 0471572918
Listen to Win: A Manager's Guide to Effective Listening by Curt Bechler, Richard L. Weaver. Master
Media, ISBN 1571010025
Basics of Business Writing (Worksmart Series) by Marty Stuckey. AMACOM, ISBN 0814477925
Getting It Done: How to Lead When You're Not in Charge. Harperbusiness, ISBN 0887308422
Discovering Common Ground: How Future Search Conferences Bring People Together to Achieve by
Marvin R. Weisbord. Berrett-Koehler Pub, ISBN 1881052087
Breakthrough Innovation, Empowerment, Shared Vision, and Leadership When the Heat's on by
Danny Cox, John Hoover. McGraw-Hill, ISBN 0070132674
Leading Self-Directed Work Teams: A Guide to Developing New Team Leadership Skills by Kimball
Fisher.
Empowered Teams: Creating Self-Directed Work Groups That Improve Quality, Productivity, and
Participation by Richard S. Wellins, William C. Byham. Jossey-Bass Publishers, ISBN 1555425542
Leading the Transition: Management's Role in Creating a Team-Based Culture by Wilbur L. Pike III.
AACC Press, ISBN 0527762474
Why Teams Don't Work: What Went Wrong and How to Make It Right by Harvey Robbins, Michael
Finley. HighBridge Company, ISBN 1565111923
Why Change Doesn't Work: Why Initiatives Go Wrong and How to Try Again-And Succeed by
Harvey Robbins, Michael Finley. Petersons Guides, ISBN 1560799447
68
Teams
Reaching the Peak Performance Zone: How to Motivate Yourself and Others to Excel by Gerald
Kushel. AMACOM, ISBN 0814402224
Patterns of High Performance: Discovering the Ways People Work Best by Jerry L. Fletcher. Berrett-
Koehler (Short Disc), ISBN 1881052338
The 2,000 Percent Solution: Free Your Organization from 'Stalled' Thinking to Achieve Exponential
Success by Donald Mitchell, Carol Coles, Robert Metz.
Bringing Out the Best in People: How to Apply the Astonishing Power of Positive Reinforcement by
Aubrey C. Daniels
If It Ain't Broke, Break It : And Other Unconventional Wisdom for a Changing Business World by
Robert J. Kriegel, Louis Patler. Warner Books, ISBN 0446393592
Vision: How Leaders Develop It, Share It, and Sustain It by Joseph V. Quigely. McGraw-Hill, ISBN
0070510849
Building a Shared Vision: A Leader's Guide to Aligning the Organization by C. Patrick Lewis.
Productivity Press, ISBN 156327163X
The Confident Decision Maker: How to Make the Right Business and Personal Decisions Every Time.
Quill, ISBN 0688142281
Competing for the Future by Gary Hamel, C. K. Prahalad. Harvard Business School Press, ISBN
0875847161
The Profit Zone: How Strategic Business Design Will Lead You to Tomorrow's Profits by Adrian J.
Slywotzky, David J. Morrison. Times Books, ISBN 0812929004
Drawing on the Right Side of the Brain: A Course in Enhancing Creativity and Artistic Confidence by
Betty Edwards. J P Tarcher, ISBN 0874775132
69
Chapter 2
70
Creating Project Schedules
Now that we have a basic understanding of the cycles of a Visual Basic project, the goals for each cycle and
who is responsible for each goal, we can begin to look at making schedules. We will define a schedule as a
visual document that allows you to see how you will use the time resource towards accomplishing your
goals.
A schedule begins with a set of goals that need to be accomplished. Goals can be divided into three
priorities: high (critical), medium, and low. Each goal will have one or many milestones that will allow us
to measure whether we have accomplished this goal or not. We will have a set of resources, which includes
time, money, and human resources, which we can use to accomplish our goals.
Because there will almost always be limitations placed on what we can do with our resources (there is never
enough time!), we must balance our schedule so that the high priority goals are met within the limits of our
resources. Low priority goals may not get done, and medium priority goals may be done, but not
immediately. By using a schedule, we have a visual tool that allows us to adjust the amount of time allotted
for our goals until we arrive at a schedule that allows us to complete all of our critical goals, and hopefully
most, if not all, of our medium goals. If you can also accomplish your medium priority goals within your
normal workday, consider yourself very lucky.
If we are using a scheduling tool, we can extend the definition of a schedule to being a visual document that
allows us to see how we are using all of our resources, including time, people, money, and space, towards
accomplishing our goals. Using these scheduling tools, you can adjust the usage of all of the available
resources until you arrive at a schedule that efficiently uses the resources towards the accomplishment of
your goals.
We will use Microsoft Project 98 because it is easy to use and learn, the examples we use with Microsoft
Project 98 are useful for any project management software product, and it can be used to demonstrate all of
the important concepts of creating a schedule. If you do not have Project 98, you can download a free 60-
day trial version at:
Chapter 3
http://www.microsoft.com/office/98/project/trial/info.htm
This web site also contains links for Project 98 that can help answer even your most advanced questions
about how to use Project 98. I would highly recommend you taking the time to download Project 98 now if
you do not already have it.
This chapter is filled with important scheduling skills and will teach you the basics of how to create a
project schedule. Two of the visual aids provided by Project 98 are Gantt and Pert charts.
A Gantt chart represents each goal as a horizontal bar. The horizontal bar will be placed over a time scale,
which is situated at the top of the chart. The length of the horizontal bar shows how long it will take to
complete the goal. Using a Gantt chart, one can quickly determine the status of goals over time, the
relationship between goals if one exists, and resources associated with the goal.
In this book, I will be placing goals on the schedule. Normally, most people would
call these tasks, instead of goals. Tasks are defined as something that is assigned. In
our view of teams, we do not assign work. Goals are created for the team, and each
team member assumes the goals that fit with their role and their abilities. The word
task just does not fit in with our view of a team. Goals, on the other hand, fit in
perfectly with our team view. Project 98 uses the word 'tasks'. Just substitute 'goal'
for 'task' when working with Project 98.
72
Creating Project Schedules
A Pert chart shows the relationships between goals. Goals that are dependent on other goals, for example,
one goal requiring another to be completed first or a goal that is a sub-goal of a second, can easily be seen
in a Pert chart. Pert charts are useful for visualizing the sequence of goals and they can also show the
progress of each goal as time goes on. More information can be found in the Project 98 help files.
Throughout the rest of the book, we will use a generic Visual Basic DNA project as an example to show
you how to manage a project. This project will contain the normal parts of a Visual Basic DNA project:
client components, server components and web components. If any of these components are not part of your
project, you can remove them from this schedule.
In this chapter, you will start out in the Visual Basic developer role. We will look at your personal schedule
for the beginning of a project. We will do this to introduce Project 98, show you some of the basics of this
tool and also discuss some special scheduling issues for Visual Basic developers.
73
Chapter 3
Project 98 Views
Project 98 comes with twenty-six views. The eight most common views are listed in the dropdown menu by
default. They are:
Calendar: A view of goals by date. This view looks very much like the calendar in Microsoft
Outlook, except that you cannot set the hours for your goals. You can set the range
of dates you want to view.
Gantt: Goals are shown as a bar spanning the time it will take to complete the goal.
Pert: A diagram showing all goals and the relationship between goals.
Task Usage: A list of goals showing the resources assigned to each goal.
Tracking Gantt: Used to track the percentage a goal is completed.
Resource Graph: A graph showing resource allocation, cost or work.
Resource Sheet: A place to enter all the resources available to the project.
Resource Usage: A list of resources and the goals associated with the resource.
More Views: Additional ways of viewing the schedule.
We will only discuss the Gantt view in detail because it is one of the most popular views for project
management and the best one to manage your schedule and resources.
74
Creating Project Schedules
We would like our project to have dates in the future. I have chosen to begin this project on January 15,
2002. We need to tell Project 98 that we are beginning our schedule on this day. The project information
can also be seen at any time by selecting Project | Project Information Don’t worry about the Finish date:
Project 98 will automatically put that in for you.
Gantt View
Now that we have started a new project, we must make sure that we are in Gantt view - do this by selecting
View | Gantt Chart or by clicking the Gantt button on the left hand side of the screen.
If you don’t see these buttons, you can view them by selecting View | View Bar.
75
Chapter 3
On the left side of the screen, you will be able to assign each goal a name, a start and finish date, the
duration of the goal, any goals that must be completed before this goal is completed (the Predecessors
column), and a list of required resources. This information will be used by Project 98 to create the task bars
on the right hand side.
You can change the major and minor timescales by placing the cursor over the timescales and right mouse
clicking. Select Zoom to increase or decrease the timescale.
76
Creating Project Schedules
When you select Zoom you will get the following form:
Select the range that you wish to see. You can also select Timescale in the dropdown menu to change both
the major and minor times. Selecting Timescale will give you the following form:
You can now adjust the major and minor time as you wish. Using this feature you can view your project
over hours or weeks, or whatever is most appropriate.
When adding goals, you can type the information directly into the left hand side of the screen. Let us begin
by making the schedule for our developer during the envisionment phase of our project. During this phase
the developer will have minimal input into the project. This is a perfect time for the developer to spend time
learning new skills or improving old ones.
When making a Gantt chart, you are showing how the time resource is being used by your goal. You are not
making an hourly working schedule. This means that you are not saying that on April 15 th from 9 A.M. to
11:00 A.M. I will be working on goal 1 when using a Gantt chart. Instead, a Gantt chart will show that two
hours of the time resource have been allocated to working on goal 1 on April 15 th without saying which two
hours.
77
Chapter 3
Once you have allocated the total time resource for the day to different goals, you can use a standard
scheduling program to assign what hours in the day will belong to each goal. Thus, the Gantt chart could
allocate one hour to goal 1, four hours to goal 2, and one hour to goal 3 on April 15 th. You can then use a
calendar program such as the one in Outlook to assign 9 A.M. to 10 A.M. for goal 1, 10 A.M. to 11 A.M.
and 12 P.M. to 3 P.M. for goal 2, 3 P.M. to 4 P.M. for goal 3 and 4 P. M. to 5 P.M. for administrative tasks.
As soon as you type in the task name, Project 98 will assign it a duration of 1 day. Simply click on the
appropriate column and type in 0 hrs as above.
We have said that the duration of this goal is 0 hours - as we break down the goal into sub-goals, and assign
durations to them, this main goal will have a duration that is the sum of all the durations of its sub-goals.
Don’t worry about this for now, it will become clearer later.
m minute
h hour
d day
w week
em elapsed minutes
eh elapsed hours
ed elapsed days
ew elapsed week
78
Creating Project Schedules
You can set the time for the workday as you need to.
If a goal is to run Friday through Sunday, and you have the default workday as shown above, you can list it
as a 3 ed starting on Friday. This means that you were expecting it to run over 3 elapsed days - Friday,
Saturday and Sunday. If you used 3 d, Project 98 would see this as meaning 3 work days, and would make
the goal run over Friday, Monday and Tuesday of a regular work week.
79
Chapter 3
There is another way to enter information into Project 98. Double click on any part of the row you have
created. You will now see the following form:
Select the Advanced tab: under Constrain task change the Type to As Soon As Possible:
I will be focusing on learning several of the new features in Visual Basic. The skills I will be focusing
on are the new data source classes, web classes and IIS classes. During the envisionment phase I will
spend a maximum of five hours on skills and drop to zero hours during the development phase.
80
Creating Project Schedules
Select OK. Notice a note icon has been added to the information column of the left of the goal name.
Some of you may be thinking that it is unrealistic to study at work. I once worked at a large
company that did not allow reading of any material at your work desk. I found out about this
policy because one of my coworkers spotted me reading a magazine at my cubicle and
reported me to my senior manager. I was immediately called into the manager's office. I
explained to my manager that I was reading an article in VBPJ and using the code sample in
the magazine for the current project I was working on. I was referring to the article as I
typed code into my project. I was told that reading any magazine at work was not allowed,
and if one of the company's vice presidents had seen me, I would have been fired on the spot.
I was advised to go to the cafeteria or step outside if I wanted to do research on my coding
during work hours. While this may seem like it came out of a Dilbert cartoon, this really
happened to me.
During times when programmers have slack time, such as during the envisionment phase or
between projects, team members should be allowed to study. I cannot emphasize this
enough. Visual Basic is a constantly evolving language, as is the entire Enterprise
technology. There is just too much to learn during off hours. If a company wants highly
skilled Visual Basic team members, then they must allow their full time Visual Basic
employees to spend some time improving their skills during work time. They should also be
willing to invest in training.
I would go as far as setting a quiet office aside and turning it into a study room. The room
should be made comfortable and also have one, preferably several, computers set up to work
with Visual Basic and Back Office. The computer should have as much source code as
possible, the MSDN and tech net loaded onto it, and as many study aids as possible. There
should be shelves loaded with good reference materials. A conference room should also be
set aside when several developers have downtime so that they can work together on learning
a topic. If someone has expertise in a field, they should give a talk on that topic. The
company can also pay to have experts in certain areas come in and give classes to the
developers.
81
Chapter 3
Learning new Visual Basic 6 skills is a goal that will be scheduled over a one-month period. We would like
to see how many hours we can devote to this goal each day. To do this with a Gantt chart we must divide
our goal into sub-goals. Each sub-goal can be accomplished within the number of hours you can spend on
the overall goal (learning new VB 6 skills in our example) in one day. On Tuesday, January 15 you can put
five hours towards learning the new features of Visual Basic 6. This is enough time to learn the basics of
Visual Basic 6’s new Data provider classes. We will make this a sub-goal for January 15 that will have a
duration of five hours.
I have changed the major timescale to days and the minor timescale to hours - notice how there is now a bar
on the right hand side representing the length of this goal.
Creating Sub-goals
You want to make a sub-goal of the Learn VB 6 New Features goal. We can do this by
selecting goal 2 and clicking the arrow pointing to the right on the left hand side of the
toolbar:
The plus and minus signs will show or hide the sub-goals:
82
Creating Project Schedules
After clicking the right arrow, you should now have the following:
Notice that there have been a few changes in goal 1. The duration of goal 1 is now 0.63 days. A day is
defined as 8 hours; 5 hours is thus 0.63 days. The finish time is now Tue 01/15/02. The main goal can only
have a duration that totals the combined durations of its sub-goals. Notice that on the right hand side there
is now a black bar indicating that goal 1 is divided up into sub-goals.
The time listed is an estimate of the time we expect this goal to take, not the amount of time we actually
must spend to do this goal (though hopefully the two will be nearly the same). We need a milestone here.
For example, the book, VB 6 UML, published by Wrox Press, covers data source classes in chapters 12, 13
and 14. Thus, we could create the following milestone for this sub-goal:
Read chapters 12, 13 and 14 in the VB 6 UML book and enter the code from these chapters into a test
project.
When the chapters are read and the code is written, the goal is complete, regardless of how many hours it
takes to reach this point. Hopefully, though, our time estimate of five hours was accurate.
83
Chapter 3
The number of hours assigned to a goal is only an estimate of how long it will take to accomplish the goal.
The actual time to complete the goal may be longer or shorter. It is important that you work toward
accomplishing goals every day, and have a milestone that tells you when the goal has been reached. When
all of your milestones for the day have been reached, you have completed your day’s work. If you are new
at estimating the time it takes to accomplish a goal, talk to a co-worker who may have more experience.
Over time, your estimates should become more accurate and you should be able to properly estimate the
goals you can accomplish in a normal workday. Also, actual time spent on working towards a goal can be
stored against a goal so that developers and managers can see how accurate time estimates have been and
can learn and refine their estimates.
You can enter the milestone in two ways. You can either enter it as a comment or you can create a
milestone with Project 98 by entering a goal with a duration of 0, as follows. Enter the following into
Project 98:
Let us imagine that on Wednesday, January 16 we will spend the day in meetings so we will not allocate
any time to learning VB on this day. On Thursday, January 17 we will spend part of the day reviewing the
meeting but will still have two hours to spend working on our VB 6 skills. We will spend this time
reviewing MTS. Let us add the following to our schedule:
84
Creating Project Schedules
Project 98 automatically gives this a duration of 1 day starting on the first day of the whole project - this
will change when we add sub-goals.
Under the Northwind Project on lines 7 and 8 we can add the following sub-goals (don’t
forget to click the indent arrow):
85
Chapter 3
You may have noticed that when you try to enter the date for the First Envisionment Meeting, a wizard
pops up, looking like this:
86
Creating Project Schedules
Our scale on the right is too large so we need to change it. Right mouse click on the timescale:
87
Chapter 3
Recurring Goals
Our schedule is beginning to fill out. We would like to allot one hour every day to administrative time,
which includes breaks and checking email. We will need to add this in for every day. Microsoft Project 98
allows us to add recurring goals.
Click on the next empty row (number 9) and go to Insert in the menu. Select Recurring Task:
88
Creating Project Schedules
Press OK. Select goal 9 and click on the left arrow to move Administrative up one level. Your schedule
should now look as follows:
Links
Sometimes one goal is dependent on another goal. Project 98 allows you to set up four types of
dependencies:
89
Chapter 3
Finish To Start: One goal must be completed before the next one can start. If we needed to complete the
VB6 UML chapters before moving onto MTS, we could add this type of dependency. To make the link, we
need to select the first item on the Gantt chart on the right hand side and drag the mouse pointer to the next
goal. Select Goal 2 first and drag the mouse to Goal 4. As you do this, you should see the chain link
symbol, showing that a link has been made.
The default will be Finish to Start link. Your schedule with the link will look as follows (we have changed
the major time scale to week and the minor to day):
You could have also just typed in the number 2 in the Predecessors column for goal 4. Use whichever is
easiest for you.
90
Creating Project Schedules
Notice the link has moved from the end of the first goal to the beginning of the first goal. When using start,
the link is attached at the beginning of the bar; for finish the link is attached to the end of the bar.
Finish to Finish: This is used when two groups finish at the same time.
Start to Finish: This is used when one group starts when one finishes. For example, you may be upgrading
a system. When the new system starts, the old system finishes.
Let us now link together some groups. Insert three new rows into your schedule before goal 9. Make sure
that goal 9 is selected, then select Insert | New Task three times:
91
Chapter 3
Now link all of the Northwind goals together by selecting goals 7 to 11 and clicking the
chain link button on the toolbar:
Double click on each link and change it to a Finish to Start link. Your schedule should now look as follows:
92
Creating Project Schedules
This allows you to save backup copies of your schedule. We do not need to do this, so we select Save
'DeveloperSchedule' without a baseline. You can get rid of this by clicking in the box Don't tell me
about this again. The schedule will then be saved as DeveloperSchedule.mpp
Resources
Up to this point, we have only been working with the time resource. There are many other resources that are
available, including people, equipment, rooms, etc. In regards to the schedule we are creating for a
developer, some of the resources may be the availability of the study room and the study computer. Let us
add these two resources to our schedule.
93
Chapter 3
In the resource sheet add Study Room and Study Computer; Project 98 adds the extra information
automatically:
94
Creating Project Schedules
Click View and go back to Gantt view. Double click on the Learn basic skills of VB 6 data source class
goal to bring up the Task Information window. Select the resources tab, click on the dropdown combo and
select Study Room. Since the room can hold four people, you are using 25% (one quarter) of the total
resource. Enter 25 for Units. You should see the following:
Using this resource information, a master schedule can be put together to make sure that the team is not
overusing a resource. In this case, if five team members were trying to use the study room at the same time,
the resource would be over utilized and this would show up on the combined master schedule.
95
Chapter 3
Resource Management
What would happen if we did over allocate a resource? Let us deliberately add a conflict to our schedule to
see what would happen. We will do this by adding a second envisionment meeting and hold it on the same
day as we are reviewing the first envisionment meeting. Select goal 9 and insert a new row (Insert | New
Task) and then enter the following into the schedule:
When I was using Project 98, it wouldn’t allow me to enter the finish date as Thursday, January 17th 2002,
so we must make Project 98 let us do it. To do this, double click on the goal and bring up the task
information window.
96
Creating Project Schedules
Click on the Advanced tab and make sure that everything looks the same as the above. When you click on
OK, you may see this window pop up:
Click on the third option and press OK. This window may then pop up:
97
Chapter 3
Click on Continue and press OK. The schedule should then look something like this:
However, we have not yet told Project 98 where we are holding these meetings, so let’s add a new resource,
the meeting room. Select View | Resource Sheet and add Meeting Room to the list: it should look
something like this:
98
Creating Project Schedules
Now we need to tell Project 98 that the First Envisionment Meeting will take place in the meeting room.
Click View and go back to Gantt view. Double click on goal 7 to bring up the task information window. We
will be using the whole room, so enter the units as 100%. Task information should look as follows:
Repeat this for goal 8 and goal 9; the schedule should look like this:
Notice how the resource name appears on the right hand side of each goal in the schedule. As we are fully
utilizing the resource, there is no percentage mark beside it.
99
Chapter 3
Now that we have entered this information into our schedule, we would like to look it over and make sure
we have used our resources correctly. Go to the menu, select View, and then select Resource Graph. Put
the cursor over the time scale and right mouse click. Select Timescale from the dropdown menu. Make
sure the major scale is in weeks and the minor is in days. Scroll over to January 17 and make sure that you
select Meeting Room on the left hand side of the screen. You should see the following:
We can see that we have overscheduled our Meeting Room for Thursday, January 17.
Although I had to deliberately insert a conflict of resources into the schedule, you can see that the resource
graph tool can be a very powerful aid in helping you manage your project. As you begin to include all of
the resources relating to your project, there is an awful lot of room for errors in resource allocation. The
resource graph tool can help you keep a check on these, especially when you may not realize that conflicts
occur.
100
Creating Project Schedules
Right mouse clicking on a link will give us a dropdown list, which includes the Gantt chart wizard:
You can also click the Gantt wizard button on the standard Toolbar to open the Gantt wizard:
You must select the rows you want to format. Put the cursor over the numbers on the left column, hold the
left mouse button down and select the rows. You should now have:
101
Chapter 3
Open the Gantt chart wizard. The first screen of the wizard will look as follows:
This brings up a very important part of a project, the critical path. At this point, all goals look the same.
Yet, some goals are much more important that other goals. Critical goals are the ones that must be
accomplished for the project to succeed. In our schedule, administrative time and studying Visual Basic are
not critical goals. If we do not accomplish these goals, the project should still succeed. It is essential to
identify which goals are critical. As this is just a sample project, we will include all goals in the Gantt
chart, so leave the Standard button checked. A complete, real schedule might only show the critical goals,
in which case we would check the Critical path option button.
102
Creating Project Schedules
Click Next and on the next screen select Custom task information.
Click Next. On the next screen, select Name in the Left box. You could add any fields you want, such as
the resources, but I am leaving them out to prevent the chart from becoming overcrowded.
Click Next. Step 11 allows us to add labels to our summary Gantt bars, which are the black bars that
represent the goals that have sub-goals. Step 12 gives us the option to include labels for milestones. The
next screen in the wizard, Step 13, asks us if we want to include link lines between dependent tasks; leave
this option as Yes, please. You should then see the final screen:
103
Chapter 3
Click the Format It button and your Gantt chart should be transformed: simply press the Exit Wizard
button to return to your schedule.
If you chose to follow these steps, your schedule should look like the following:
104
Creating Project Schedules
Project 98 Tables
Project 98 uses tables to display the information. Go back to the Gantt view. If you now go to the menu and
select View, then Table:, you will see the following:
This shows that you are currently viewing the Entry table. This is the table that you use by default to enter
information.
Cost Estimates
We can choose other tables to view information. Select Cost from the drop down list. The cost table view
should look as follows:
105
Chapter 3
We haven’t entered any costs for any of our goals, so our project isn’t costing us anything! However, you
can see that this can give us an estimate for the cost of each part of the project. The estimate at this stage
would be based on our estimates of the time we think the project will take: these are likely to be refined as
we go through the project, and so the costs are only as accurate as our estimates allow. Building a software
project is not cheap: this is where Visual Basic’s wide range of applications and object oriented
programming come to the rescue.
By building reusable components that can work in a wide range of environments, from the client exe to the
web class to the Office VBA macro, we can reduce the total number of components we need to build. If the
components we build in this project will be part of the next project, then we will eliminate a large portion
of the cost of the next project.
The cost of the envisionment phase can sometimes be seen as prohibitively high. Visual Basic projects are
very complex. The vision/scope document puts this project into a general Enterprise architecture that will
allow it to work with existing and future components. The vision/scope will also allow components of this
project to be reused in future projects. This in turn will save money. The vision/scope will give the project a
clear well defined purpose which will allow the project to have the maximum probability for success.
106
Creating Project Schedules
What happens when you skip this stage? Your project will end up with no well-defined goals or purpose.
The project will stumble along and discover its purpose along the way. The design will be in constant flux
and the code will be rewritten many times before the Visual Basic team comes close to delivering
something acceptable to the user. Let us say that our average VB developer is costing us $75 an hour (a
cheap rate in the current market). If we have four developers hacking away and skipping the envisionment
phase which results in only four weeks of extra development time, we come up with $75x40x4x4=$48,000.
Not too bad, but we must take into account debugging the code. Since the project was not well organized
prior to writing the code and many changes have been made in the middle of coding, it is highly unlikely
the code will be clean and have well-defined components. This in turn will be a debugging nightmare.
Finding a small bug may take days. So, let us add another four weeks of extra debugging time at a cost of
another $48,000. We now have reached $96,000.
Am I exaggerating my figures? In my experience, projects that lack an envisionment phase and have a poor
design phase will require about one month of extra time for coding and one month of extra time for
debugging for approximately every three to six months of the project than a project with an envisionment
and design phase. I am not saying this is a hard and fast rule, but this is about average. Besides the extra
time and expense, the code of these projects lacking an envisionment phase is almost always not built out of
components. They are code islands in which none of the code within them can be reused in future projects.
Of course, the argument of cost may be a moot point if the lack of envisionment and design phases results
in the complete failure of the project.
While it may seem like a large expense on the front of the project, it is an expense you cannot escape.
Either you pay for detailed envisionment and design phases that give you a project that fits in the Enterprise
and gives you reusable components or you can pay for a longer development time, unmanageable code and
code islands. This is an inescapable truth of managing a Visual Basic project and this must be made clear to
all senior managers.
Another point to be made here is that once a thorough vision statement is made for one project, it will be
reused in future projects that are fulfilling that vision. Thus, the initial project will incur the most cost and
future cycles will only need to define the scope. Therefore, this high cost will only occur during the first
cycle.
When you have read through the rest of this book, you will understand the different phases of the cyclic
methodology and what they entail. In Chapter 13 you will see an example schedule for the project we build
up during this book - here, you will see the complexity of Visual Basic projects and appreciate how a
scheduling tool can help you manage your projects. You will also be able to see more on how to make cost
estimates for your project and resource allocation.
107
Chapter 3
108
Creating Project Schedules
Click the New… button. In the Table Definition form enter the Name as HTML Export. Click on the first
row in the Field Name column and the drop down list box of all of the field names will appear. Select
Name. In the next rows select Resource Names, Start and Finish. The form should look as follows:
109
Chapter 3
Unclick Lock first column. Change the Row height to 3. Click OK.
Close the More Tables dialog and then go to the menu and click File | Save As HTML:
110
Creating Project Schedules
The Export Format window will now come up. Click on the New Map... button.
111
Chapter 3
On the Define Import/Export window check the Tasks button. This will make the Task Mapping tab
accessible.
112
Creating Project Schedules
113
Chapter 3
Select OK on the Select Base table form, select OK on the Define Import/Export form and click Save
on the Export Format form. The table will now be built. Open the table in your web browser.
114
Creating Project Schedules
We will use this feature later. If you use this feature, you can build a web application very easily which can
be viewed by all team members.
115
Chapter 3
Summary
Making an accurate schedule requires you to balance your resources so that all of your goals get
accomplished. Project 98 is an excellent tool that allows you to allocate your resources to your current
goals. Project 98 offers a wide range of views of the information that allows you to adjust, refine and
improve your schedule so that no resources are over utilized. Project 98 also allows you to export your
information into HTML format so that you can build web pages out of your schedule.
There are many more features in Project 98. You can go to the web site we mentioned at the beginning of
the chapter to explore some of the additional features. You can create workgroups to share project
information and resource information, set the importance of a goal, add additional resources, etc. Explore
some of the other views and tables. I really believe this is a product you will find valuable for your Visual
Basic projects.
Learn how to accurately estimate the time it takes to accomplish your goals. Keep a record of when you
make a mistake so you can learn from it. Keep old schedules as a reference for time estimates. Making an
accurate schedule is an essential part of being a team member of a Visual Basic goal-driven team. It is an
important skill to learn in order to succeed as a member of the team.
116
Creating Project Schedules
117
Chapter 3
118
Envisionment Phase
The creation of any new product or system must be driven by the needs of the client organization. The work
performed during the envisionment phase is, in broad terms, geared towards obtaining an understanding of
these needs. The team must obtain an understanding of exactly what the client requires, what is driving the
requirement and, therefore, what problems must be solved and what benefits the client expects to derive
from the solution of these problems. In this manner we can move towards a definition of exactly how these
requirements may be satisfied.
Before we get into a full discussion of envisionment, let’s have a summary of the key deliverables from this
phase of the cyclic methodology:
The testing members of the development team will be busy reviewing the initial goals of the project and
developing general testing scenarios. While the specifics of the components of the project are not defined
during this stage, the overall type of the project is known, that is, an E-commerce application or an intranet
application, and general methods of testing for different types of applications can be determined at this
point.
The component managers and project manager should be working towards building component teams and
creating a master schedule for their teams. These schedules will need to be rolled up into one large master
schedule(which will look like the schedule we made in the last chapter). By the end of the envisionment
phase, the schedule should be revised to give a detailed accurate schedule for the next phase, that is the
design phase.
The logistician will be the primary architect of the Enterprise Architecture document, which assesses client
infrastructure and business processes. The logistician will deal with infrastructure while the product
manager would answer corporate environment issues that would need to be addressed by the high-level
client management. The educator would answer any issues in the EAD relating to end users.
120
Envisionment Phase
show what business processes will be affected by these goals and how these processes will be improved
by these goals.
To accomplish all of this during the envisionment phase will require a commitment to the project from the
entire team right from the very beginning of this phase. Working together, a consensus can be reached as to
what the higher-level goals of the project are. The business processes needed by the enterprise will drive
these goals. The available resources and creativity of the team members will shape them.
The conceptual stage of the design phase will redefine these goals from the user's
perspective and, in the logical and physical stages, these goals will be turned into an overall
design of the Visual Basic product.
The final Vision/Scope document, the main deliverable associated with the Vision/Scope Approved
milestone, will represent the goals that were arrived at by the entire team. The fact that the vision will
include a measurable result means that not only can we define why the goals need to be accomplished; we
can verify how successfully they have been accomplished.
There are many stages along the way to achieving the Vision/Scope Approved milestone. In this chapter our
main focus will be on the Enterprise Architecture document, the consensus meeting and estimation of the
Total Cost of Operations (TCO) and Return On Investment(ROI). The chapter will conclude with a listing
of each section that should be included in the Vision/Scope document.
121
Chapter 4
The corporate infrastructure is the technological foundation of the corporation and provides all of the
computing resources for the enterprise. Assessing every single aspect of the business of a huge corporation
is a formidable task. It is important that we focus on reviewing the part of the corporate infrastructure that
relates directly to our project, whilst giving due consideration to the system of which it forms a part. These
resources include hardware, software and people that allow the corporation to perform essential business
processes, including the essential functions of the corporation, communications, distribution of information,
reporting and achieving the corporate goals.
The Enterprise Architecture Document is a very thorough assessment of the current state of technology in a
corporation. It needs to be honest and accurate. There may be some areas in the Enterprise that may be
identified as being deficient and needing improvement. You must be professional when making remarks
that may be viewed as criticism. For example, you should say, "At this point, there is no effective system to
upgrade software and the current software is outdated by at least two years." instead of saying, "Their
software is extremely outdated, nearly useless. They do not even have any organized system to get new
versions of the software." Remember, everyone on the team, including the client, will see these documents.
You also have to be realistic that certain corporations may not be willing to accept the criticism. Yet, most
of the time, they will accept your opinion and use your Enterprise Architecture document as a tool to
improve their Enterprise Architecture. The investment in the envisionment phase can therefore extend far
beyond this project.
As noted earlier, the primary architect of the Enterprise Architecture Document will be the logistician and
the product manager with assistance in gathering information and creating the document from the project
manager. There will also be sections added at a later time by other members of the team.
In the following sections are the main questions that the EAD seeks to answer.
Evaluation of Technology
Current Status of Technology: This section gives an overview of how current the computer technology
is in the enterprise. Is the hardware and software current or outdated? Has the software been updated on
a regular basis? Do the system administrators have the authority to release new software? How efficient
is their communications system? Do they have email and Internet access? Are they currently using
Visual Basic 6? Are they building object-oriented solutions with Visual Basic? Are they building DNA
projects with Visual Basic? Are they working with Visual Basic script in Interdev? Are they still
building two-tier applications?
Flexibility: How easy or difficult is it for the corporation to change their technology? How flexible
are the people involved with the systems that may be changed by this project? How flexible is the entire
corporation? Have new technologies been quickly adapted?
Technological Importance: How important is technology to the corporation? Is using new technology a
part of the corporation's strategy? Are the members of IT a part of the decision processes for the
corporation? Does the person in charge of IT report directly to the CEO? Is technology considered an
essential part of accomplishing the corporation's goals? Is technology used to remain competitive and
produce the best products?
Methodologies: Is there any form of project planning in existence? Do projects run through a well-
defined methodology? (Do projects follow the four phases of the cyclic methodology?) Are the methods
used to manage projects successful? Have most of the corporation's products been successful or have
they failed? Are they open to new methodologies? Are any Visual Basic frameworks being used? Is
UML used to design projects? Are strict coding standards adhered to?
122
Envisionment Phase
Component Resources: Are outside consultants used for building systems? Are pre-packaged solutions
commonly used? How much are the internal resources relied on? What role do custom solutions play in
the corporation?
Network: What is the current bandwidth of the network? What is the total amount of storage space?
What types of systems exist: mainframe, UNIX, Microsoft? How much can the network currently
handle?
Client Resources: What technology exists for the client computers? What systems exist on the client
site? Does the client site have Internet and email access?
Developer Resources
Type of Developers: Are there currently Microsoft developers? Are there Visual Basic Developers?
What are the skill sets of the developers?
Attitude: What is the attitude toward developing Microsoft solutions?
Experience: Has anyone built Visual Basic object-oriented projects? Has anyone built 3-tier
applications? Are the team members open to learning new skills? Does anyone have Microsoft
certifications in Visual Basic?
Number: Are there enough developers for the project? Can additional developers be added to the
project?
Geographical
How is the corporation geographically located? Is there one central location? Is the corporation spread
across the continent or across the entire world? Are there many small offices, or are there only a few
smaller offices? What is the communication between corporate offices in different geographic locations?
123
Chapter 4
Financial Resources
Hardware: What funds have been allocated for upgrade of hardware? Who is responsible for approvals?
What has been allocated for hardware upgrades for this project?
Training: What funds are allocated to general training? What funds exist for training for this project?
Are there funds to train their developers for this project if it is needed? What training facilities are
available? Does training have a priority in the corporation?
Continuing Support: How much money exists for future development?
Software: What funds have been set aside for the development or purchase of new software systems?
Overall: What is the current status of the corporation? Is their budget extremely tight or is there a large
financial surplus? How much money can be contributed to development of new technology?
Realistic Expectations
General: How realistic are the expectations of the client? Are there realistic constraints or are the
constraints (such as time to complete the project) arbitrary?
The functionality of the project is proportional to the time and financial resources available. If you limit
either time or financial resources, functionality must also be limited. Clients often want full functionality
completed in a very short amount of time. This time limit is not based on an analysis of the project, but
based on when someone would like it done. These projects are bound to fail. If you want full functionality,
you need to allow sufficient time for the project as well as substantial financial resources. Time and budget
constraints may mean that some of the less important functionality must be left out, or put off until a later
date. The purpose of the envisionment phase is to determine what functionality is critical for the system and
must be implemented in the first few project cycles and what is not critical and can be left to later cycles.
The critical question is: can the highest priority goals be achieved within the financial and time constraints
of the project?
124
Envisionment Phase
One could give many reasons to invest in a consensus meeting. Certainly getting input from everyone
involved will result in more ideas and a better set of goals. Yet, there is something far more important about
the consensus meeting. When people are assigned goals that they do not understand the purpose of, nor
where the goals come from, they will have little motivation to accomplish the goals. Involving the entire
team in the definition and refinement of the project’s goals ensures that everyone understands why we are
trying to achieve these goals and where these goals come from. The project manager can play a very
important role here. Team involvement also means that everyone feels that they had an input into the
creation of the goals. The goals therefore belong to every member of the team, and every team member
feels they are accomplishing goals they created. This gives a new meaning to achieving the goals and
maximizes the possibility that the goals will be successfully accomplished. One word of warning: the more
people you involve the more opinions you get and the more difficult it can become to make a final decision.
You need to ensure that there is always someone (probably the product manager) who can act as a mediator
when differences of opinions arise.
The questions that should be answered by the end of this process are:
The sponsor should lead the first meeting and begin with an explanation of the meeting and how it will be
run. Once this is done, everyone should introduce themselves and their roles in the project. Some means
should be provided to record the meeting in a way that all of the people attending can see summaries of
what has been discussed. Either use large white paper or some way to project the notes onto a screen visible
to all the participants. The product manager should assist the sponsor in running the meeting, keeping
things on track and moving along. Each meeting should not extend much beyond half a day.
The focus of this meeting is defining the project’s goals and prioritizing the goals. Prioritizing goals is not
as difficult as most people think. We will divide goals into three classifications of priority: high,
medium and low. High priority goals are the ones that we must do for the project to be successful. If we
cannot accomplish our high priority goals, there is no reason for doing the project. Medium level goals add
value to the project and make the business process more efficient, but they do not have to be in the scope of
the first few cycles of the project. Low priority goals usually are some unneeded feature someone would
like to be added on, and usually are not included in the project. Low priority goals will add little to the
efficiency of the business process.
125
Chapter 4
It is important to define goals at a high level at this stage, in order to keep the
process manageable.
When we are only comparing two goals it is fairly easily to decide which goal is more important than the
other. Yet, what do we do when we have dozens of goals? The easiest way to prioritize a large number of
goals is to perform comparisons of two goals at a time. This can be accomplished by building a table whose
columns and rows contain the goals. For example, if we have six goals we would have the following:
The dashes (−) represent blocks that are to be ignored. Start at the first column and move down and
compare the goal associated with the column with the goals in the row. For example, as we move down the
Goal 1 column we will rank Goal 1 against Goals 2 through 6. If Goal 1 has a higher priority than one of
the other goals, we place an X in the cell. If it has a lower priority, we do not place a mark in the cell. In the
following table, for example, Goal 1 is voted to have a higher priority than Goals 3 and 4 but Goals 2, 5 and
6 are a higher priority than Goal 1:
Goal 1 − X X X
Goal 2 −
Goal 3 X −
Goal 4 X −
Goal 5 −
Goal 6 −
Notice that since we have rated the priority of Goal 1 against all other goals then, logically, we have also
ranked all other goals against Goal 1. Thus, we can fill in these rankings in the Goal 1 row. This process of
filling in the chart by comparing two goals at a time is called a two-goal comparison. We must perform
this comparison for every established goal. Everybody present should be allowed to voice their opinion
when prioritizing goals in this manner.
126
Envisionment Phase
Once we have defined our goals in this manner, we will have our vision. Next, we have to define our scope.
To do this, we must begin to make a plan for how we are going to transition from where we are to where we
want to be. At this point, we must determine what goals will be accomplished in the first cycle, the second
cycle, etc. The goals that will be chosen for the first cycle will be the most critical goals, deliver the most
functionality, and fit within the constraints of the project. Once the cycles have been defined, we can focus
on the first cycle of the system development.
By the end of the meeting, the project’s goals should be defined and prioritized based on a consensus
agreement. The results of the meeting must be written up and used to prepare for the next set of consensus
meetings.
We will end this section by taking a look at a specific example of the above process. Let’s consider our
Northwind Company, who wish to establish a new E-commerce site. The company has studied its market
and the manner in which it conducts its business and has decided that in order to improve status and
profitability it must grab a share of the Internet market. This need has been analyzed and specific goals
identified. We join them at the stage where they are choosing the goals to be accomplished in the first
project cycle. The goals to be prioritized may be expressed in the following manner.
1. Increase number of orders (and ease and efficiency of ordering process) by transferring a substantial
proportion of its order processing from telephone to Internet.
These are all important goals but Northwind is anxious to get the site up and running within a reasonable
timescale and it may not be realistic to expect to achieve all of them in the first project cycle. Thus, the
goals are prioritized as described above and we end up with the following table:
1 2 3 4 5 6
1 − X
2 X − X
3 −
4 X X X −
5 X X X X − X
6 X X X X −
127
Chapter 4
Looking at this chart, we can quickly see that Northwind’s top priority is to regain lost customers. This
along with Goal 1 may be considered high priority goals. Goals 2 and 4 would probably be assigned as
medium priority goals whilst Goals 5 and 6 would almost certainly be classed as low priority goals.
It is important to remember that low priority goals are not always unimportant goals. They
may be low priority only in the fact that they may be beyond the scope of the first project
cycle.
Thus, using this chart has given Northwind a measurable way of determining what goals are the most
important, instead of just a subjective opinion as to what is and is not high priority. Just as important as
identifying priority goals is defining measures by which we can determine whether or not the goal has been
achieved. This should be accomplished by the end of the first set of consensus meetings with senior
management. Thus Northwind’s list of prioritized measurable goals for the first project cycle may look as
follows:
3. Regain customers lost to competition (who have already established this service)
Regain 50% of the customers lost over the last two years.
Regain 75% of the customers lost over the last year.
128
Envisionment Phase
In practice this is sometimes difficult. Some of the current project's development team
members may be heavily involved in the latter stages of a different project. It is important
that they have access to the reports from these meetings and are allowed to submit their
input. There are many ways of doing this, as we will discuss shortly.
These meetings begin with a summary of the first meeting with senior management. The purpose of the
second consensus meeting is to take the goals identified by the stakeholders and sponsors to be included
within the scope of this cycle, which were defined at a high level, and drill down to the next level of
analysis to arrive at a set of second level goals. The stakeholders and sponsors do not need to attend, but
their attendance may be of benefit to the meeting. It is possible that upon looking more closely at one of the
broader goals of the senior management we may find that it needs to be redefined. We may also find
additional broad goals that should be included in the project but were not. If senior management is present,
these changes can be made at the meeting and the redefined goals can immediately be broken down into the
next level.
If senior management does not attend the later meetings, they should receive a synopsis of the meeting at
the end of the day. You could also set up a live hook-up for the senior management who do not attend so
that they can watch the meeting as it is happening. If they hear something at some point that they feel they
need to comment on, they can join the meeting by electronic media, telephone or by physically joining the
meeting. You could even set up a computer in the meeting to receive comments from those watching but not
present so the meeting flow is not interrupted by someone suddenly joining in. Today, there is a wide range
of technology that allows you to include people who are not physically at the meeting.
Another possibility is to record the meeting and then put the video on the web site. Everyone, including
those who did not attend, can review the meeting at their leisure. You can allow a one-day break between
meetings to allow everyone time to review the meeting. You can create a web page to submit comments,
thoughts and ideas on the meeting.
Use what is appropriate for the situation. If you are designing a large project that will go through many
cycles and will reengineer the corporation, then it would make sense for the senior management to be
involved in all of the consensus meetings. For example, a corporation that is doing business solely through
phone sales decides to build an E-commerce site. They are going to make a major new purchase in hardware
and hope to shift most of their business to the E-commerce site. When the E-commerce site becomes
functional the current order entry personnel will focus on customer service instead of taking orders. Such a
major change in the corporation should have senior management involved in all of the meetings.
On the other hand, we could have a large corporation that is always plagued by personnel shortages that
decides to build a special human resources web site. This site will list job openings, information on the
corporation, benefits, etc. This HR department is part of a large department that also includes the payroll
and benefits departments. The sponsor is the manager of the three departments. While it is important to
have this person’s commitment to the project and to know what their goals and
concerns are, it is unlikely they will have anything to contribute to the second consensus meetings. This is a
high level person with limited time resources. It is unlikely that you will be using their time wisely by
involving them in these meetings.
129
Chapter 4
If at all possible, the consensus meetings should not be held on site. It is too easy for people to return to
their desk at breaks and get caught up in work: people will be returning late, assistants waving at the door,
etc. will interrupt others. It is best to get an offsite room - make it a large one so that you can adorn the
walls with lots of paper.
The most difficult part of these meetings is defining how deep one should drill and what should be
discussed. If you start discussing how something is to be done, then you have strayed out of the
envisionment phase and into the design phase. You should be describing the goals in a fairly general way in
the envisionment phase. For example, an acceptable goal description for this phase may be: Have a
customer enter an order through the Internet using an easy-to-use web page. If the team starts to discuss
exactly how this will be done (the customer will navigate to the site, the customer will enter order
information etc.) then this would be going too far. At this stage the project manager must get the team back
on track. This final level of analysis will be done in the conceptual stage of the design phase.
Let’s now take an example of how we might drill down into the high level goals we identified for the
Northwind order entry project.
Primary Goal:
Building a customer Internet site that will handle fifty percent of all customer orders, increase orders,
regain lost customers, capture new customers, and improve customer service.
The goals expressed in this vision are first level goals. Iwill call the sub-goals of this first level goal the
second level goals. This is to make it easier to talk about the different sets of goals. I am not limiting the
goals defined by management to two levels. It will be necessary to drill down to third or even fourth level
goals in order to arrive at the level of analysis that can provide a foundation for the design of the product. I
am defining first level goals for the primary goal as defined by management, and second level goals for all
of the goals that management creates to support the first level goal.
130
Envisionment Phase
2. First level goal Regain customers that were lost to the Internet market.
Second Level Goals:
iii) Improve customer representative’s jobs so that they devote more time improving customer service.
Get higher ratings for providing customer service on customer surveys.
See 1 i).
These are broad vision statements. There are no statements in here that describe how these goals will be
achieved, only what we want to achieve.
Just where did these vision statements come from? The term vision can be applied to a corporation in many
ways. We have been discussing the vision of the project. Each corporation will also have a vision (mission)
for the entire corporation. I will call this corporate vision to differentiate it from the project vision we have
been discussing thus far. In the best corporations, this corporate vision is documented and known to the
entire corporation. The corporate vision focuses on the goals of the entire corporation. Examples of
corporate visions are:
131
Chapter 4
The vision statement for the project should not be a radical new rethinking of the corporate vision. Instead,
the project vision is a subset of the corporate vision. In this case it is clear that the project’s second level
goals could be considered a subset of the second, third and fourth corporate vision statements listed above.
Notice that not only are the first level goals associated with a way of measuring whether these goals have
been achieved, the second level goals are too. Either the corporation has achieved a 30% reduction in the
cost of taking orders within six months or they have not. While we have not shown this in our examples,
there should also be an explanation as to why a goal is important and what business processes will be
improved and/or affected by the achievement of a goal.
An assessment of current business processes as set out in the EAD (notes from the meeting should be
added to the EAD)
A set of third level goals to take forward to the Design phase (to be included in the Vision/Scope
Document)
A definition of the scope for the project cycles (to be included in the Vision/Scope Document)
Business Processes
The meeting(s) should focus on three things: the past, the present and the future. The past and present
determine where the corporation currently is. It is important to have an understanding of the corporation’s
past and present before walking into the consensus meeting. This is why you should create an Enterprise
Architecture document prior to the consensus meeting. This document is a tool that can be used to build the
corporation’s future. When the consensus meeting is finished, the information gathered on the current state
of the corporation’s technology should be added to the Enterprise Architecture document.
Talking about current business processes also makes it easier for people to think about future business
processes they would like to see in the work place. Looking at current business processes, we can see what
works very well and what is not working at all.
When beginning the second set of meetings with the entire team, it is a good practice to make it easy to take
notes that the entire group can see, just as we did in the first meeting. One possibility is to cover the walls
with large sheets of paper and have someone with neat handwriting take notes during the meeting. A piece
of paper can be devoted to the current business processes that will be impacted by the project. On top of the
sheet should be the name of the business process, and the rest of the sheet should be divided horizontally
into three sections labeled Positive, Negative, Neutral. You can then have the group discuss the positive,
negative and neutral aspects of the business process. It is quite possible a business process will only have
one section filled out. Those processes that have the majority of entries in the Negative should be reworked.
The processes that are ranked positive should be used as examples to build new processes and should be
maintained if possible.
It is important that everyone is allowed to speak freely during the discussion of the present corporation. No
matter how tempting it may be to comment on someone’s suggestions, it is important that no comments are
made that inhibit people from speaking openly. It is also important that the meeting does not degenerate
into a session to air grievances or start running off track.
132
Envisionment Phase
It is the role of the product manager to be the facilitator, to control the meeting and to make sure everyone
stays on track. The product manager keeps the meeting moving, draws everyone in, makes sure all the
people are participating and are comfortable enough to be honest. The educator and logistician can assist
the product manager.
Once the present has been discussed, the meeting moves into the future. As you start to talk about the
future, there should be no constraints, such as budget or time, placed on the initial discussions. In the
beginning, the team members can express whatever ideas come to mind to allow a brainstorming session. If
a team member feels that, in the past, their job has been made difficult by deficient software, then their
input will be valuable in determining exactly the sort of functionality that the new product should embrace.
Therefore, it is vital that they are allowed a say as we start to drill down to the third level goals that will
provide the foundation for the design of the product.
You can place on the top of a piece of paper the first and second level goals, as we defined them in the
previous section. Each of the second level goals may be expanded down one level further into what I will
call third level goals.
Remember, these goals do not necessarily have to be three levels deep, I am using
this term to make it easy to understand the different sets of goals defined at
different times. The first level goals are the primary goals of the project, or the
vision. The second level goals (defined largely by senior management) support the
primary goal. Third level goals are the ones created by the whole team to support
the second level goals. It will be necessary to drill down to a sufficient level of detail
that the goals can act as a "template" for the design phase. Just how deep we need
to drill is an important decision that must be made by the project management.
Again, no constraints. There will be time during the last part of the consensus meeting to sort out what fits
within the constraints of the project. When there are no constraints placed on what people can suggest, you
will be amazed at how much information flows. Place constraints on what can be suggested and people will
often withhold valuable ideas because they are afraid they may not fit within the constraints.
Following is a list of third level goals that may be identified during the second consensus meeting:
133
Chapter 4
Document all customer complaints and route the complaint to someone who has the authority to handle
the complaint.
Make it easier for the customer to submit a complaint.
Make it easier for the customer to submit suggestions for improvement.
Make it easier for the customer to place an order.
Reduce the number of orders the sales people are handling so they can spend more time working with
customers.
Make customer and product information quickly available to the salesperson.
Allow customers to review the billing history.
Let customers know about future discounts.
Give customers discounts based on the items they buy.
Give customers more detailed product information.
These third level goals are the ones that I can come up with immediately. In a real consensus meeting with
many people attending, each coming up with a few possible suggestions, this list could be very long. We
will need to prioritize the goals, choose the ones we will try to do in the first cycle, and then determine
which ones fit into the scope of this particular project.
There is one goal here that illustrates a very valuable point. Looking at the goal "make customer and
product information quickly available to the salesperson", we have a goal that seems to have nothing to do
with building an Internet site. Normally, this would be part of a regular EXE application that runs on the
sales person’s workstation, not something that runs over the Internet (though it could work over an
intranet). If the goal of the first cycle is to build the first version of the E-Commerce site containing only
the critical elements, what does building an EXE for the workstation have to do with this discussion?
Everything. Two of our other goals are:
If we build a component that retrieves customer information for our Internet site, and another component to
retrieve product information for the Internet site, why couldn’t these components also be used to build an
EXE application for the sales person’s workstation? Both the Internet application and the EXE application
require identical information, that is customer and product information, so why not use the same
components for both applications? If we use the same components, we will substantially reduce the cost of
the EXE application. This brings out another major advantage of the consensus meeting (and of object
oriented development): we may find that the goals of the current project fulfill the goals of other projects or
other cycles.
When we create an Enterprise Architecture Document and review the goals in a consensus meeting, we get
to see the big picture: how everything fits together. We can see if goals in one cycle are similar to goals in
other cycles. Using this information, we can then see if the components we design to fulfill one set of goals
can be used to fulfill another set of goals.
134
Envisionment Phase
Component reuse reduces the overall costs of development, and will often more than
cover the costs of the initial envisionment phase. Without the envisionment phase,
these opportunities may be missed, and two or more teams may build components
performing the same function at the same time. This duplication is a waste of
resources.
At the end of this brainstorming session, the next task is to decide which of the identified goals fit into the
vision of the project. Those chosen will then need to be prioritized in order to determine the scope of the
first project cycles.
Defining Scope
The first part of this process will determine which of the suggested third level goals will be incorporated
into the vision of the project. What suggestions fit within the constraints of the system? Which ideas
contribute to the first and second level goals? What are the high, medium and low priority lower level
goals? Just as we did previously, making a chart and comparing two goals at a time can rank these goals.
If there are a large number of people participating in the meeting, then it is quite possible that you may
have a very large number of high priority third level goals. Even after comparing two goals at a time, you
may find that the number of high priority goals far exceeds the limitation of budget and time. There may
also be goals that did not rank very high, but may still need to be considered.
You can now start going through the goals that received the highest ratings in the two goal comparisons and
start rating them based on the following:
For example, if a critical daily report is currently generated using an Excel spreadsheet by cutting and
pasting information from one sheet to the next, a goal may be to create a Visual Basic application that
allows the information to be inputted and formatted without cutting and pasting. If we analyze this goal we
can see that there is a very low risk here. It will improve the accuracy and the speed to produce the critical
report, the person entering the information will be the one affected by having a more efficient way of
producing the report, and it will decrease the amount of effort by eliminating a repetitive task (cutting and
pasting) and replacing it with an automated process.
Most of the goals will be low to medium risk. We will discuss risk evaluation in detail in the next chapter.
For now, realize that risk is both in the process of building the application (not enough resources, time,
technology may not yet be available, etc.) and also the risk that the measurable results may not be achieved
(such as building an Internet site and getting customers through the site).
135
Chapter 4
Once the third levels goals are chosen, we will have to place the goals into the cycles that we will have to
go through to fulfill the vision. These brief summaries of the top ranking goals then can be reviewed by
senior management to make a final choice as to what goals form a part of the vision of the project.
The number of cycles there will be depends on the size of the project and what type of project it is. The
highest priority goals should be included in the first cycles. In our E-Commerce site we could have the
following three scopes: build the base Internet site with minimum order functionality, build the customer
suggestion and complaint portions of the web site, and build the product review portion of the web site.
In the development phase different teams can build all three of these parts of the project in
three different development cycles at the same time. When they are all complete, they can be
put together and implemented to become the first version of the E-Commerce site. Additional
functionality will be the scope of future cycles.
In a very large corporation where the project may affect thousands of people, it will be impossible to
include everyone in a consensus meeting. In this case, representatives of different groups should attend the
meeting. To make sure the final document includes the input of everyone, you can place the summaries of
the second consensus meetings on an intranet site. People from the entire corporation can view it and make
suggestions. After a period of time, the summary of the second consensus meeting and the comments
submitted through the intranet site can be given to senior management to make the final decisions.
Creating accurate estimates at this stage can be very difficult. We have no solution
yet, only goals. We may be able to quantify some of the benefits from the goals but
we will only know something about the magnitude of what we want to accomplish
once we've done our design and know how the product is going to be built. It is only
at this stage that we will be able to put together accurate development estimates.
Having said all this, it is unlikely that the sponsor will be willing to proceed to the
design phase with just a set of goals. Some estimation of the cost of the project will
have to be made.
In basic terms the TCO is the total cost of investment in an IT asset (such as an operating system). The ROI
compares the cost of the investment to the additional profit made by the investment. For example, for an e-
commerce site the cost of the investment will be the cost to build the e-commerce project and the TCO (cost
of licenses for the operating system, web server and the e-commerce software, the cost for maintaining the
site, etc.). Increased sales by having wider access to clients and a decrease in the number of operators
required to take orders are all ways the investment can increase profit. If the total cost of the investment is
less than the additional profit, it is a good investment.
136
Envisionment Phase
The Gartner Group does estimates for the cost of computers in a networked environment that can be used to
determine some of the hardware costs. There are some software tools that can provide estimates for
software, such as Price Systems. Creating a schedule with Microsoft Project 98 will also provide you with a
tool to estimate the cost of resources, such as team members. Microsoft provides a spreadsheet tool called
"TCO/ROI Desktop Advisor". It can be downloaded from the following site:
http://www.Microsoft.com/office/tco/
The larger a project is, and the longer it is expected to take, the more difficult it is to estimate the cost of
the project. If a project is not broken into cycles but consists of one long development phase extending over
several years, it is a much more complex task to estimate costs accurately. If you have
any doubt about this, go to your favorite computer dealer and get an estimate for the cost of one specific
computer. Check the price of the computer every two months. As new hardware comes out, you can watch
the price of the computer drop. Trying to estimate costs two years in advance is very difficult. Even worse,
the technology may have completely changed over a single year. New versions of software, or new types of
software such as SQL Server 7’s data warehouse may make a plan completely obsolete.
137
Chapter 4
By building the project in short cycles, it is unlikely that we will find ourselves using outdated technology
or methods in the middle of our project. Our estimates of the cost of the project should remain fairly
accurate over a short cycle. The estimate for the next cycle of the project will be the most accurate, the
estimate for the entire scope will be less accurate and the estimate for the entire system to be built
according to the vision will be the least accurate. Using the cyclic methodology will help us make fairly
accurate estimates of the costs of each project of the system.
When making an estimate of the costs of a project, you should make a detailed estimate of the cost of the
cycles you are about to design. Future cycles should only have a general estimate, which will be refined
when it comes time to actually begin the cycle.
There are also unexpected expenses, such as down times, equipment failures, etc. These should be taken
into consideration, included in the risk document, and figured into the total cost of the project.
It sounds like stating the obvious but the safest way of securing a positive ROI is to choose a project where
the estimates indicate that there will be a very high ROI. Even in cases where there are unexpected
expenses or additional costs, a project with a high ROI estimation will still usually give a significant return.
Projects that increase productivity, reduce costs, improve customer service, etc., are all projects that have
the potential for a high ROI.
Introduction
The introduction contains general information about the document, the project and the team.
Primary Goal
This section will contain the overall goal for the project. In our example above, the overall goal was:
Building a customer Internet site that will handle fifty percent of all customer orders, increase orders,
regain lost customers, capture new customers, and improve customer service.
138
Envisionment Phase
Document History
When the first cycle is completed, and the scope of the first project has been implemented, it is time to
move to the next cycle with a new scope. This new scope will fulfill another part of the vision of the
project.
The initial Vision/Scope document will identify the scope of future cycles in broad terms, which will need
to be refined and clearly defined when it is time to begin a new cycle. This in turn will result in the addition
of extra information to the Vision/Scope document. It is also possible that the vision may have changed
since the last cycle began. New goals may have been established, new technologies may have emerged or
Visual Basic may have undergone another revision and offer new opportunities. Any of these will result in
an update of the vision statement. These changes should be documented in this section, including a reason
for the changes. Copies of the original documents should also be maintained. The Vision/Scope document is
a living document that may guide the corporation’s development for many years.
Change Control
Change control is necessary for every document in the project. Without this control, anyone could add and
remove information in the document. This section needs to identify the following:
What types of changes are allowed in the document? Changes can include editorial corrections and
updating scope statements or goals.
What is required to get approval for changes? For editorial changes, it is likely that these changes can be
made easily. Changes of goals may require a meeting with several or all of the team members.
Team Members
This section lists all of the roles for the team and who will be fulfilling the roles. This section should also
list responsibilities of each team member and the consequences if they do not fulfill their role. Listing
responsibilities and consequences is especially important for the client who may not know what these are.
Project Cycles
This section will go through all of the different cycles that will be needed to complete the vision of the
document. Each cycle will have a certain scope associated with it, that is a set of goals that will be
accomplished in this cycle. Each goal should have a set of milestones associated with them and a set of
reasons why these goals need to be accomplished.
First Cycle
Summary
A general discussion of the scope of the current cycle. It will list what is to be included in this cycle, as
well as what will not be included in this cycle.
139
Chapter 4
Scope
This subsection will list all first and associated second level goals that will be completed within this cycle.
All of the goals that were identified in the consensus meeting will need to be ranked in terms of priority.
The highest priority goals will need to be accomplished first. The medium priority goals will be
accomplished in later cycles if the resources do not exist to do them during the first cycle. For instance, in
our above example we could consider the following goals as our high priority goals and include them in the
first cycle:
2. First level goal Regain customers that were lost to the Internet market.
Second Level Goals:
These goals will not only define the initial design of the site, but also what we will need to do to design the
web site. Thus, meeting the second level goal "make a better site than the competition", will dictate that
during the design phase there will be research of competitor’s sites in order to define their strengths and
weaknesses along with additional research into very successful E-commerce sites.
The second level goal "track customers’ needs, complaints and problems" will also add definition to the
site. There will have to be HTML pages devoted to taking customer complaints, and some system
to process these complaints. These pages will also help achieve the goal "improve customer service". Of
course, there may be many more ways to improve customer service, and this is likely to be a topic that will
require a great deal of time in the second consensus meeting.
140
Envisionment Phase
The first level goal "getting back the customers that were lost to the Internet market" may require several
actions. One solution is to get a lost customer list that lists all customers that have not placed orders in the
last six months and create a special account for them. A promotion scheme may be devised whereby these
customers may have special discount prices for some period of time, probably one or two months. All of the
customers on the lost customer list can be sent a letter telling them about the scheme and how to access the
corporation’s new Internet site with their assigned ID and password. Of course, the site would need to be
able to display one set of prices for the special customers and other prices for other customers (that is a
promotion component would have to be designed that would function as part of the order entry system).
Thus, this goal will also define the features of the site and how it will work.
During the design phase we will take a more in-depth look at how the goals will affect the design of the
project.
The goals that are defined in the envisionment phase are the starting point for
designing the application. Without an envisionment phase, goals are missed,
improperly prioritized, or poorly defined. The end result is that the design will not
fulfill the primary goals of the corporation, and therefore the project will fail. In the
envisionment phase, the goals are defined based on a consensus. Every team member
may have important information to contribute and this information will become
part of the goals. A design based on these goals has the maximum possibility of
meeting the overall goals of the corporation.
Each goal should be listed separately. For each goal, you should have the following subsections:
First Cycle
Scope
Introduction:
The scope of this cycle is to get the E-Commerce site live with the majority of the essential features. This
cycle will not include the building of any of the customer service workstation applications.
141
Chapter 4
Goal
Allow customers to review the billing history.
Sub Goals
Send the customer an order confirmation via email. Customer representatives and sales managers will
accomplish this goal.
Risk Analysis
Documenting potential risks is an essential part of the project. The next chapter will cover risk management
and how to create a risk document. The risks identified during the envisionment phase
should be listed in a risk document and included with the Vision/Scope document. At least the top ten risks
identified by the consensus of the team during the envisionment phase should be included in this section.
142
Envisionment Phase
Resources
This section will list all of the resources that are available to the project, including financial, time,
technological and any other resource that may be needed by the project. A summary of the current resources
available and the resources that will become available during the project should be mentioned.
Conflict resolution
It is critical to have some system in place to resolve potential conflicts. What happens when the
development team decides that they cannot possibly meet one of the goals of the project due to constraints
on finances or time? What if the end users demand that the goal still be met within the projected budget and
schedule? Who will resolve this issue? Ideally, there should be one final person to resolve such issues,
usually the sponsor. Yet, you do not want to bring every issue to this person, as they usually do not have
time. The product manager will be the liaison with the client and can also have the final say. Some system
should be put in place to resolve issues first. When every means of resolution fails, then it should be turned
over to the person who can make the final decision. This system of conflict resolution should be described
in this section.
Project Schedule
A copy of the overall schedule should be part of the document. The schedule would look like the template
we created in the last chapter, except the schedule for the design phase will be more detailed and complete.
The master schedule should be posted on the Internet or secured intranet so everyone can view it.
143
Chapter 4
Business Processes
During the second consensus meeting the major business processes related to the project were discussed and
rated. These ratings, and the comments on the strong and weak points of the business processes should be
recorded in this section. The weaknesses will show where the project needs to make improvements. The
strengths will show how.
Possible risks, errors or omissions should be found in this final meeting. It is also possible to simply post
the information onto an intranet site (or secure Internet site) and allow the team members to review it and
submit suggestions. The suggestions can also be put on the web so people can view them and perhaps come
up with solutions to potential problems.
Summary
The envisionment phase creates the Vision/Scope document that will guide the entire project. The
Enterprise Architecture document, TCO and ROI estimates, and an initial analysis of risks will also be done
in this phase of the project. The primary purpose of this meeting is to create the first and second level goals
of the senior management and break them down into a set of third level goals. These third level goals form
the basis for our product design in the conceptual stage of the design phase. This whole process is geared
towards ensuring we have a product designed according to the needs of the user.
There are many ways to redesign business processes. One way is to create a radical change in the way a
corporation is being run. According to this line of thought, if the corporation is not running successfully
now, the business processes are failures and need to be abandoned. Radically new business processes need
to be created without any regard to the old ones.
Personally, I feel there are many lessons to be learned from the failures of the current business processes, as
well as many lessons to be learned from their successes. I feel that one can still radically
reengineer the company based on a careful analysis of the past and current business processes as we did in
the Enterprise Architecture Document. This document not only gives an assessment of the current business
processes, but also the state of the technology in the enterprise. You cannot realistically restructure the
technological infrastructure without understanding what is currently in place.
144
Envisionment Phase
The reengineering can span across the entire corporation altering workflows, changing job descriptions and
roles, organizational structures and virtually the entire company. Everything from the production line in the
factory, to the structure of teams, the availability of information and the means of selling products to a
customer, can change to meet current market needs. A radical quick reworking of the corporation with a
complete disregard to the past is a dangerous undertaking: more than likely it will be too much, too fast and
go beyond the corporation‘s resources.
With a carefully prepared Enterprise Architecture Document, everything will be in black and white in front
of you and the entire team. Everyone can review the document in advance of the consensus meetings, look
at the available resources, the future needs of the company, and try to find the best ways to improve the
corporation’s processes.
I highly recommend reading Bill Gate’s new book, Business @ The Speed of Thought. You will read about
the corporations of the future, and get some insight into where the modern corporation needs to be going.
There are many valuable insights into restructuring the corporation in this book. It is definitely worth taking
the time to read this book if you intend to be part of reengineering a corporation.
145
Chapter 4
146
Risk Management
Considering the high rate of failure for software projects, we can certainly say that a Visual Basic project
has a great deal of risk associated with it. The size and complexity of an enterprise project, and the possible
impact the applications could have on the corporation, are two factors that by themselves make the projects
risky. By identifying possible risks and properly managing them, we can substantially increase the
probability that our project will succeed.
What do we consider to be a risk to our project? A risk is anything that may adversely affect our project.
Adversely affecting the project means that something could decrease the functionality of the project or
could reduce the probability that our project will succeed. This would include things such as an increase in
the cost of the project, an increase in the overall time to complete the project, the inability to complete the
project, the project not being able to meet the needs of the client, etc.
Most of the risks to our projects can be managed. Managing risks requires clear guidelines of how risks
should be documented and handled. Every member of the team must be able to easily add risks to the risk
document. Risk documents, which are documents that list all possible risks to the project, will be described
in detail in this chapter. Team members must also feel comfortable with reporting risks. Often it is the team
members in the trenches who will be the first to know when something is going wrong, which means that a
risk has been realized, and it is usually these people who are most often afraid of reporting bad news.
Everyone must be allowed to submit risks without consequences.
One can handle risks proactively by making assessments of possible risks, documenting them, and then
creating a plan to deal with them. This plan covers two aspects: the first part is how to reduce the likelihood
of a risk happening, and the second is how to deal with the consequences if the risk does happen.
Chapter 5
One can also handle risks reactively, waiting for something to happen. Reactive risk
handling results in crisis management, jumping from one disaster to another, until finally so
much has gone wrong, the project fails. Obviously reactive risk management is not very
useful and usually causes the entire team to suffer burnout.
Identifying risks to the project will be the responsibility of every team member. While every team member
may play a role in managing the risks, it will be the component manager who will prioritize risks and
determine the probability that the risk will actually occur. The component manager will work with members
of the team to find solutions for high probability, high priority risks. Once solutions are found, the product
manager will make sure resources are properly allocated to reduce or eliminate the high probability, high
priority risks. This will be one of the key roles of the product manager in every part of the project.
To perform this assessment a document should be created that lists the standard risks to a project. The
senior developers, component and product managers can all come together to create one standard document
that lists a general set of risks that need to be ranked for every project.
To give you a place to begin, I have listed some risks to projects that can be included in your general risk
document. You can add to this list or modify it to suit the needs of your team.
148
Risk Management
Project Schedule
The risk of a project not being finished by the deadline is dependent on the schedule drawn up for the
project. If the project has been assigned an arbitrary schedule, based on the needs of the corporation rather
than on those of the project, this risk has a very high probability of being realized. At the other extreme, if
we have based the schedule on a detailed review of the project, the vision/scope document and the overall
design of the project, we can drastically reduce this risk, and, while we cannot guarantee that the project
will be completed on time, we will have a realistic timetable, which we ought to be able to meet. If the
schedule has been based on preliminary review of the project, but is determined prior to a detailed analysis
of the project, there will be a medium risk: there is a chance that our project will meet the deadline, but
unforeseen circumstances could easily cause the deadline to be missed.
Funds
The issue of funding for a project can prove to be a major headache. If funds are extremely limited, this is
very likely to cause the project to fail - without funding, there is no way the project can continue. However,
if there are sufficient funds available there is less of a risk that the project will fail due to running out of
money, and more of a chance that the project can continue as planned and be completed. If there have only
been some funds allocated, this is a medium risk: the project can continue, but there is a chance that the
project could go over budget.
Resources
A resource is anything that is used within the project to help bring the project to completion - examples are
people, money, time, computers, and meeting rooms. The risk to a project of varying availability of
resources is also another major consideration. If there are numerous constraints on project resources, the
risk is very high that the project will be under threat: if people do not have enough resources to do their job,
the project is very likely to fail. Also, if the sponsor is not in control of resources then resource availability
will suffer, bringing major flaws to the project. On the other hand, if the sponsor has responsibility for
allocating resources, and is committed to the project, there is a low risk: if the resources are made available
(for example, if meeting rooms, computers, or money is made available) people will be able to work on the
project. A medium risk would be if some resources were limited and some were flexible: the project could
continue, but if the limited resources applied to critical tasks, this would be a risk to the completion of the
project.
Personnel
The number and type of personnel available to a project can potentially threaten its chance of success. If
there aren’t enough people available, some may have to undertake conflicting roles (for example, testing
and development), or simply have too much work to do in the time available. This is a high risk to the
project, because if people are overscheduled, they will not be able to complete their given tasks - for
example, the project may not have full functionality as set out in the scope statement: if it doesn’t meet
expectations, the project could ultimately ‘fail’. However, if there are enough people available to fill the
different roles sufficiently, this is a low risk: each task will have somebody devoting their full time and
attention to it. If there were not enough people, but some people could double up team roles without
conflict, this is a medium risk: the tasks will still get done, but there will be less time available to spend on
them.
149
Chapter 5
Project Manager
You would be in trouble indeed if you did not have a project manager! Not having a project manager would
constitute a high risk, because there would be nobody to coordinate the efforts of the team, see that work
was being done and goals were being achieved, and seeing that the project was on time and on schedule. It
would be chaos! On the other hand, if there is a project manager with good planning skills, or experience in
object-oriented project design, this would pose a low risk - efforts would be coordinated and the project
kept on track. A medium risk would present itself if there were a project manager, but they didn’t have all
the skills needed to manage a project. Some areas of management would be lacking and could cause
problems for the project.
Client Expectations
The client's expectations of the project will have a direct bearing on the success of the project. If the client
has unrealistic expectations, such as full functionality in a very limited amount of time, this will pose a high
risk to the project: as you will probably not be able to meet these expectations, the client may lose interest
in the project and so jeopardize its success. If, however, the client fully understands the nature of the
project and what it can offer, this is a low risk. The client knows what the outcome of the project is likely to
be and accepts this. A medium risk, in this case, would be if the client still harbored some unrealistic
expectations for some parts of the project, but was willing to accept the rest.
150
Risk Management
Workflows
Workflow is simply a term used to describe the way in which work - information or documents, for example
- moves from person to person throughout the company. This movement, however, will adhere to a certain
set of rules. If new workflows are created by the project, this is a potential high risk to the success of the
project: people may not accept the new ways of working and, in turn, reject the project. If, however, the
project fits in with current workflows so that there are no changes to the way people will have to pass on
information, or training is implemented so that people know how to perform the new ways of working, this
is a low risk. A medium risk would occur if the project introduced only a few new workflows: these may
still cause the project to be rejected if opposition is strong enough.
Well-Defined Goals
In order to let people know exactly what it is they are supposed to be doing, the goals need to be very well
defined. The top-level goals will be broad in design, as by their very nature they encompass the whole
project. As you drill down, the goals need to be more detailed so that people can begin working towards
specific goals. If these lower level, or third level, goals are not well defined, it could result in poor product
design and people will be unsure as to what it is they are to do: this can pose a high risk to the success of
the project, as goals will not be able to be achieved. If the goals are well defined, this is a low risk, as
people will know what to work towards and what is expected of them. A medium risk would be posed by
the fact that, although the goals may have some clear definition, they are hard to accomplish.
Long-Term Results
The corporation needs to be looking towards the future and how it will survive in an ever-changing market
place. If the goals are created simply to address a problem the corporation is facing now, this is a high risk:
once the project is over, the corporation will still be in the position of having to catch up with the
competition, rather than lead it. On the other hand, if the goals are created with the long term future in
mind, this is a low risk: goals such as these would look towards utilizing evolving technology and building
systems that could easily have new functionality added if and when it was needed. A medium risk would be
posed by the fact that the goals were focused only on the short term, but they offered a creative solution to
business problems.
151
Chapter 5
Milestones
It is essential that goals have milestones to monitor progress, and also essential that these milestones can be
measured. A high risk presents itself when the milestones cannot be measured: there is no way to tell
whether the project is on schedule or what stage the project is currently going through. The opposite is also
true: if the milestones have binary measurements, these will serve to show exactly where the project is
currently and whether it is on schedule. This is a low risk. If the goals have measurements, but they are not
binary, this poses a medium risk.
Well-Tested Technology
Well-tested technology means that its functions and methods are widely known and understood. If the
project is not based on well-tested technology, and the technology used has not been formally tested, this is
a high risk to the success of the project: the ‘untested’ technology could prove to be unreliable or
untrustworthy and the project could fail. If well-tested technology is used, it poses a low risk, as people
know and understand how to use it. If untested technology is used, but there are plans to formally test it,
this would pose a medium risk: the functionality and methods would be investigated, then understood.
152
Risk Management
Testing
The project needs to be tested throughout the development phase to ensure that it works as expected without
any errors. Developers are not the best people to test their own code. There is a high risk of failure if testing
is not carried out until the end of the development phase and it is carried out by the developers. This means
that errors will not be found until the last minute, some may be missed because the developers are checking
their own code, and any errors found are very expensive and time consuming to correct. If, however, there
is a designated tester and testing is performed throughout the development phase, there is a good chance
that errors will be found, and corrected, early, presenting a low risk. A medium risk would be posed by the
fact that testing is carried out throughout the development phase, but the developers test their own code.
153
Chapter 5
User Contribution
It is very important to involve the users and keep their needs in mind throughout the project. If, however,
they are not available for interview during the conceptual design phase, they will not be able to make their
needs known, and this will be a high risk to the project: how can you keep the users’ needs in mind if you
don’t know what they are? A low risk is presented when the users are available at every stage of the project
and are representative of all the users of the system: a medium risk would be when some of the users are
available throughout the project, but are not necessarily a representative sample.
User Interest
It is paramount that users are interested in the project to ensure its success. There is a high risk of failure of
the project if the users do not see any positive impact of the project on their working life: the project is
supposed to focus on the needs of the user; if they don’t want it, how can there be a project? If the users can
see how the project will improve their working life, and actually want the project, this is a low risk: after
all, this is what we are working towards. A medium risk would be if the users could see a potential benefit
of the project, but do not fully understand the positive impact it could have on their working life.
Scope
The scope of a project defines what is to be achieved in one particular cycle. There is a high risk of project
failure if there is no project scope: more than likely, the project will try to achieve all the high level goals at
once, which, in most cases, cannot be done. A high risk would also be when the scope is unrealistic within
the constraints of the project. A low risk would occur when the scope is well defined and realistic in its
expectations. If the project has a scope, but it is not clearly defined, feature creep may occur, which would
pose a medium risk to the success of the project.
154
Risk Management
Change Control
Throughout the life of a project, there is the potential for many things to change - this is not entirely bad,
but it must be controlled. A high risk would ensue if there were no guidelines for recording changes to any
stage of the project, or if the design was not locked at the start of the development phase: in this way, any
part of the project could change without anybody being notified, and nobody would know the correct state
of the project. If there are clear guidelines, however, this is a low risk: it is also a low risk if the design has
been locked at the start of the development phase - this eliminates feature creep, and everybody knows what
he or she is supposed to be developing. A medium risk is when the design may be locked down, but there
are unclear guidelines on what to do if a part of the project changes.
Documentation
Documentation is an essential part of any project - it shows exactly how the project progressed and is a
reference for future teams. There is a high risk if there is no documentation at all - how will you know what
steps you have taken, or what changes have been made, or how the project is progressing if no records are
kept? The opposite poses a low risk: if there is detailed documentation for every step of the project,
showing how things are changing and progressing (especially the risk document), then it is easier to rectify
a mistake if the project should go wrong. There is a medium risk if there is some documentation, but it only
covers limited aspects of the project.
Definition of Goals
Goals must be clearly defined. If they are not, this is a high risk, as team members will not know what it is
they are working towards. If, however, the goals are detailed and have been drilled down to the correct
level for design of the project to commence then this is a low risk. A medium risk would be if the goals
were defined, but they were still vague and unachievable: people would have an idea of what they were
supposed to achieve, but no detailed way of how to go about it.
Methodologies
Using a methodology is a good way to provide structure to a project. If there isn’t a methodology, or any
standard way of carrying out the project, there is a high risk that the project will fail: if there are no
guidelines, how do you know that what you are doing is correct, or if you are missing out anything
important? If, however, a defined methodology is adopted, people will know whether they are doing things
in the right order, or in the right way, and this poses a low risk to the project. A medium risk would be if
there was a methodology available, but people didn’t know how to use it or follow it effectively.
155
Chapter 5
Change Control
Rating: Low
Comments: There are very clear guidelines as to how change should be introduced. The design
has already been locked down.
Funds
Rating: High
Comments: Funds are extremely limited and it is difficult to see how we will be able to achieve
any of the goals set out. In its current state, the project is very likely to go over
budget.
User Contribution
Rating: Low
Comments: Every user group is represented and the representatives have attended every
meeting. They seem to grasp the underlying concepts of the project and understand
and accept what it is we are aiming to do.
This document will give insight into possible risks that may exist within the corporation. Once this
document is completed for a particular project, it should be available to the entire team and become part of
Vision/Scope document. These risks should be assessed as early as possible, as you may discover that the
risks to a project are so great that you may not want to do the project. In addition to the standard risks, there
may be risks that are specific to the situation or to the type of the project that should also be added. A
review of the Enterprise Architecture document should also reveal risks to the project.
Looking at the master schedule you built with Project 98, you can also find many risks to the project. Are
resources (especially personnel) overscheduled? Do you have team members in roles that they are not
adequately trained for? Are the cost estimates you arrived at using Project 98 far more than the amount of
money allocated to the project? Can you accomplish the items in the critical path in the allotted amount of
time? What would happen to the project if one of the key resources left the project (a team member
becomes ill or leaves the company)? If there are goals that are dependent on many other goals first
becoming accomplished, are all goals in this critical path based on reasonable time estimates, or is likely
that some of these goals will take longer than expected and delay all of the dependent tasks? Are there goals
that will take a very long time (these tend to have inaccurate time estimates)?
156
Risk Management
In addition to this risk document, you should also be keeping a separate risk-tracking document with the
highest priority critical risks to the project. This second risk document will be discussed below. First, we
must determine how critical a risk is.
To begin with, you must determine whether the consequences can be tolerated should a particular risk be
realized. This will depend on the project. For example, is a possible one million dollar over run in costs in
the overall project acceptable? Most people would say no, and in a project that is projected to cost two
million dollars this is certainly not acceptable. But, what if you are doing a major Enterprise project that is
estimated to cost two hundred million dollars? A one million dollar overrun could be acceptable in this
situation.
We must determine what is and what is not acceptable for each project. These issues
should be discussed with the stakeholders and the sponsors at the beginning of the
project and documented.
Determining the likelihood that a risk will occur is usually something you can only do by experience and
research. At first it may not seem so bad not to include a component manager for a small team of four or
five developers. Yet, with experience, you will know that a project will require a constant adjustment in
resources. A developer working on critical path goals may get sick and another developer working on
another non-critical goal gets assigned to the sick developer’s goals. A critical component is taking too long
to complete and may throw off the entire schedule, so a developer working on a non-critical goal is
reassigned to help with the critical goal. A goal will require additional financial resources to complete so
features are removed from another goal. All of these changes must be coordinated, and without someone
overseeing the project, these adjustments will not be made. Small issues that could have been easily
handled will not be dealt with, and soon the project is running over time and over budget. Through
experience, you can know what effect a risk can have on a project. The overall effect of the risk is perhaps
one of the most important criteria for determining how critical a risk is.
Another source of information on the effect a risk can have on a project is prior project documents such as
status reports, risk documents, etc. This is another reason to document everything. By reviewing previous
projects you can see how risks impacted these projects and then make an assessment on how these risks will
affect your current project.
Once you have documented and quantified all of the risks, you need to create a plan for each significant
risk.
157
Chapter 5
Other risks are far more complicated. If you are building a project that will completely reengineer the
corporation, many users may feel resentment toward the project. The end users may not appreciate that the
new system will completely change the way they do their job. Many people are afraid of change. It is
critical that your end users support your project, so you may find yourself working with management to find
a way to help get acceptance for the project. You could build an Intranet site that contains information on
the new corporate structure, how old skills and jobs will map to new skills and jobs, etc. The development
team’s educator can work with the client’s education department to conduct training classes. While all of
this might seem to have very little to do with building your Visual Basic project, you will quickly see the
relevance when users will not work with you.
Each risk will require its own solution. This solution will depend on the corporation, the structure of the
corporation and the particular situation. Our initial risk assessment, combined with the Enterprise
Architecture document, will tell us what resources we need to make plans to reduce or eliminate the risks to
our projects. We will have to make a plan to get access to these resources.
It is better to be honest than to take on a project you know cannot succeed. Ideally, the solution is to create
a plan to correct the problems and to carry the plan out. Unfortunately, sometimes in the corporate world,
creating change simply cannot be done. If you see there is a problem with a project, it is likely that you
came to this realization after careful analysis. The rest of the people involved with the project will need to
go through the same steps you did to arrive at your conclusions. This may take time and careful
explanation. Try to work with the other members of the team and take them through the steps that you took
to arrive at the conclusion that the project will not succeed. That is the best way to make someone
understand your viewpoint. Sometimes, as you go through the process of explaining, you all get a new
insight and find new solutions.
158
Risk Management
The most difficult position is when you are a developer in a non-self-directed team and are ordered to write
Visual Basic code in a manner that is bound to fail. A familiar situation is where the project manager orders
a developer to begin writing code without any formal design phase. One of my favorite stories is about the
manager who would take the developers to lunch whenever there was a new project. The manager would
grab a stack of napkins and start drawing pictures of how the project was supposed to work. After the lunch,
the developers would return to their desks with a stack of napkins and start coding. I cannot say if this is a
true story, as I heard it second hand, but I would not doubt it. I have seen many projects begun with only
that amount of design. This does not only happen to developers. Team leaders will often get orders from
much higher to do a project that they know will fail. In the case of the team leader, the responsibility is
even worse than for the developer, as accepting this type of project not only means that the team leader
must do this, but the entire team as well. I have always viewed it as my responsibility as a leader to protect
those I am in charge of, and would try everything in my power to find a way to redefine the project, so it
can be completed, or end it.
It is difficult to decide what to do when your manager orders you to do something that is bound to fail. You
must evaluate the situation based on your situation. For the most part, it is best to be honest with your
manager, explain your concerns and ask if steps can be taken to reduce the risks. Go through the steps that
led you to realize this is not the best way of doing things. Your manager does not want the project to fail
any more than you do. If you can convince your manager that your way will improve the chances of success
of the project, your manager might agree with you. Remember also that your boss is most likely following
orders from higher up and the problems may lie with a larger bureaucracy.
Most importantly, when you present your ideas, do not be closed to your manager’s viewpoint. Sometimes
they have information that you do not. Occasionally, what seems like madness is actually the best solution;
it only seems that way to the worker because they do not see the big picture. Before going ahead, do your
research and get the best understanding of the situation that you can. Get your facts straight, and when you
present your case to your manager, start off by making sure that you both agree on the basic information
before getting into the problems and solutions.
It is very easy to be part of the problem. I will admit that there have been times when I have complained
about a manager who was leading a project off a cliff. I would make an attempt to steer the project the right
way. Sometimes I succeeded and sometimes I did not. In retrospect, I wonder whether I had spent time
working on solutions instead of complaining, if I would have succeeded. Now, I focus on finding solutions
and not on complaining, and I find that there is almost always a way to reach a mutual consensus that will
be acceptable to everyone and will insure the success of the project.
Once we have identified the risks and created a plan, we must monitor them. Let us look at how we can
monitor our risks during our projects.
159
Chapter 5
Risk Tracking
Simply defining the risks at the beginning of the project is not enough. You must actually do something
about the risks. The best way to do this is to create a tracking document, or use a risk-tracking program.
A risk-tracking document is a living document. Every member of the team should submit a risk document at
some interval, usually once a week, to his or her component manager. The component manager will review
these risks and make an assessment of the priority of the risks and the probability the risks will occur. High
priority, high probability risks must be taken care of immediately. Working with the entire team, the
component manager will find ways of reducing or eliminating the risks. If there is a risk caused by a
conflict with the client and the development team, the component manager will go to the product manager
for help on resolving this issue. If resources are needed, such as a copy of a database for testing and the
client is not willing to give this data, the logistician and the product manager will work towards a solution
with the component manager. If the problem concerns a bug in one of the primary components of the
project, the component manager will work with the developers, testers and even possibly other component
managers to find a solution. The component manager manages the resources to find ways of reducing any
possible risks to the project.
Description: This is a detailed description of what the risk is, which parts of the project could be affected
by the risk, and the consequences of the risk occurring.
Scenario: The sequence of steps that would need to happen for this risk to affect the project.
Probability: The probability that the scenario could actually occur, usually rated high, medium and low.
Resources Affected: What resources will be affected if the scenario occurs? Will there be financial loss?
Scheduling delays?
Plan: The plan to prevent the scenario from happening, or at least to reduce its likelihood of occurring or
decreasing the negative consequences to the project, if the scenario occurs.
Risk Metrics: What we will use to determine if the risk is occurring and to determine if the risk has been
reduced.
160
Risk Management
Current Responsibilities: What actions must be taken by team members to reduce the risk and which team
members are responsible for these actions.
Trigger: At some point if the risk is not reduced, or the scenario starts and cannot be stopped, we must
switch to an alternate plan. This section will explain what must occur for us to switch to the alternate plan.
Alternate Plan: A description of the alternate plan if the first plan is not successful.
Current Risk Assessment: This section should be added to periodically, at the minimum weekly, stating
what the assessment of the risk is on that day.
Description: The users have no interest in the outcome of the project. They see no practical benefits of the
system and do not understand the impact it can have on their daily life. This affects all project areas.
Scenario: Vision is defined - users do not agree. Consensus cannot be reached. Negotiations break down
and users retract their support from the project.
Results: Without end-user support, the project will no longer be allowed to continue. Work will stop
immediately.
Probability: High - the end users see no real benefit to the system and are reluctant to offer their support.
Resources Affected: All resources will be affected - if user support is withdrawn, there is no justification
for the project and resources will also be withdrawn. If negotiations continue, this could cause financial
loss and scheduling delays.
Comments: We are appointing a new user educator, whom we hope will be able to convince the users that
the project will bring many benefits to their working environment.
Related Risks: Sponsors and shareholders might lose interest if we cannot provide a system that is wanted
by the users.
Plan: There will be a detailed user education guide to show the users the benefits of the system. This will
hopefully allay their fears of change. If the scenario does occur, the plan is to halt work immediately, notify
everybody involved and release resources and funds to other projects.
Risk Metrics: We will know if the risk is occurring if the vision and scope cannot be determined or a
consensus is continuing to prove difficult to reach. We can see that the risk has been reduced when a
consensus is reached and design can begin.
161
Chapter 5
Current Responsibilities: Team members must work to ensure that the end users understand what is
happening and the benefits the change can bring to them. This will primarily be the task of the team
members occupying the user education role.
Trigger: If the users will not offer their support to the project and a consensus cannot be reached, no matter
how much negotiation occurs, we will switch to the alternate plan.
Alternate Plan: If user education cannot describe the benefits to the end users so that they fully understand
the benefits the system can bring to them, we must enroll the help of the stakeholders. If the stakeholders
see the benefits of the project, the responsibility for the acceptance of the end users must ultimately depend
on them. User education will work closely with the stakeholders to make sure they fully understand and
accept the benefits the system can bring.
May 31, 1999: This risk has dropped to a medium level risk. Our education program has been
successful. The users are beginning to see that this project will enhance their jobs and allow some
employees to move into other positions, rather than being laid off. We have accomplished this
by…(etc.)
Each risk that was labeled high or medium should have a page like this devoted to the risk. Periodically, at
the very least every week, the Current Risk Assessment section should be updated. Once these updates are
done, the document should be reviewed. Periodically, all the team members should review this document to
see what risks may impact their portion of the project, which risks have been missed, and which risks may
have been improperly assessed.
Summary
One of the most important parts of creating a successful Visual Basic project is the proper management of
risks. Assessing the risks at the beginning of the project, developing a plan for medium and high risks, and
finally carrying the plan out and monitoring the risk can mean that you can almost guarantee the success of
your projects.However, not all risks will be able to be identified at the beginning of the project: risk
assessment and risk tracking should carry through the whole of the project to determine whether new risks
have presented themselves, or make sure that low risks have not been ignored and allowed to escalate into
high risks, almost without notice.
You can use a wide range of resources to find possible risks to the project. You can create a general
resource document, as we did above. You can analyze your master schedule in Project 98 for possible
resource conflicts. You can create a copy of your master schedule and test ‘what if’ scenarios and see how
they will impact the entire project. You can review documentation from previous projects or speak to senior
members of the team. Using all of these techniques, you can assess possible risks to your project and
manage them appropriately.
162
Risk Management
163
Chapter 5
164
Design Phase: Conceptual Stage
In the conceptual design stage we begin to give some structure to our envisioned solution. We will define
how our users will interact with our application and we will step into the roles of the users of our
application and find out how they want to accomplish the goals of our application as they are defined in the
Vision/Scope Document. In this way, we end up building an application that meets the needs of the
customer and of the business, allows the users to accomplish their goals in the way they view as most
efficient and makes easy and complicated tasks simple to perform. When the conceptual design milestone
has been reached there will be a clearly defined description of the product, the functionality it will include
and the manner in which the users will interact with the system
Create scenarios for third level goals, built upon the needs of the user.
Discuss roles, workflows, business processes and incorporate this information into our scenarios.
Create use case documents and diagrams based around our scenarios.
Identify exactly who the "users" of our application might be.
Scenarios for each third level goal identified in the Vision/Scope Document.
A library of use case documents to take forward into the logical design stage.
Chapter 6
The conceptual stage will allow us to take the third level goals in the Vision/Scope Document and turn them
into scenarios.
Essentially, we are transforming the third level goals into a set of requests for services from the system.
We will build a Visual Basic application based on a very detailed set of goals that
are defined by scenarios built upon the needs of the user.
When we eventually build our Visual Basic application in the development phase, we will create methods
(functions and subs) that allow a user to make a request to our application to perform some service. Thus,
redefining our goals in terms of services will allow us to create methods in our Visual Basic application to
fulfill the goals.
166
Design Phase: Conceptual Stage
Based on these scenarios, we will build the UML use cases, the ultimate deliverable of the conceptual stage.
These use cases form the foundation of the design of our Visual Basic application. This type of application
is a user-centered application - it will be built to fulfill the goals of the users in the way they feel is best.
The users can feel as if the application belongs to them and is a result of their input. This will make the
users more productive. In many cases, systems developed in this way make the work more enjoyable and
create a better work atmosphere.
The conceptual stage does not necessarily have to begin at the exact end of the envisionment phase. The
conceptual stage is the link between defining the goals of the application and the actual designing of the
application. Being a bridge between the two, it usually spans from the envisionment phase into the design
phase. Since it is easier to define the beginning of the stage by a milestone, I have defined the beginning of
the conceptual stage to be the point where the third level goals start to be transformed into a set of service
requests and a set of inputs.
Other methodologies, such as the Microsoft Solution Framework, do not create such a well-defined
boundary between envisionment and conceptual design. Much of the information gathering and
determination of goals are included as part of the conceptual stage. I feel it is easier to define the
envisionment phase and conceptual stage as I have done in this book.
3. A form specific for the type of complaint will load in the browser.
4. The customer can (optionally) enter their name, address and phone.
5. The customer enters his email address (if logged into site, this is automatically put into the form).
167
Chapter 6
6. The customer selects checkboxes to choose ratings and make the complaint.
7. The customer optionally types information into the form.
8. The customer selects submit.
9. The complaint is routed to the person who handles this type of complaint
10. The complaint is dealt with, and a response is sent to the customer through email.
In these steps we are still not answering how. There is no mention of how the complaint page will be
created, how the specific form will be built, how the form gets to the appropriate person, etc. We are only
describing what we want the system to do at a finer level of detail. The conceptual stage simply transforms
the goals into a series of requests for services from the system or the input of information into the system.
This chapter will show how this is achieved using user interviews, surveys and other techniques. The
logical design stage will then form the bridge between what we want to do and how we are actually going to
do it. The physical design stage will complete the definition of how.
In the conceptual stage, we will view each goal from the perspective of the person who will fulfill the goal
(which will be listed in the Vision/Scope document). In our example above, the customer’s goal is to easily
submit a complaint. We have stepped into their role and found the steps they will want to take to
accomplish this goal. Don’t forget though, that we will want to create and improve processes for employees
as well as customers. A goal, in this regard, might be “improve the efficiency and ease-of-use of the order
processing procedure”. In the Vision/Scope document we may find that it is the goal of Sales
Representatives and Sales Managers to easily process orders. We can step into their role in the same way.
It would simply be impossible to define a different technique of fulfilling the same goal for every possible
user, especially if we have thousands or tens of thousands of users. Therefore, we look at all of the users of
the system, place them in groups, and then create a certain type of functionality for the group. The system
may have one set of functionality for the “customer” and another set of functionality for an “order entry”
group. In other words, we will group people together based on how they interact with the system. For
example, anyone entering orders into a database will interact with the system in the same way so we can
define an order entry clerk role. Sales Representatives and Sales Manager will use this role to enter
orders.
In the order processing application we will have many roles besides the order entry clerk role. There will
be an inside sales role for entering new products and updating the inventory along with a manager role that
will enter employee information and review reports, etc. Since this is an Internet application where the
customer can enter orders directly, or directly review product information, there will also be a customer
role.
168
Design Phase: Conceptual Stage
It is clear that roles define the set of tasks that a group of users need to perform. With this information we
can identify the components of the system that the role will need to access. Thus, we can use roles to help
us build the security in our system by limiting the services each role is allowed to request. For example, we
would not want to allow someone in the order entry clerk role to attempt to triple his or her own salary.
Only someone in, say, a manager role can request the “change an employee’s salary” service.
Every role will have certain goals associated with the job, and certain goals that the user in that role is not
allowed to perform. Goals the order entry clerk role cannot accomplish with the system may be deleting
customers, editing employee information and editing product information. Someone who can delete
customers cannot be in the order entry clerk role.
It is important to remember that the role a person is in has nothing to do with their job title. If a person who
is a manager is filling in for a sales representative while they are on a break, and the manager is using the
system to accomplish the goals of the order entry clerk role, then the manager is in the order entry clerk
role. The role a person is in is determined only by the goals they are requesting the system to accomplish.
So, we now have roles that will need to accomplish certain goals. The series of steps that are required to
accomplish a goal will form our scenario, which is a set of requests for services. How do we know what
services each role will request? Are there different routes that may be taken to achieve the same goal? Put
another way, these questions mean: How do we know exactly what functionality each group of users needs?
In order to find out we need to step into the shoes of a user who will use one of our identified roles. The
best way to do that is to talk to them.
Interviewing Users
Basically, once you have identified the roles for your system, you need to interview users who will be in
these roles. These interviews will determine what services a person in the role requests from the system, the
level of technical expertise a person in this role usually has, their work responsibilities, and their view of
the new system you are building.
The best way to learn what a user does is to spend time with the user as they are doing their daily work.
Have the user teach you their job. Usually, it will be the educator who will be conducting these interviews,
though other team members can help out if need be. The sorts of questions that may be asked are as
follows:
169
Chapter 6
Of course, you are not going to ask these specific questions. You will need to ask questions based on the
user’s level of expertise. It is unlikely that a user would understand what you mean by “What services do
you request from the system?” On the other hand, they should understand you asking them what tasks they
perform and what tasks they ask the computer to do. You will need to talk to the user in terminology they
understand.
Following is an example of the sort of interview that might take place with a Northwind Sales Representative,
who will use the role of order entry clerk:
Interviewer: Valerie, why don’t you start by telling me what you’re currently doing and how you do it?
Valerie: Basically I’m an Order Entry Clerk - so I enter the new orders. We’ve got a computer system,
which is supposed to make things easier. It’s like a database that I can get information from and add things
to. Everything I need should be in the database. A customer calls in with an order and I take their details.
Then I take their order – which is tells us how many of our products they want.
Interviewer: So could you tell me what customer details you need and why?
Valerie: Well first I need their company name and address so that I can tell whether they’re a new or an old
customer. We have a list of customers to check from. Each customer has an ID number but I’m not allowed
to change that. We have different customers with the same name so that’s why we need their address. Also,
if we have a new customer call in, I need to set up a new account for them. At this point I also check that
the details on our list are correct - maybe the customer’s moved.
Valerie: Well, then I just take the details of their order, what they want from our catalog and how much.
The products are stored in the database too. I confirm these details and the computer works out how much
it’s all going to cost and then I make sure the customer is happy with the price. Of course, I can’t give them
a deal or anything, but sometimes they haven’t realized how much their order is going to come to. So
anyway once the order is taken, I save it to the database and wait for the next one.
Interviewer: Right, so could you tell me how the customer receives his goods?
Valerie: Oh yes, sorry I have to do that too. From another list I select a suitable shipper depending on the
company’s address and add the cost of shipping to the cost of their goods and then check if the price is OK.
Interviewer: So adding new customers is one of your responsibilities. Could you tell me how you go about
setting up an account for a new customer?
170
Design Phase: Conceptual Stage
Valerie: Yes that is one of my responsibilities. I’m supposed to be adding new customers or changing a
customer’s details. To check if a customer is new I have to search through our list. If the customer is new I
take the customer’s company name and address and add it to our list on the database. The computer then
generates the customer ID number. Also a customer may call up and say that their address has changed and
so one of my responsibilities will be changing the customer’s address. I have to get the customer
information from the database and modify it. All this can take some time because we have loads of
customers. What I would really like is an easier way to check customers – like if I just typed in the
company name and it knew if the customer existed or not. Or even if it gave me a list of customers with that
name straight away rather than me having to find it myself.
Interviewer: Are there any possible errors that can occur while you are doing this?
Valerie: Yeah, each field can only be a certain length, but the program will allow you to type in as many
letters as you want. If you type too much, the program will just chop off the extra letters.
Valerie: Umm, here. I’ve written it down. The company name can be 40 letters; the contact name, 30
letters; the contact title, 30; the address, 60; city, 15; region, 15; postal code, 10; country, 15; and the phone
and fax, 24 digits. I have to remember these.
Interviewer: Do you have any other responsibilities besides taking orders? Can you edit orders or change
orders or do things like that?
Valerie: No, I can’t change an order. Once I’ve entered an order, if there’s an error in the order, the Sales
Manager has to take care of it and she is responsible for modifying the orders.
Valerie: No, I don’t have anything to do with them, the inside sales person handles that.
Valerie: Yeah, sometimes when we are shorthanded or really busy, the Sales Manager will step in and take
orders.
Interviewer: Can you think of anything else that you like or dislike about your current system?
Valerie: Well we have loads of products and different products clearly belong to different categories.
Sometimes it takes me ages to find the right product because they are all in one long list. I could find each
product much more easily if they were split up into the different categories. Another thing that can be
frustrating is that if someone else is changing a customer record, I won’t be able to modify it until they are
done. I understand why this is, but sometimes I can’t get a record for an hour or so and you just know that
they have gone to lunch leaving the connection open. Also the system can sometimes be very slow.
171
Chapter 6
Places orders
Creates new customers
Updates customer information
Arranges for orders to be shipped
We found out what she doesn’t do: deal with product information; change order information after it has
been placed. We found out what she disliked about the current system and what improvements she would
like to see. Thus, we can begin to see the sort of things we need to accomplish in order to achieve our
“improve the efficiency and ease-of-use of the order processing procedure” goal.
In addition, Valerie confirmed that the business manager would occasionally use the order entry clerk
role. We even obtained some information about business processes - she couldn’t change a customer record
while someone else was accessing it (we will discuss business processes again later in the chapter). When
we have conducted a series of interview such as these, we will have enough information to start capturing
our scenarios.
Creating Scenarios
The four tasks we identified for the order entry clerk role (place order, create customer, update customer,
arrange to ship order) can be considered sub-goals of our “improve the efficiency and ease-of-use of the
order processing procedure” goal. We must look to improve the efficiency of each sub-goal in order to
achieve our overall goal. We are now in a position to convert these sub-goals into scenarios:
Order Entry
Place an Order
Customer telephones order or places order via web site
If customer is ordering by telephone, request company name
Request customer information from system
If customer does not exist, Create Customer
Check customer address, if customer is in system
If incorrect, Update Customer Information
Select product customer wants
Enter the number of the product customer wants
Calculate total bill
Submit order
172
Design Phase: Conceptual Stage
Create Customer
Enter customer name
Enter customer address
Enter customer telephone number
Enter customer fax number
Enter customer credit card number and expiration date
Verify customer information is correct
Save customer information
Ship Order
Shipping gets order
Shipping fills order
Shipping ships order
We have now transformed our original goals into scenarios. By talking to the users, we can find out all the
possible scenarios that may occur when trying to accomplish their goals. We have put several scenarios
together by using if statements in our scenario. This if statement means that we could have one scenario
where the customer is new and we need to add a new customer, another scenario where we have an existing
customer who has moved and requires their information to be updated, and a third scenario where it is an
existing customer whose information is correct.
When interviewing users you will want to find out every possible scenario, and then try to put them
altogether into one scenario using if statements.
In this example we are gathering detailed information on existing processes. If we are going to completely
redefine the way a goal is accomplished then matters get more complicated. It is harder trying to invent a
scenario for something the user doesn’t yet do. You may have to propose something and get comments back
before the user will be able to envision the new scenario. Also note that when creating scenarios for the
customer role you may not be able to have access to real customers and will have to work with a “customer
representative” instead (someone from the organization who thinks they know how a customer role would
work).
Once again, an intranet can provide a resource for recommendations on how to optimize scenarios. Once a
set of scenarios is developed based on the Vision/Scope Document and user interviews, you can post them
on the company intranet so that everyone can review them. A form to offer suggestions, improvements and
additional scenarios should be provided.
173
Chapter 6
Workflows
Now we have defined our scenarios we need to consider workflows. Essentially, a workflow is a
component part of a business process. A “create new customer” workflow, for example, is part of our
“processing an order” business process. Different roles may perform each workflow. It could even be that
parts of a business process are not supported by the system – they could be manual activities, be performed
by other software tools or even be performed by different organizations.
Placing an order, adding a new customer and updating a customer, are all workflows that will be
accomplished by someone in the order entry role. Since these workflows are all performed by the same role,
we should group them together (perhaps call them the “order entry” goal). In the logical and physical
design stages we will see how these three requests will also be grouped in our Visual Basic application.
Someone in the shipping role will accomplish the final goal, ship order.
When we design our application, it will make it easier for a user if a set of scenarios that are usually done
together by the same user can all be done at one time. This may have implications for the design of the
Graphical User Interface. In this case, we would design our application so that enter orders, add customers
and edit customers are all on one form. When a person in the order entry clerk role is entering orders, they
can accomplish all the goals they normally do in their job by accessing one form. This is much easier than
if we had separate forms to accomplish each goal, thus making the user jump from form to form to do their
job (see Chapter 7).
174
Design Phase: Conceptual Stage
Use Cases
We now begin the process of converting our scenarios into a set of use case models that we can take on to
the logical design phase. A use case model has numerous sections. We will start by creating a use case Flow
of Events. Our scenarios represent every step and every possible flow of events that can occur as a user
attempts to achieve a particular goal. The use case Flow of Events encompasses this type of information but
there are other important differences:
Use cases define the behavior of the system from the standpoint of the user requesting the
service.
We use the generic term actor for the user requesting the service. An actor is someone or something that
makes a request to the system to perform a set of services. The actor will always be external to the system.
In order to transform our create customer scenario into a use case flow of events, we would make the
following alterations:
Create Customer
Primary Actor: Sales Representative
Actor enters customer name
Actor enters customer address
Actor enters customer telephone number
Actor enters customer fax number
Actor enter customer credit card number and expiration date
Actor saves customer information
We have defined a primary actor and we have defined each step from the point of view of the actor. You
may also have noticed that we no longer have a “Verify customer information is correct” step. This is not a
request to the system or input into the system, it is a manual step, identifying that the information is correct.
Requests to the system to perform a service or the inputting of information into the
system are the only statements placed into the use case.
This can be further demonstrated by another example. When we consider the system boundaries, we have to
modify our ship order scenario as follows:
175
Chapter 6
Ship Order
Primary Actor: Shipping Clerk
Actor requests new orders
If order is shipped, actor marks order as complete
Shipping the order is not something we actually request the system to do. This is done outside of the
system.
This information will not be lost, though. The services that the system performs internally
will be placed into business rules, which we discuss in the next section.
You may have noticed earlier how I referred to someone or something requesting services. It is quite
possible that the actor may not be a person. You may have external computer programs that make requests
for services to other programs. If you make a Visual Basic application that validates credit card information
that is a separate application, this credit card system may be called by an order entry system. The order
entry system would be an actor for the credit card system, as it is external to the credit card validating
system and requests it to perform services.
At the moment there is still a lot of information that is missing from our use case - they contain many terms
that should be defined. Exactly what is a customer? What defines a product, an order, a bill or a customer
address? How do we calculate the total bill? Are we allowed to have a customer with no billing address?
We will need to include this information in our list of service requests. Essentially, what are missing are
our business rules. Business rules define how the business is run. They can be rules governing the
definition of business terms, such as “customer” or “billing address”. They can be the formulae to calculate
a business value such as total bill, or rules that tell us what is allowed, what is not allowed, and what
happens when something that is not allowed actually happens.
Business Rules
There are five types of business rules that, generally speaking, place restrictions on the possible outcome of
our flow of events.
Example: “Customers are billed on the last day of the month.” This rule would be derived from several
other rules, such as: “customer’s bills include new charges and unpaid balances, calculation of customer’s
unpaid balance, calculation of unpaid charges, etc.”
176
Design Phase: Conceptual Stage
Example: The customer has a customer billing address where the customer prefers all billing
correspondence to be sent. It can be different from the shipping address.
In this example the “customer” is the business term and the “customer billing address” is the attribute.
Format: Every (Each) <business term> <relationship to> <another business term>
Example: “Every ordered item is a product” or “Every customer has a billing address.”
Example: “A customer’s state must be one of the 50 states” or “The state name must be two letters”.
Thus a Requirement business rule that will affect our “Place an Order” flow of events may be: If another
user is accessing customer record, system will inform requesting user (remember the information we
obtained from Valerie?).
Business rules have a big impact on object-oriented design and on our coding. They can determine what
properties an object will have, the correct values for the properties and methods of deriving the information
needed by a class.
177
Chapter 6
The Constraint, Fact and Derivation Business Rules are essential elements for converting UML diagrams
into a Visual Basic application. It’s important to make sure that all of the Fact, Constraint and Derivation
Business Rules are implemented in our code.
The easiest way to do this is to put a comment into the code with the name of the Business
Rule that the code is based on. We can later do a search on the code for every one of these
rules; if we do not find a reference to the Business Rule in our comments, then we know we
forgot to implement a rule.
Furthermore:
Definition and Fact Business Rules can be used to determine the properties of our objects, and which
objects contain other objects, i.e. object hierarchies.
Constraint rules will define what users can do, and will form the basis for the type of application errors
that may be raised in our code (IF billing_address is NULL THEN….).
The derivation business rule defines the formulae we will use in our code to derive calculated fields.
178
Design Phase: Conceptual Stage
Overview
The main purpose of this use case is to create a new Customer
Primary Actor
Sales Representative
Secondary Actor
None
Starting Point
The use case starts when the actor makes a request to create a new Customer
End Point
The actor's request to create a Customer is either completed or cancelled
Flow of Events
The actor is prompted to enter information that defines the Customer, such as Name,
Address, etc. The actor will then enter the information on the Customer.
The actor can choose to save the information or cancel the operation. If the actor decides
to save the information the new Customer is created in the system, and the list of
Customers is updated.
Measurable Result
A Customer is added to the system
Business Rules
Customer
Customer Fields
Restrict Customer Create
179
Chapter 6
There are some new terms here. The only non self-explanatory one is “Use Case Extensions”. Occasionally,
use cases exist that are a variation of another use case and extend the functionality of the original use case
(e.g. create customer and create VIP customer). These extensions are listed here. We also include a
Business Rules section. The “Restrict Customer Create” Constraint business rule, for example, has been
added to the design of the project to ensure that nobody will be able to create a customer who already exists
on the system:
Overview
This rule is for when a Customer is added to the system
Business Rule
Each Customer must have a unique CustomerID
Business rules are highly contextual to the actual business environment in which the program is being
written, but this is a good way to present them clearly and professionally.
We can see that, basically, our final use case documents are a verbal description of what happens when
someone using the program we want to design needs to create a new customer. Actors are identified (sales
representatives), start and end points are located (in this case, a sales representative asking to create a new
customer, and successfully having created a new customer) and a flow of events is drawn up to explain how
the system can get from the start point to the end point (information obtained from our scenarios). Further
to this, some alternative sequences are identified (perhaps the user decides they don’t want to add a
customer half way through the process), measurable results are defined, and some business rules are
created.
The use case model describes exactly how the goal of the user can be achieved. It
provides a comprehensive definition of how a user will interact with the system.
Once a use case is complete, the relevant users should review the document. Once again, the documents can
be posted on an intranet or Internet site where all the users can review it and make suggestions. Surveys can
also be put on the web site for users to fill out, though it is better to create these after spending some time
with some of the users. After everyone has been given time to review the documents, a final set of
documents should be physically signed off by members of each group.
180
Design Phase: Conceptual Stage
It may have seemed like a fairly long road to get here, but we have finally hammered and shaped the
original level one and two goals, based on the needs of the business from management, down into a set of
user-centered use cases that will form the basis of our Visual Basic project. Before we can move onto the
logical design stage, we must talk about how we get information from the user and who the user is.
The customer may be someone we never see and never speak to. If we were building a new Internet site, we
could send surveys out to current customers to see what they may want on our new Internet site. Yet, if all
of your customers use phone or mail order, it is quite possible that your current customers are not the
people who would use the new Internet site and therefore could not give you any useful information.
Even worse, the Internet application creates a whole new group of users who you have no way of contacting
prior to building your web site: the potential customer. There is a big difference between the customer, who
is someone who is loyal to a corporation and their products, and the potential customer who is trying to
decide whether the corporation deserves their business. The Internet application must satisfy the needs of
both the loyal and potential customer. Even the loyal customers may have different shopping patterns. Some
may like to come and browse through the web pages and take their time selecting goods, others will want to
go directly to the product they want, order and leave.
We can begin to see the benefit of creating roles that define the services requested from the system by the
user. By creating a potential customer role, a leisure customer role (for the customer who likes to
browse) and a fast customer role (for the customer who likes to enter, order and leave) we can define a
unique set of use cases for each of these types of customer. Using these use cases, we can then add
functionality into our web site for each user. We can even customize the web site so that people in different
roles see different web pages and have different options.
One of the most interesting things about building web applications is that we really cannot accurately define
the different scenarios a user of the site will use until the site is up and running and people are using it.
What we can do is research the best web sites currently in operation, research the potential users of the sites
(most likely customers), research successful business patterns, send interviews to potential users, etc. Based
on this we can create our first design. Once the site is running, we have users log in and then track what
they do. We will see patterns emerging on how users move through the site and place orders (if placing
orders is part of the site). Based on these patterns, we can refine the different types of roles that the web
application has and what scenarios are associated with these roles. From this we can build and refine our
use cases, which in turn will allow us to revise and upgrade the design of our site. This brings up a critical
point. When building a web site, you cannot design and build it in one development cycle.
181
Chapter 6
The very nature of web sites requires that they be built in iterative cycles. The first cycle creates the initial
site with the basic functionality of the site. Based on how the site is used the roles are refined or new ones
created and scenarios are revised or created. These new roles and scenarios will be the basis of the next
cycle of development. Once this cycle is complete, the site usage will lead to new refinements of roles and
scenarios leading to the next stage. As the market and the Internet itself evolve, so must a good Internet
site. The cyclic methodology allows the site to be continuously refined so that it is always the most efficient
for the users.
When building a web site, one fundamental question you have to ask is whether to allow users of the site
full access without logging in or to require them to log in. By having them fill out a login form and then
logging in each time, you can track how users within different categories use your site. Thus, a travel site
may be able to compare the difference between how business customers and regular tourists use the site or
what pages and what items people in different income brackets order. This information is extremely
valuable and can allow you to customize your site for each user type (role). The problem is that many
people do not want to give personal information, do not want to waste time logging in, and may simply
move on to another site that does not require logins. You can make logging in optional and offer benefits to
those who log in, without excluding those users who choose not to log in. You can even use this option to
make comparisons between those who log in and those who do not
Many sites use cookies to store account and session information that is maintained
at the client (system) level. When a customer returns to the site the cookie(s) can
relate information about how the customer used the site, which can in turn be used
to customize the site for the customer experience. However, some customers are
reluctant to store cookies on their computer.
As we said, some of your users may not be people. As everything starts to become automated, we are now
starting to pass information from computer system to computer system. This means that a user of your
Visual Basic application may be another computer system. Currently, this may mean that you have to
produce output in some standard format, such as EDI (Electronic Data Interchange). With the new emerging
XML standard, it is likely that XML will soon become a major part of communications between computer
systems.
XML is a language similar to HTML. One can make XML files to store data such as a
recordset (a set of table from a data source usually held in memory). XML files have tags
within the file that identify the structure of the data in the file. As the file is self-defining, it
is an excellent choice for sending files across different operating systems and environments.
These files also can be easily sent across the Internet and used as a data source for the
client.
Just as you need to determine how a human user of your system will use the system, you will need to do the
same for how systems use your computer. These other computer systems will be actors in your use cases,
and you can build scenarios based on how they will use your system. You will also need to carefully define
how information will be formatted and transferred using business rules.
182
Design Phase: Conceptual Stage
Your Visual Basic application may need to pass information in disconnected recordsets for a Visual Basic
EXE application, in the format of HTML to an ASP page for a web application, and also in the format of
XML to transfer information to another system. All of this functionality may be in one component.
Disconnected recordsets are copies of information from the database, but once the records
have been retrieved into the recordsets, the connection to the database is severed. Later,
once the information in the disconnected recorset is updated, it can be reconnected to the
database
For example, if we build an order entry application we could build a product component. For the order entry
clerks this product component would be in a Visual Basic EXE application using disconnected ADO
recordsets, in the E-Commerce site it would be in an ASP page being controlled by server side Visual Basic
script and need to return an HTML page, and finally it could be used in a Visual Basic application that
automatically reorders products, when the total items in stock falls below a certain number by sending a
message in XML format to the supplier. One product component will be producing information in three
formats.
Some of you may be thinking that it is not good design to make one component that performs so many
functions. We could just as easily build all of our components so that they only use disconnected ADO
recordsets. We can then build another component that takes a disconnected ADO recordset and converts it
into either HTML or XML format. In this way, we build all our components to work with disconnected
ADO recordsets, and have one component that provides the additional formats when they are needed. This
saves us putting the same conversion routines into every component but still allows us to reuse our
components in many environments. The best solution depends on the available resources and the
requirements of the system.
An application built from the envisionment phase will include the big picture. Between the Enterprise
Architecture Documents, the Vision/Scope Document and the use cases, we will have a broad view of how
our Visual Basic application will fit into the Enterprise. With this view, we can build reusable components
that fit into many projects and diverse situations.
Once the user is identified, we should create a profile of the user and what services they will be requesting
our system to perform. The educator and the project manager, assisted by the rest of the team if necessary,
should make these profiles. Once the profiles are complete, they should be added to the Enterprise
Architecture Document under a new section called User Profiles. The use cases should form their own
separate document.
183
Chapter 6
Iterative Cycles
In our schedule template (Chapter 13), we have placed a clear boundary between the different phases of the
project and clear boundaries between the stages of the design phase. In reality, though, parts of one cycle or
stage may end prior to the cycle or stage being complete, resulting in parts of the next cycle or phase
beginning. In this way, there is overlap between the different stages and phases. We have already said that
the conceptual stage will usually extend from the envisionment phase to the design phase. It is quite
possible that a set of use cases will be completed by the educator and handed over to the developers who
will start turning them into the UML sequence diagrams. Building sequence diagrams is part of the logical
stage, yet the educator may still have many other use cases they need to complete so the conceptual stage is
not actually done. Even when all the use cases are complete and the conceptual stage is complete we may
find, while creating a sequence diagram, that something from our use case is missing and have to go back
and correct it.
The design of the project is an iterative process. We start with our initial view of the design and then
present it to the users who suggest modifications. We make these modifications, show them to the users and
again make necessary corrections. We begin to make sequence diagrams, find a few other areas that need to
be polished in our use cases and finally, after many iterations, arrive at the correct use cases. While we are
doing our sequence diagrams, we will show them to the development team and the users and once again
polish them. When the sequence diagrams are complete, we will again go through many iterations until they
are complete. We will go through this iterative process with the UML diagrams in the physical stage, too.
While our schedule has clear boundaries for the phases, in reality there may be a blurring of the lines
between phases and stages.
Summary
In order to design a successful enterprise solution, you must not just look at an individual scenario, you
must see the big picture. How does everything fit together? Can one process be improved by improving
another process? Does improving communication between different parts of a workflow improve the overall
workflow? Be creative, use your imagination. Perhaps one of the best sources of ideas is the brainstorming
sessions in the second consensus meeting. Many great ideas will come out of this meeting. The reason I
suggested writing down all suggestions, even ones that did not get a high ranking, is that sometimes an idea
that seems stupid or just too risky at first, may turn out to be the best solution. The suggestions you gather
at the consensus meeting are the creative ideas of the entire team, and more importantly, the people most
familiar with the business processes. These are the people who are most likely to come up with the best
solutions.
184
Design Phase: Conceptual Stage
In the conceptual stage we take this a step further. We interview users to find out exactly what goals they
need to achieve, how they currently achieve them and exactly how we can improve the ease and efficiency
with which they can achieve them. The users are a great source for recommendations on how to improve
processes. By reviewing their reasons why a process is poor, we can often see how to improve it. Based on
this information we create scenarios and use case models for every third level goal identified in our
Vision/Scope Document.
Thus we have a set of use case models based on the goals identified by the client and management (and
refined by the whole team) along with detailed information about how exactly the user would interact with
the system. By proceeding in this manner, we are well on our way to creating an application that will satisfy
both business and user requirements. It is very important that the entire team stops focusing only on
building components. Instead, they need to start viewing their coding as the fulfillment of one or more
goals of the client. This shift in thinking is critical to producing Visual Basic applications that meet the
expectations of the client.
In the next chapter the use cases will be analyzed for a description of the services the system must provide
(identified by the verbs in our use case Flow of Events, such as create, update etc.) and in order to start to
identify system components (prime candidates are the nouns in our use cases, such as Customer, Order
etc.). However, we will see that before we can really identify which components we will need, we need to
consider the framework within which they will operate.
185
Chapter 6
186
Design Phase: Logical Stage
The logical stage is the point at which the developers really become the focus of the project. Up to here, the
focus has been on defining the goals of the client and extracting from those a set of UML use cases. At this
point, therefore, we know what the application is going to do, but not how that will be achieved. During this
stage, the developers will convert the use cases into a set of sequence diagrams, which define more
explicitly the components that the product will contain and the services and properties that these
components will require. In order to identify what components we need, it will be necessary to determine
the system architecture which will be the most suitable for the product. This stage will also require the user
interface to be prototyped and feedback on this prototype to be obtained from the end users.
Refresh and expand on what we've already learned about object-oriented programming
Examine some of the considerations we need to make in order to choose the framework for our
application
Consider how to convert UML use cases into sequence diagrams
Take a quick look at prototyping a user-friendly interface for the end user
The testing group will be involved in devising a strategy for testing the components. This will include
designing functions to test each component, and every method and property of the components. They will
also cooperate with the user educators and the end users in beta testing the GUI prototype. The end users
will be interviewed by the educators and invited to give feedback on the prototype.
During the envisionment phase and conceptual stage, the development team will be working closely with
the client to define the goals and services of the system. The logical stage begins when the users and the
development team have defined these goals and services and the scope of this current project.
In the logical stage, there is a shift of focus: up to now, the client has been our primary resource for
designing the project; from this stage onwards, the members of the software team will take over most of the
design work. They will work together to turn the user’s goals into objects and to define the interfaces (the
methods and properties) for these objects. These interfaces will define the services and attributes of the
system’s components. The developers will also create a description of the interaction between these
components.
Therefore, the logical stage centers on defining the components that will accomplish the business goals of
the user. This stage will determine what services these components will perform, what attributes
(properties) they will need to perform these services and how they will communicate with each other and
with the user. There will be no discussion on how the components will be coded, only what the interfaces
will be. Thus, the components designed in the logical phase could be built with any development tool. In
the physical stage we will actually begin to look at how our design can be optimized for the development
tool we are using, which in our case, is Visual Basic.
188
Design Phase: Logical Stage
If we go beyond defining the public properties and methods of our objects in the logical stage, we are
probably going too far. If we need to test new methods or techniques and you have to define the private
methods and properties in the logical stage, this is fine. Otherwise, in the logical stage it is better just to
define the component’s interface.
Before the logical stage, we have been viewing the project from the outside. We were not concerned with
how the system would fulfill our goals or even what components would exist inside the system. During the
logical stage, we take our first peek inside the system. We will not look too deep; we are only going to look
at what components are needed to enable our system to accomplish its goals. In the physical stage, we will
take a closer look and define how these components will look. Let us a look at an example to get a better
idea of what this means.
Imagine we were designing a car with the cyclic methodology. During the envisionment phase and the
conceptual stage, we would describe how we want the car to look, the features we want in the car, the way
the gauges will look, how the car will drive, etc. Essentially, we would describe every detail about how the
car will look and drive by the end of the conceptual stage. In the logical stage, we would lift the hood and
start describing the engine and all of the mechanical components.
Every component that we need to make the car perform and function the way we described it in the
envisionment phase and conceptual stage will be defined in the logical stage. We will not say how these
components will work; only what they must do (what services they must perform) and what characteristics
(properties) they will have. Thus, we can say that we will build an engine that will have a certain color,
have a certain range of revs per minute, etc. We will need an alternator that will produce a certain voltage,
turn at a given rpm, etc. Once we know what components are needed for our car, we can describe how each
component will communicate with each other and with the driver.
When we have finished describing the components and how they communicate, we will move on to the
physical stage, where we will actually start defining the design of the components. In the physical stage, we
would make blueprints of the engine specifying every characteristic of the engine. Finally, in the
development phase we would choose the metal, mold it and actually build the engine.
In summary, we will start with the most general goal for the project (the first level goal) in the
envisionment phase. We will expand this first level goal into a set of detailed goals that will be used to
build the use cases in the conceptual stage. The use cases will be written in the language of application
design (that is, we will talk about services and information input and output). In the logical stage, we will
expand the use cases into a more detailed design of our application, i.e. a description of the components, the
communication between the components, the communication between the components and the user, and the
framework for the application, using sequence diagrams. Once we have done this, we will expand our
sequence diagrams into a set of pseudo-code instructions in activity diagrams in the physical stage.
Pseudo-code involves summarizing the code you will write in a set of descriptive sentences.
For example, the following lines illustrate how we might write pseudo-code instructions for
opening a connection to a database:
Initialize ADO Connection
Each step will become one or more lines of actual Visual Basic code.
189
Chapter 7
The flow of a project from the defining of the general goals to the creating of activity diagrams can be
represented as follows:
All the way through the envisionment phase, the conceptual stage and the logical stage we are just looking
at the system from the outside. In the physical stage we will be looking at the inside of the system. We are
doing this because we are designing an object-oriented Visual Basic project. As we will discuss in this
chapter, when we are using an object, we are not concerned with how an object does something, only what
services it will need to perform and what properties it will have. We will therefore only be concerned with
identifying the objects of the system and the properties and services they will have all the way through the
logical stage. By the end of the logical stage, we will have a detailed description of the objects we will need
to build for our system. These objects can be built from any programming language as long as they can
perform the required services. To design an object-oriented Visual Basic application properly, we will need
to take a look at some essential properties of objects.
Object Attributes
We met two of the most important attributes shared by objects in Chapter 1: abstraction and
encapsulation. It is worth refreshing and expanding on our definitions of these concepts, since they are
vital for a proper understanding of object-oriented programming.
Abstraction
Abstraction is the process of representing a related group of items by a general term that classifies them
into one group. For example, the word car is a general classification for something with four wheels, an
engine and used to get you from one location to another location. When I say the word car, you immediately
know what I am talking about. You do not need a description of what a car is; you immediately know what
one is. Abstraction is essentially classification: grouping together things with similar properties
(characteristics) and behaviors (things they are capable of doing, such as performing a service) and giving
that group a name.
190
Design Phase: Logical Stage
We will want to perform abstraction with the descriptions in the use case. When we look into the use cases,
we will find groups that all share the same characteristics and perform the same services. Thus, we could
have many customers that share similar characteristics such as having a credit card number, billing address
or orders on record. Customers will also have certain behaviors, such as placing orders or changing their
address. Thus, I can group all the people with these behaviors (placing orders, changing orders…) and
characteristics (a billing address, orders on record, a credit card number…) into one group called customers.
Creating abstractions will be the first step in creating objects and this is the first thing we will do in the
logical stage.
Abstractions not only help us build our objects, but they also help us view our systems in a simpler manner.
By creating these classifications, we will reduce our complicated system into a group of objects. We will
find it much easier to talk about abstractions, especially to the client.
Encapsulation
As we have said, we were only interested in what the system is supposed to do (what services it provides)
throughout the logical stage. How the system performs these services is something we are not concerned
with until we get to the physical design stage. This is encapsulation. Essentially, encapsulation is the
process of building components that perform a set of services and have a set of properties. These
components will hide how they perform these services.
Encapsulation is one of the fundamental concepts of building objects when working in Windows. Windows
9x and NT all use the Component Object Model (COM). We could write entire books on COM, and indeed,
many have been written. Essentially, COM allows components running under Windows to communicate to
other components. COM acts as a translator between components. One component will make a request to a
second component to perform some service or one component will make a request to set a property on a
second component. COM will transfer this request from the first component to the second component, the
second component will perform this service or set the appropriate property and COM will carry any
messages back to the first component, if necessary.
For more information about COM from a Visual Basic perspective, see VB COM: A Visual
Basic Programmer's Introduction to COM, ISBN 1-861002-13-0, from Wrox Press.
The great thing about COM components is that they can be built from any development tool that works with
COM. As long as the component exposes its methods (the services it can perform) and properties in a way
that COM has access to them, it makes absolutely no difference how they are built. In other words, it does
not matter how the object performs its services, only what services it has to offer. Which, of course, is what
encapsulation is all about.
Visual Basic components are COM components. Encapsulation and COM allow us to build our Visual Basic
components so that they can be used by any other COM component. Our Visual Basic components can also
use any other COM component regardless of the development tool which was used to build the component.
However, for this all to work, we need to design our Visual Basic components properly. To do this, we need
to start with a focus on what the components will do, and not how they will do it. This is exactly what we
have done.
191
Chapter 7
Encapsulation offers us other advantages, too. Since we are only concerned with the methods and properties
that the object makes available (that is, public properties and methods) we can change the internal workings
of our component, keep the external methods and properties the same and not have to change the code in
the components which use this component.
For example, imagine we have a Customers component and an Orders component. The Orders
component has two public methods, CreateOrder and DeleteOrder and one property, OrderID. The
Customers component uses both these methods and also the property. Let us imagine that the Orders
component starts off as a COBOL program accessible through COM. Perhaps this is a very old legacy
program running on the mainframe that functions as a Windows COM component through the magic of
SNA Server (a Microsoft server that allows communication between the Windows world and the mainframe
world). Our first cycle is to get the Customers component up and running and to see how it works. Once
we have completed this, we now decide it’s time to upgrade our old COBOL component, Orders. We
rewrite this using Visual C++. Our new C++ component still has CreateOrder, DeleteOrder and
OrderID, which all work exactly as they did in the COBOL program. As for the Customers component,
we may have to make a few changes in how it references Orders, but any code that calls the methods or
properties of Orders can remain unchanged. This is one of the wonderful features of encapsulated objects.
Because we don’t care how an object performs its services, it makes no difference if it changes how it
functions internally as long as the public methods and properties do not change.
This is one of the fundamental concepts of object-oriented programming. The public properties and
methods, which we will call the object’s interface, that you include in the design of your project, must not
be altered. You can change the internal, private methods and properties as much as you like, but you had
better not change the public ones. If you are building objects with Visual Basic, consider your final object
design as an irrevocable contract between you and the developers that will use your object. You will create
total havoc to schedules if you initially design your object with a certain set of public properties and
methods, give this design to other developers who design other components based on this design, and then
later change your design. All the components using your component will have to be redesigned. If the other
components are built, they will have to be rebuilt. Doing this will not only make you rather unpopular, but
also destroy the integrity of the entire project. This is why it is so important that you take the time to
properly design your object right from the start.
If you should need to add functionality to your object after you have designed it, this will not affect any of
the objects dependent on your object if you only change internal properties or methods. If you start adding
new public properties or methods though, you risk walking into a potential landmine.
Imagine that I have created Version 1 of a Customers component with method CreateCustomer. I
release to dozens of developers who use this component in dozens of Visual Basic applications. Later, one
of the developers tells me that they really need another function, DeleteCustomer added onto my
component. So, I create and release a new version, Customers 2.0, with the CreateCustomer and
DeleteCustomer methods. Now, some developers have applications using Version 1 and some using
Version 2. What happens if someone installs an application that uses Version 2, which overwrites Version
1? If there are still applications on the machine that use Version 1, there is no problem as the
CreateCustomer method is still supported by Version 2. But what happens if we install a Version 2
application, which puts Customers 2.0 on the machine and then someone installs an application on the
same computer which installs Customers 1.0? Now there is a problem, as the Version 2 component will
be looking for the DeleteCustomer method and it will not be there. Version 2 will probably no longer
work.
192
Design Phase: Logical Stage
In an ideal world, this would not be a problem: it is for this very reason that we assign
version numbers to components. Setup applications should not install older versions of a
component over more recent ones. In reality, however, it is a problem, and it is impossible
to guarantee that a newer version won't be overwritten if your component is to be released
to other developers and installed by many setup applications.
Thus, you can add public methods and properties to your components without changing the GUID (an
identifier that uniquely identifies your component), but you should only do this when you are certain that an
earlier version of the component will never overwrite a later version. If you have a Visual Basic server
component that only runs on one server, and there is a strict control of what components are placed on that
server, it is safe to add public methods and properties, as it is not likely that the older version will be
installed. If you are distributing your components over the Internet or over an intranet and you increment
your version numbers, you should also try to make sure that the newer version is always installed over the
older version. Thus, when you have strict control over the component, it is safe to add public methods or
properties. It is a very bad idea to add public methods or properties when you do not have strict control
over a component, such as when a component is used by many developers and placed in many setup
programs. When you do not have control, it is better to recompile the component with a new name and a
new GUID.
We can see that we can adapt our objects to new requirements by adding new private methods or properties
or by changing them. Any changes to the internal workings of an object will have no affect on your
component. This is all possible because of COM and because encapsulated objects perform services without
us caring about how they actually perform these services. As for adding public properties and methods, this
can be done when there is strict control over the component. If we do not have strict control, then the
component should be renamed and recompiled as a new component.
Encapsulation and abstraction work together. Objects will represent a certain group of things that all share
similar properties and methods. Thus, the customers Smith, Jones and Williams will all be objects in an
order entry system. They are all customers and a customer is an abstraction. By creating encapsulated
objects that contain an interface with public properties and methods, we have found the perfect way to
create our abstractions in Visual Basic.
It gives users of the object an interface to work with that defines the public property and methods.
It provides a way of hiding the complexity by creating abstractions.
It creates an independent, self-contained unit whose internal workings are not important.
193
Chapter 7
For example, if we consider the computer object we discussed in Chapter 1, we can see that each computer
is made up of processors, memory boards, sound cards, etc., that are tightly bound together. There are many
different types of internal chips that together create a very tightly bound system. This is a tight form of
cohesion. A number of computers can be linked together in an intranet, which forms a much looser
coupling. This arrangement - a very tight cohesion associated with a loose coupling - is very common.
Cohesion and coupling do not only refer to our Visual Basic objects. Coupling and cohesion also refer to
our methods, the entire application, and essentially any part of the system we are building. Our goal will be
to use tight cohesion and loose coupling. Let us look at cohesion and coupling to see why this is the best
solution.
Cohesion
There are four types of cohesion that are beneficial to Visual Basic components:
Functional Cohesion. Functional cohesion creates the tightest binding within a component. A
component that has functional cohesion only does one thing. If a component performed more than one
function, than the component would be doing two separate things, which means the component is not
tightly bound. All of your Visual Basic methods, both private and public, should have functional
cohesion; that is, they should only do one thing. This makes it very clear what the function does and
makes it easy to debug.
Sequential Cohesion. A component that has sequential cohesion will have internal components that
must work in a specific order. The internal components will also share internal data. Several internal
methods that pass data from method to method through parameters, and work in a specific order, would
be considered sequential cohesion. This is common when you create functions or subs in your Visual
Basic code that perform some operations on the data. Sequential cohesion makes it easy to follow the
flow of the code. Debugging is easier as you can check the parameters which are passed into a method
'by reference'; this means that a variable itself (rather than its value) is passed into the method, so the
value of the variable can be changed within the procedure.
Temporal Cohesion. Temporal cohesion means that internal operations are combined so that they can
be done at the same time. For example, when you update an order, you will update the Orders, Order
Details and Products tables in the database at the same time.
Components with these types of cohesion are tightly bound, perform a clear set of services and are easy to
debug and understand.
194
Design Phase: Logical Stage
All of these types of cohesion result in Visual Basic code that is easy to read and debug. Because
components with these types of cohesion are tightly bound, they can easily be tested in isolation from the
rest of the project. This means that if an error is found during the testing of an individual component, the
error can only be in that component. If each function has a single clear purpose, it should be fairly easy to
see what is wrong and find the function in which the error occurred.
On the other hand, there are three other types of cohesion that result in Visual Basic code that is poorly
written. These are:
Procedural Cohesion. This is what happens when a series of operations are grouped together because
they occur in a specific order. This differs from sequential order in that the operations do not share data.
When two routines manipulate different data, they must be performing two completely different
functions, so they are very loosely cohesive. There will be no clear logic in the order of the operations
and consequently it will be difficult to follow the code. As functions are grouped together without having
logical cohesion, it becomes difficult, if not impossible, to test individual functions and components.
Often, entire sections of code must be tested at once. If a bug is found, you must search through
mountains of code to find it, which could take a very long time.
Coincidental Cohesion: This is simply a worse case of procedural cohesion. In procedural cohesion,
there is at least some logic in the order of the procedures, but there is no sharing of data. In coincidental
cohesion, there is simply no reason for the order of the code. Code jumps from one module to the next
with no obvious pattern or reason. The common term for this is 'spaghetti code'. It is unreadable, un-
maintainable and impossible to debug. Visual Basic has evolved to a level where the developers should
be professionals. Professional developers should never be writing this type of code. It does not matter
how many great features of Visual Basic a developer may know or how deep their knowledge of the
language is if they write code that is a tangled, unmanageable mess.
Logical Cohesion: The routines have a logical parameterpassed in that determines what the routine will
do. Inside the routine will be a huge Select Case (or, even worse, an If ... ElseIf statement)
that will determine what the routine will do. These routines can stretch to hundreds of lines of codes and
become completely unmanageable.
The most common reason for procedural and coincidental cohesion is a total lack of a design phase. During
the design phase, and specifically the physical stage, you can see the big picture and organize your
components so that there is a logical flow of the internal components. Being given a set of properties and
methods that your component is supposed to have, and then just start hacking out code, will result in code
that does not have a clear organization. Sometimes a very carefully designed project can end up with
spaghetti code because of feature creep. As new features are added in the middle of coding, modules have
to be hacked and changed. New modules suddenly need to be stuck in to add this new functionality and all
order is soon lost. This is why it is so essential to create a good design and get all team members, especially
the stakeholders and sponsors, to sign off on the final design. A clear agreement has to be made that once
the design is final, new features will be added in the next cycle. Because there is a documented design, even
new team members will be able to work within the existing design and to add features in ways that continue
“clean” design in the next cycle.
195
Chapter 7
Coupling
Ideally, we want to be able to test components by themselves first. To do this, each component must be
loosely bound to other components. Loose coupling also means that we can remove one component, replace
it with another that performs the same services and has the same public properties, and the rest of the
project will be unaffected. The connections between components are defined by their interfaces, which
gives us maximum flexibility in building components.
Components should have interfaces that are simple to understand. It should be clear what each method and
property is. The interface should not be too complicated, and should be kept as small as possible. If the
interface begins to get too large, it may be better to break the component into a hierarchy or into smaller
components. Nothing should be hidden: everything should be very straightforward. The one exception to
this is passing parameters into the initialization event of a class (this occurs when an instance of the object
is created). As this cannot be done in Visual Basic, we must initialize our class without passing in any
parameters and either have an additional method or use properties to initialize variables that need to be set
at the creation of the object. Interfaces should also be as generic as possible to allow the component the
maximum amount of flexibility.
The composition of a system is the arrangement of the components within the system. A set of components
may come together to define a single entity. For example, a set of components may work together to fulfill
a particular goal: we can combine Customers, Orders and Products components to allow the user to
enter an order, etc.
Associated with composition is the concept of emergence. Emergence is the creation of something which is
different to the sum of its parts. For example, we can take pasta, tomato sauce, spices, meat, mozzarella and
ricotta cheese and put them all together to make baked lasagna. Separately, these ingredients do not make
lasagna; it is only when they are all combined that we get lasagna.
Composition and emergence are perhaps two of the most difficult aspects of building a Visual Basic object-
oriented application. They require you to look very carefully at all of the components in the system to see
how they communicate to each other and what services they will perform. Once we do this, we can build a
system from these components, other systems from these components, and different objects from these
components. To put all of these pieces together, we will have to place all of the information into some type
of model.
196
Design Phase: Logical Stage
Building a system like this is simply too complex to visualize mentally. We can see how components fit
together within the entire system more clearly if we create models of the system that allow us to visualize
the components. The best tool for doing this is UML. In the conceptual stage, we used UML use cases to
create a formal description of each of the users’ goals. In the logical stage, we turn these use cases into
UML sequence diagrams. Sequence diagrams will show how our objects must communicate to each other,
what services they must provide and where in the system they will be located. Just how do we convert UML
use cases into sequence diagrams? Once again, there is no black magic. We begin with a careful review of
our use cases to define the objects that will be needed by our system. Once we have done this, we will map
the communication between our objects using sequence diagrams.
The objects that we will define in the logical stage, which will become Visual Basic components in the
development phase, should fulfill one or more goals of the user, be loosely coupled and tightly cohesive,
encapsulate its functionality, and provide a component that can be easily used by other components.
Looking at our use cases, we will usually find that the services our objects will need to perform are verbs.
We can either identify the verbs and then ask, “What object will perform this service?” or identify the
nouns and ask, “What services (verbs) are associated with this noun?”
To do this, let’s take a look at the goal of placing an order. In our initial interview with the user we got
what is called a scenario, which is a broad, general description of how something is done. We then removed
from this anything which should be placed in a business rule or which was outside the system. By following
these steps we created a use case, which describes how the user will interact with the system; that is, it
describes exactly how the application will function from the user’s perspective.
We will just look at the sequence of events part of the use case, as we have gone into detail about the other
sections in the previous chapter. We will underline the nouns that are good candidates for becoming objects
in our application and place the verbs that may become services in italics. We will bold anything that can
become a separate use case, such as creating a customer:
Order Entry
Place Order
Primary Actor: Sales Representative
Actor begins new Order
Actor requests Customer information from the system
Actor will Create Customer if the customer does not exist
197
Chapter 7
Looking at this use case, we can identify three objects that will be required by our order entry application:
Order, Customer and Product. Clearly, we don’t want to underline every noun in the use case: objects
must provide services (so they must have methods) and have certain attributes (properties). There’s no point
in making an object out of ‘quantity’, for example. This doesn’t have any attributes, nor does it provide any
services. Rather, it is descriptive of the product, so it will become a property of the Product object.
We can further see that we have italicized seven verbs, which will give rise to the methods exposed by
these components. Three of our verbs - place, create and update - are amongst the goals of the primary
actor, the sales representative; these all require a separate use case. ‘Place order’ is the current use case, and
we have to define use cases for ‘create customer’ and ‘update customer’. From this we can see that we will
need an Order component that has an Add New method to allow us to add new orders. Before we can
actually use the Add New method, though, we will have to perform all the steps listed in the use case. As
for the Customer component, it will need an Add New method to create a customer and an Edit method
to update a customer. These methods will also require the steps listed in those use cases to be completed.
This leads us to an important observation: the steps listed in the use cases are either a request for
information needed to set a property for one of the objects of the use case, the actual setting of the property,
or a request for a service from the system. In our example, the Order object is the main object of the use
case. Note that an object’s property can hold another object, so, for example, our Order object will have a
Customer property that will identify who placed the order - this will be one of our Customer objects.
The following steps will identify the value of that Customer property:
An order will also require a list of the products ordered and the following step will determine the value of
the Products property:
In a real system, we would probably have an Order Details object, too, that would hold
the list of products. I have left it out to keep the example simple.
198
Design Phase: Logical Stage
Once we have set all the properties, we can actually submit the order. Notice that only the steps required to
get information to set a property of the objects in the use case, actually to set the property or a direct
request for a service from the system belong in the use case. If other objects are descended from the main
object, as the Customer and Product objects are derived from the Order object, we can include steps
to set properties for these objects. However, if setting these properties can be grouped together to form
another goal of the user, such as adding a new customer or editing the information on an existing customer,
these steps should be moved into a separate use case.
When we reach the point where we are actually trying to identify the objects and the properties and methods
of these objects, we might find that we must refine our use cases. A large use case may contain steps that
fulfill a goal, such as adding or editing a customer, that need to be separated out into another use case. In
our above example, we would probably alter the use case so that it also had an Order Details object to
hold the product information. Design is an iterative process and often requires many revisions before we
reach the best design for our system.
Now that we have identified our objects, we are almost ready to start to define their interfaces - their
methods and properties. However, first we must give some consideration to the framework for our
application, and think about how to decide where our various components will be located. What we decide
will have a significant effect on how we must define our components.
Choosing a Framework
While our choice of programming language may not be a central part of the logical stage, how we are going
to distribute the application will have a large impact on our logical stage design. Whether we choose to
build an application on a two-tier or three-tier framework will have a major impact on the logical design
stage because it directly affects how we will design the component’s interfaces.
We have three primary alternatives how to build our systems. These options are the monolithic (single-
tiered) model, the two-tier and the three-tier models. Each of these types of applications has its place, but
using an inappropriate model could have a serious performance cost to the application. It is vital that
everyone in the team understands the implications of choosing a specific architecture, so we will spend
some time considering this question.
Single-Tier Applications
One-tier systems run completely from one machine. They tend to be monolithic systems that do not have
separate components. If they are monolithic and not built from components, they can only be tested as a
single component. Because of the incredible difficulty in testing and maintaining non-modular monolithic
system, single-tier systems sometimes have a bad reputation. There are still situations, though, where it
makes sense to build this type of application.
An application that runs on a computer and does not need to access data on another machine should use the
one-tier model. Examples of such applications are screensaver programs or an appointment scheduler. If
you were writing an application that controlled an assembly line that puts caps on bottles and then checks
the caps, there would not be enough time to communicate to another computer between each cap. A
program that needs response time in milliseconds will probably be one-tier.
199
Chapter 7
Creating one-tier systems is still a large part of what Visual Basic programmers are doing. If you are
building these systems, they should be built from components. An excellent example of this is the Microsoft
Office suite of products. For the most part, Word, Excel and PowerPoint are one-tier applications.
Two-Tier Applications
However, what if we have a number of order entry clerks, who all need to access the same database from
their computers? We will need more than one tier: an order entry application on each clerk’s computer
(called the ‘client’) which will retrieve and update data from a database on a server which serves the whole
company. Systems with two or more tiers are usually called client-server applications. Two-tier systems
usually consist of a database server and a client application which retrieves and updates data on the server.
This allows a number of people using different client computers to access the same database concurrently.
The usual solution to all of these problems is locks. While locks can solve the problem, we will see that
they too have some serious problems. If you create a lock that does not now allow a client to look at or
change a record when another client is changing a record, all of the problems with client-server go away.
Unfortunately, though, locks introduce their own set of problems. Locks can lock more than one record;
sometimes they can lock many records. If someone else needs one of these locked records to do their job,
they will not be able to do their job until the lock is released. Thus, you will have periods of time where the
users are waiting for a record to become unlocked. Sometimes this is not a problem; sometimes this can
become a major problem and slow down work performance.
This type of locking, which prevents a record being edited by more than one user at a time, is called
pessimistic locking. There is another type of locking, called optimistic locking, which avoids this problem
by locking the record(s) only when the user attempts to update the database. However, as you will
appreciate, this has the drawback that two users can still edit the same record concurrently and won’t be
informed of any conflict until they attempt to update the database. Without going into too much detail, I
think you can begin to see that things can get very complicated with client-server and locking records.
200
Design Phase: Logical Stage
Scalability
Another significant problem with two-tier applications is their lack of scalability: we can suffer enormous
loss of performance as more and more users are added. Imagine we write an order entry application as a
two-tier application. The client application will enter the order and the database will have stored procedures
to perform the updating and retrieving of records. The initial two-tier application has about ten users. The
company later starts selling over the web, and suddenly the database has to run stored procedures for
thousands of clients. Scaling a database is not very easy and we can reach a point where we run out of
connections. Thus, a two-tier architecture is not very good for web applications or for large-scale enterprise
applications that will need to be scaled.
The solution to this problem is to add an extra tier - we can take any business processing that does not
directly produce what the users see on their screens and place it into a middle tier that sits between the
client application and the database. The middle tier is then responsible for managing the network traffic and
the load on the database. Furthermore, we can decide to have a separate, dedicated machine for our middle
tier, which serves our several hundred users. Any updates that need to be made to our business processing
can be done quickly and easily - on the middle-tier machine only and not on the many client machines.
However, two-tier is ideal for building small department-size applications. An application that needs to
have a central data store used by a few dozen people is perfect for a two-tier application. Most
recommendations specify fewer than 100 users, but personally I would consider even 100 users high for a
two-tier Visual Basic application. If you are building an application to move graphics into a database that
will be used by one user, this is a good candidate for a simple two-tier Visual Basic application.
Three-Tier Applications
In a three-tier model, we separate out the data services, the business services and the client services into
separate components. The data services are services that deal with direct communication with the database.
Data services would include getting all of the customers and returning them to a system object such as a
customer object, or getting an updated record from a system object and saving the new information to the
database. The business services are services that deal with the maintenance of the system’s objects.
Business services related to a customer object would be retrieving a specific customer, moving to the next
customer, adding a customer, etc. The business services are usually in components that encapsulate a
business object, such as a customer object or an order object. The client services are services that deal with
getting information to the user and usually make up the user interface.
In the three-tier framework, we will usually have components for each set of services. The interfaces for
these components will be affected by what services these components perform. As we will see below, this
three-tier framework will need special server objects for the data services that have no memory of what they
did the last time they were called. (This persistence of values between sessions is termed state; components
that lack this memory are said to be stateless.) These server objects will need very special interfaces to
work this way. We will describe these in the next chapter.
201
Chapter 7
There are many advantages to placing the application onto the third tier. The primary advantage is
scalability. If we build our application from components, we can easily divide these components across
multiple servers. If we build Component1, which is used by several of our applications to get data from
the database, we can place this on its own server. If the server cannot handle the number of requests to use
Component1, we can upgrade it, and when the server reaches its maximum capacity, we can add another
server and place Component1 on two servers. In this way, we can easily increase the capacity of our
system by adding hardware and not by rewriting applications. Applications take one or two years to build
and can be very costly. Hardware can be bought for a reasonable price and shipped overnight.
The data services element of the logical three-tier model is not the database; it is where the components that
communicate directly with the data source reside. This could consist of a middle-tier component on a server
that retrieves and updates data for the client, or it could be a set of stored procedures in the database. In our
application, the data services component will be the server component. The data services can also be a
combination of both middle-tier components and stored procedures.
202
Design Phase: Logical Stage
Business services are components that service the client application and usually encapsulate business logic,
which validates the data being passed to or from the server. In our application, the business services will be
the client components such as the Order, Customer, Products and Order Details components.
These components can reside on the client computer or on the middle tier. For example, the Products
component could provide product information to an order entry application on the client. The same business
services component could also reside on a web server and retrieve data for a products page to be viewed by
potential customers surfing the web. Thus, in the logical three-tier model there is no restriction on where
the components will reside, only a placement of the services into three categories according to the functions
that the components perform.
The end result of using MTS is that we can focus on developing middle-tier business objects to solve our
business problems, rather than spending 40% of our development time implementing the framework
required just to host our objects. Indeed, writing a truly scalable system in Visual Basic is probably not
possible without MTS. Even in C++, creating our own scalable infrastructure would be fairly silly, given
that somebody else has already done the hard work and is giving it away for free!
MTS is built entirely around COM, and you should think of it as an extension of existing functionality that
COM provides. Probably one of the most important features of Windows 2000 is the unification of the
COM and MTS programming models (as COM+), bringing context and activity-based concurrency
management directly into the COM runtime. The unification means that investment today in MTS won’t be
wasted with the advent of the next generation of Windows operation systems.
Since the decision whether or not to use MTS will have a major impact on the way we design and code our
components, it is worth looking at this topic in some detail.
Transaction Processing
The most powerful feature of MTS is transaction processing (hence its name). If you’ve ever used a
relational database, when you read the word transaction your mind probably interprets it to think of
database transactions. Whilst this interpretation is correct in many ways, it’s important to realize that MTS
is designed to deal with transactions for many types of data sources, and not just databases.
What Is a Transaction?
A transaction is best described as one or more actions that are either all performed as a whole or none of
them are performed at all. To see why we might want to do this, consider the following scenario.
203
Chapter 7
A customer enters our Northwind e-commerce site and places an order. He enters his name, address, credit
card number etc., and the appropriate sum of money is duly removed from his bank account. So far so good,
but suppose the system unexpectedly crashes at this point, and all record of the deal is lost. The customer
has already paid, and the money been deducted from his account, but we haven’t yet updated our database
of products to be shipped, so he won’t get his goods.
Using MTS, we could place both operations within a transaction. This will ensure that both succeed, or both
fail. So, if the system crashes before our database is updated, the transaction will fail and no money will be
removed from his account. Similarly, there’s no danger that a computer crash will cause the goods to be
sent without the customer having to pay.
As in this example, transactions are a vital part of any system which involves the exchange of goods or
money, so we really should consider using transactions in any e-commerce site we wish to create.
ACID Properties
A transaction must have four properties, which are known from their initials as the ACID properties. These
four requirements are:
Atomicity
Atomicity dictates that a transaction must execute completely, or not at all. If the process breaks down in
the middle, based on atomicity, everything that occurred before the breakdown should be rolled back. So in
the example above, our customer wouldn’t lose his money.
Consistency
Consistency dictates that the persistent state reflects that which the business rules had intended. In other
words, the transaction must not break any rules laid down in the environment by the business rules. That
means in our above example, that once the transaction occurred, there should be goods sent to the customer,
and money removed from his account. We wouldn’t expect goods to be sent to anyone else.
Isolation
Isolation refers to how concurrent transactions are not aware of what each other is doing. The end point of
the transaction would be the same no matter what the outcome of the individual transactions. In the above
example, imagine if another customer was also purchasing something from our site at the same time. The
two transactions would be unaware of each other, but would still successfully result in two orders being
dispatched, and a set of funds being removed from both customers’ accounts.
Durability
Durability states that when updates have occurred to a resource, only then should the client be notified that
a transaction has occurred. If the system failed for any reason after the notification, then the changes would
still be reflected once the system was restarted. This allows the user to know that a transaction has been
successfully completed even if there is an error later. So relating to the above example, our customer would
not think that the money had been transferred when in fact it hadn’t.
204
Design Phase: Logical Stage
Visual Basic does a lot of work for us developers. Most of the complicated Windows programming that
must be done by C++ developers in their code is already done for us by Visual Basic. Visual Basic allows
us to code to our hearts content without ever knowing some of the deeper Windows concepts, such as what
a thread is. While we can make working components if we do not understand these things, it is very likely
that we will be coding inefficient components without some knowledge of what is going on under the
covers. With regards to MTS, the most important Windows concept is that of threading. Let us take a quick
look at this.
205
Chapter 7
Threading Apartments
Now, threads do not just float around inside your computer’s processor. They need to be put somewhere,
ideally isolated from other threads. It could be a serious problem if the sequence of steps of one thread was
suddenly replaced by a sequence of steps from another thread. To prevent this, threads are placed in
apartments. To keep one apartment separated from another apartment, apartments are placed inside a
process. This looks as follows:
When a client makes a call to a component, COM will create the component in an apartment in a process,
and run the code steps on a thread. If we have two clients, Client1 and Client2 and one component
called Object1, what happens when Client1 calls Object1 and then Client2 also calls Object1?
If Client2 makes a call to Object1 on the same machine as Client1, and Client1 is still using
Object1, the second client must wait. Client2 cannot get access into the apartment until Client1 is
done:
206
Design Phase: Logical Stage
Prior to the current releases of Windows, this is how everything worked. As you can imagine, this does not
scale very well. As more and more clients make requests for the component, the queue gets longer and
longer. Eventually the computer runs out of memory. In Visual Basic, this is called single-threaded, which
is a very poor choice for a name, as all Visual Basic components are single-threaded in the sense that there
is only one thread in an apartment. Single-threaded really means that there is a single apartment.
Apartment Threading
The only other option available to Visual Basic programmers is to have COM create multiple apartments
within one process, each with a thread in it for each call to a component. Each apartment still has one
thread, so this is not multi-threading. This would look as follows:
This solution became available in the recent versions of Windows. As you can see, each instance of
Object1 is still not multi-threaded, but now there can be multiple instances of Object1. Since there is
no waiting for Object1 to finish servicing Client1, all three clients can be serviced at the same time. In
Visual Basic and COM, this is called apartment threading. If you look at the Properties dialog of a
Visual Basic ActiveX DLL, you will see the following options:
207
Chapter 7
MTS will manage our Visual Basic apartment-threaded components: it will have an apartment waiting for
our component when a client is called and will handle the management of creating multiple instances of our
Visual Basic apartment-threaded components. This allows our component to be scalable and to be used by
multiple clients. If we code our components correctly, we can use this to make our components run faster
and scale better. MTS will also create multiple instances of our Visual Basic apartment-threaded
components so multiple clients can use the component.
Now that we understand MTS and Visual Basic, let us turn our attention to the 3-tier solution. Perhaps one
of the most confusing aspects of the three-tier solution is DNA. Microsoft replaced the term three-tier with
n-tier, and now n-tier has now been replaced by DNA. It is important to understand what DNA is if we are
going to develop a three-tier application.
People are often confused because of the word Internet; in fact, DNA does not necessarily involve building
internet applications. Actually, it is about building applications using internet programming techniques.
208
Design Phase: Logical Stage
Internet applications can have thousands of users and require components to handle hundreds of
simultaneous requests. This means that internet programming techniques must include some methods to
make components on the server scalable. One such technique centers around the idea that only the client
maintains state between calls to the server, i.e. the client has a memory of what is happening between calls
and the server does not. If we maintain state on the server, our server component will need to persist
variables for every client currently connected; this could clearly become very costly in terms of resources if
we have thousands of users. Performance considerations therefore force us to make our server components
stateless. For scalable web applications, information is therefore usually stored on the client in cookies
which can be read by the server. Of course, if we are moving information around in cookies, this
information should be limited to the smallest size to prevent delays.
From our discussion of MTS, we know that we can build stateless Visual Basic components that run on a
server. If we build the components correctly, they will be scalable. Thus, including MTS server components
in our application can fulfill the basic requirements of creating an Internet type of application. The best way
to use a Visual Basic middle-tier component is to build a three-tier solution.
Another way to make an application scalable is to build the component out of smaller components. We can
scale the application by redistributing the components across different servers. Internet-style applications
also need the ability to evolve as business requirements and technology change. By building our application
with components, we will be able to update or replace individual components over time, without having to
rebuild the entire application.
Thus, DNA is about building internet-like applications - applications that can evolve and that have a
scalable server component that does not maintain state and a client that does maintain state. DNA could
include building an Internet application, an intranet application, or a three-tier solution with a Visual Basic
executable on the client.
Remember that we looked earlier in the chapter at the use case for entering an order and identified three
objects: Product, Order and Customer. This use case included the line:
This operation contains a series of steps of its own, and can be expanded into another use case, which will
specify exactly what these steps are:
209
Chapter 7
Create Customer
Primary Actor: Order Entry Clerk
Actor requests to add new customer
Actor enters customer name
Actor enters customer address
Actor enters customer phone number
Actor enters customer fax number
Actor enter customer credit card number and expiration date
Actor saves customer information
We are going to take this use case to create a sequence diagram mapping out the sequence of events that are
required to fulfill this goal. Before we even begin, you will notice that we are missing two important
objects. Our use case says “Actor enters”, which implies that the actor has some way to enter information
into the system. In a Visual Basic application, the way for human actors to enter information will be
through a user interface. We will therefore, need an additional object to perform services for the user, the
User Interface, which will allow information to pass from the user to the system and from the system to the
user. All of the client services will be performed by the user interface.
The other object we are missing is the object that will actually perform the updates to the database: our data
services object. When building a three-tier project, the middle tier acts as a middleman between the client
component and the database. The middle tier will receive requests to retrieve information from or update
information to the database from the client component. The client component will gather the information
and then send the request to the middle tier. The middle tier will then communicate to the database and
perform the request. We therefore need a middle-tier object that will perform these services.
The middle-tier component and the user interface are two objects that are implied in the use case.
Remember, the users are more concerned with the goals they want the system to accomplish for them and
the services the system must perform than the actual components of the system. The developers must
review the use cases, begin to draw out sequence diagrams and find the implied objects.
While we can see that the data services were separated out so that they can be placed into an MTS
component for maximum efficiency, scalability and sharing of these services, you may be wondering why
we separate out the business services and the client services. The client services will be very specific to the
application and will generally not be very reusable. Thus, if I make an order entry application from a Visual
Basic executable and remake a similar application for customers to place orders over the Internet, it is
unlikely that much of my executable interface code will be reusable for my Internet application. On the
other hand, the business objects that I create for my executable, such as the Customers, Orders, Order
Details and Products objects, will all be easily reused in my internet application. By creating separate
components that perform business services and client services, we have actually separated out the reusable
components (the components that perform business services) from those that are probably not reusable
(client service components, i.e. user interfaces).
210
Design Phase: Logical Stage
The ability to upgrade the application is another reason we separate the business services and the client
services. It is likely that our application will also have to be upgraded at some point to fulfill new business
requirements that have resulted from the changes in technology and the market. It is likely that most of
these changes will not affect the external methods and properties of the business components, but instead
affect the internal rules of these objects. Thus, a change in tax laws may alter the way the order object
internally calculates the sales tax, but externally there will still be the same Save Order method that will
trigger the sales tax calculation. Thus, for the most part, when we have separate business objects we can
upgrade our applications by creating internal changes to these objects that will not have any affect on the
rest of the system.
When we actually change the way business is done and the interface of the business object must be
changed, we can make these changes and plug these business objects into a new interface. The vast majority
of the code will be reusable. Usually, only one or two objects will have to change resulting in the change of
only a few interfaces. If we needed to make this change in an application where there was no separation of
the business and client-service components, we would probably end up rewriting the entire application.
Thus, the separation of business and client services allows us to reuse business components and easily
upgrade the application.
Because the primary purpose of creating separate components that contain the business logic is for the
ability to reuse and upgrade these components, their location in the physical system is usually not that
important. Thus, we could place the business logic on the client computer or on a physical server. As these
components do not make any direct connections to the database and they will probably maintain state, there
is no requirement to place them on a server or to make them MTS components. The factors that will
influence the location of the business components will usually be how often they will need to be upgraded
(a continually changing component would probably be best on a server since it will only need to be replaced
on one machine, rather than on every client), how easy it is to deploy the components to the client and the
type of application being built.
The use case has provided us with detailed information on the interaction between the user and the client
services object (the user interface). When we look at our use case, we see that it specifies that the actor will
request a new Customer from the system. The actor will then enter the customer name, address, phone
number, fax number and card number and expiration date. Finally, the actor will save customer information.
Thus, the use case has given us all of the information for the communication between the user and the
client-services component. Each of these operations represents a ‘message’ sent from the actor to the user
interface, and will be represented in the sequence diagram by a line from the user to the interface.
When we reviewed the nouns in our use case, we saw that we needed a Customers business services
component. We can see from the use case that this component will need to perform two tasks: creating a
new customer (AddNew) and saving the customer information (Save).
The services that will be performed by the data services do not directly come from the use case. The
developers will review the services that the business services components will need to perform, and based
on these services they will decide what services the data services component will have to perform. In this
case, the data services component will save a new customer and indicate whether the save was successful.
211
Chapter 7
Our sequence diagram for creating a customer will thus look as follows:
There is really an incredible amount of information in this diagram. We can now see that we will need some
additional methods in our customer component. Each arrow represents a request for some object in the
system to perform a service. As we said, most of these requests will center on getting information to set
properties or will be the actual setting of the properties. Luckily, Visual Basic will allow us to make user
interfaces that do not require us to write complicated code to allow the user to enter information into the
user information. Most of the requests to the user interface for services will actually be fulfilled simply by
creating a text box for the actor to type the information in (or a list or combo box to select the correct
information). Other requests, such as ‘Request to Create a New Order’ will actually require the customer
object to have a special object to perform the service (in this case Add New): an object cannot create itself
out of nothing, so we need to have an object which has already been created to which we can make the
request for a new Customers object. We will see how to do this in the next chapter.
212
Design Phase: Logical Stage
Services performed by the user interface will usually involve adding text boxes or list or combo boxes. The
services performed by components will involve setting properties of the object and/or calling methods. Our
sequence diagram allows us to see exactly what objects we need, what methods and properties these objects
will need, which objects request services from other objects, what information must be supplied to perform
the service and what information has to be returned when the service is complete, and what information
must be inputted by the user and returned to the user by the system. So there is really a great deal of
information in our sequence diagram.
From our ‘Add New Customer’ diagram, we can see the following:
The customers component will require an AddNew method (request to create new customer).
The AddNew method will not require any information passed in (no parameters) but it must return a new
Customers object (thus it must be a function and have a Customer object as its return value).
The user interface will need a text box or similar control to enter customer name, address, phone and fax
numbers, and credit card number and expiration date.
While it is not explicitly stated, the information placed into the user interface will need to be passed to
the customer object before the save occurs. Thus, our Customers object will need properties for
customer name, address, phone and fax numbers, and credit card number and expiration date.
The Customers object will need to have a method to save a new customer record. This request to save
the information will be passed onto the middle-tier component. This Save method will take one
parameter, a Customers object.
The middle-tier component will need a method actually to save the information to the database. This
Save method will also take a Customers object as a parameter. The database was not listed in this
diagram as a separate component, but we could have also included it, as the database is an object of the
system. This was not included to keep the diagram simple, but we will show it in a more detailed
diagram below.
The physical location of these components (what tier they will be placed on) could also be placed on the
diagram.
213
Chapter 7
When we add the database component to the diagram, we can see that the application is spread across three
tiers. The refined sequence diagram looks as follows:
This diagram now tells us that there is a database component. The request to save a customer will be passed
from the user interface to the client customer component, to the middle tier component and finally to a
stored procedure in the database. We can also see where the components will be placed in our three-tier
application. The developer has added numerous components and messages that the user is unaware of, such
as the database, middle-tier and user-interface components, and the methods associated with these
components. This is the normal process of making a sequence diagram: we begin with the information in
the use case and then expand the information to include implied objects and the methods and properties of
these implied objects. The sequence diagram may go through many revisions until it reaches its final
version. Some of the revisions may force a rethinking of a use case and force it to be redesigned. This is the
nature of iterative design.
From these sequence diagrams, we can begin to define our component’s public interface. In fact, we have
already identified most of the methods and properties we need. As an example, let’s look quickly at the
interface for the Customers component. We have already seen that our Customers component will need
the following methods:
214
Design Phase: Logical Stage
We will also need a way of retrieving a specific instance of our Customers object. To do this, we will add
methods for moving through the collection of existing customers and retrieving a given Customers
object:
The Customers object will also need properties that contain information about each of our customers. We
can see from the use case and sequence diagram that the information we need to store requires the following
properties:
Name
Address
Phone
Fax
CreditCardNumber
ExpiryDate
Sequence diagrams can be built using sophisticated tools such as the UML tools built by Riverton (HOW),
Rational (Rational Rose or Visual Modeler) or Visio. You can also hand-draw them on pieces of paper to
see the flow of your system, or use graphic programs such as SmartDraw. Use whatever works best for you
and the situation you are in. If you are in a meeting with a client and need to show quickly how the
components of the system may interact, a sequence diagram quickly hand-drawn can provide an easy way to
view the interaction of the different components. If you are preparing documentation for your design
document, you should probably use a professional tool.
The advantage of using UML is that there is no longer any guesswork involved. We still have not identified
how the methods are going to work - we have not designed a detailed map of what the Visual Basic code
will look like in each method, but we will do that in the physical stage. However, we have identified all of
our objects and the methods and properties that will belong to these objects. We have also identified where
our components will be located, how they will communicate to other objects in the system and how they
will communicate to the user.
Before one line of code is actually written we know exactly what the system will do and have a very clear
set of documents (the use cases and sequence diagrams) that can be shown to the user. The user can review
these documents to make sure that all of the goals that the user needs the system to accomplish can be
fulfilled by the system and that the system fulfills these goals in the manner that the user finds most
efficient. As the more detailed diagrams may be confusing to the user, it may be best to show them
diagrams that only show the interaction between the user and the user services object. When an agreement
has been reached on the following items, the developers and users can sign off on the design documents:
215
Chapter 7
A list of the objects that will be required to fulfill the services of the system.
The public methods and properties of these objects.
How the objects will communicate to each other and to the users.
The user will know exactly what the system will do, and the developers will know exactly what they have
to build. The testers will know what modules will need to be tested so that they can begin a detailed set of
test plans. The educators will know exactly how the system will function so they can begin putting together
user documentation and planning training for the new system.
Without use cases and sequence diagrams, there often is nothing more than a list of things the user would
like the system to do. From this list, objects are identified and methods and properties for these objects are
created. The developer will begin to start coding these objects, putting in the necessary methods and
properties. They will then begin to build a user interface based on the developer’s concept of what is
needed. Once the interface is coded, the developer will begin to write code to pass information into the
object. This process may result in the discovery of new methods and properties that the object will need,
and these will be added. As the object is coded, the developer will discover that he needs to pass
information to the middle-tier component, so methods will be added to the component. This style of coding
is much like a man walking into a labyrinth in the dark with a flashlight that only produces a light beam
that shines two inches out. In this situation, the person takes a step, examines the next two inches, and
depending on what he sees in front of him, makes a decision where his next step will be. It is quite possible
that three inches to his right, just outside of the range of the flashlight, is the exit to the labyrinth. But he
will not see it unless he is lucky enough to take a turn to the right. He can only make decisions based on
what the next immediate step is. He cannot look at the next fifteen steps and see how these fifteen steps
may affect his next step.
However, with a detailed set of use cases and sequence diagrams, we can map out the entire system from
beginning to end. We can see how changing one component of the system will affect the entire project. In
our final sequence diagram, we included a final step that involved saving the customer to the database using
a stored procedure. It is also possible that we could use SQL code in our middle-tier component to save the
information directly to the database. Which is better? Well, what if we already had a set of stored
procedures in our database to save customers? If we did not use stored procedures, we would have to write
extra code in our middle-tier component. This could add one day of development time for the component.
Adding this functionality into all of the Update methods in the middle-tier component may add several
weeks to coding this project. Even if we had the time and financial resources to do this, is there any
advantage to be gained by not using the stored procedures? That would allow us to do batch updates with
disconnected recordsets in the middle tier and to check for records that failed to update due to
inconsistencies. These inconsistent records can then be made consistent by the middle-tier component.
Thus, by not using the stored procedures and placing the update functionality in the middle-tier component,
we can move to a more flexible three-tier architecture. While this was a fairly simple example, we can
investigate completely different scenarios by simply redrawing the sequence diagram.
One thing you must be careful about is not stopping once you find a solution to your problem. Once an
initial set of use cases and sequence diagrams have been drawn up, the developers should come together for
a brainstorming session. They should review the diagrams and try to find alternative ways of accomplishing
the goals of the system. Alternative use cases and sequence diagrams should be created. Once several
possible solutions have been arrived at, if this is possible (some systems only have one workable solution),
the best solution should be chosen.
216
Design Phase: Logical Stage
Often, the best solutions are never found because the people looking for a solution
stopped at the first workable solution they came to.
There is another advantage to using sequence diagrams: they show the details of the services performed by
the user, and we can use these to make sure we have a well-designed graphical user interface (GUI). The
user interface is the most important part of the system to the user. We can create an application that solves
all of the problems of the business, but has a lousy user interface so no one will ever use it. Thus, once the
sequence diagrams have been completed, we should go into a detailed design of the user interface. We shall
see how this is done in the next section.
To see how a use case and sequence diagram can help us to prototype a GUI, we will first build the
sequence diagram for Entering an Order. Since this diagram is going to be used to build a GUI prototype,
we will not be interested in the middle and data tier objects. We only want to see how the user interacts
with the client side objects, so these are the only ones we will include here.
As I mentioned earlier, the purpose of this diagram is to help us visualize the communication
between our components. We could make a more detailed diagram showing all of these
possibilities in full, but for the moment we should just be trying to get an overview of the
process of making an order. Editing and creating a customer are not important to our
overview of creating an order. For these reasons, we should leave these possibilities out of
the diagram.
217
Chapter 7
The Customers component then passes the CustomerID onto the Orders object, as this object will need
to know which customer this Orders belongs to. The Orders object will also need to create an OrderID.
Once the Customers object has returned the details about a particular customer, the Sales Representative
requests the user interface to get products that belong to a certain category. The Interface passes this
message along to the Products component, which returns the products to the user. Let’s take a look and
see how our sequence diagram is coming along:
The Sales Representative will then choose a particular product and add it to the Order Detail component.
The Sales Representative can then select more products from this category or make another request for
products from a different one. The Sales Representative will repeat this process until they have completed
the Order that the customer desires. A dashed line at the Interface object shows this iterative process.
Once the Sales Representative has finished, they can tell the Interface to save the order. This request is
passed to the Orders component and the Order Details components, which will then add this new record
to the disconnected recordset and send the recordset to the middle tier. From here, it is passed to the
database so that the database can be updated. As this final part of the operation is outside the realm of our
client objects, it will not be shown in our diagram:
218
Design Phase: Logical Stage
From this we can see that the first thing that happens is a customer will ring in to place an order. Then the
Sales Representative will take their name and details. At this point there are three possible things that can
be happening:
Since the customer information is only modified or added while adding an order, it would make sense to
add and modify customers on the Order Entry form. Now a customer can be added or edited without
interrupting the flow of the order by moving in and out of several forms. This part of the GUI could look
like this:
219
Chapter 7
Everything that the Sales Representative needs to carry out this initial part of her task is available to him or
her on this form. There is no need to swap between forms to complete this part of the task.
The next part of the Order Entry task is to pick out the products that the customer wants and to add them to
the order. This sub-task is quite distinct from taking the customer details and so should occupy a separate
part of the form. It could look as follows:
Using Tabs
We have chosen to use tabs in this section. Using tabs on a form can prevent the form from becoming
overcrowded and difficult to follow. Here, our user needs to check information about a product, such as
cost and availability. So there is a tab to display this general information about the product. Sometimes,
particularly when new products have been entered into the system the Sales Representative is not sure to
which category the products belong. Therefore we have provided a tab to perform a product search. For
most of the time this option will not be used and the tab would not be selected. When it is needed it can be
pulled up quickly with a single click of the tab.
The alternative is to open a special product form that allows the user to search for a product. The Sales
Representative would then have to close this form when they had finished and return to the Order Entry
form. If the user needs to do this a number of times while taking an order, the solution would involve
moving back and forth between the forms a lot of times. This doesn’t seem very efficient.
We could improve the situation by linking the product in the Product Search form to the
Order Entry form. Now we can open the Product Search form, find the product we want
and choose whether or not to add it to the current order. While this is not a bad solution, it
is still easier to click on a tab in the Order Entry form.
The final part of the Order Entry task is to select a shipper, check the order details with the customer and
that they find the total price for the order acceptable and then to cancel the order or go ahead and save it.
This information should therefore be grouped together and the final part of the form would probably look as
follows:
220
Design Phase: Logical Stage
The Sales Representative can spend the entire day using this one form and never have to
move away from it.
Most of the information we used to create this GUI came from the use case Create New Order. However,
there is at least one aspect of the GUI that follows from the sequence diagram. We have learnt that
sequence diagrams place a temporal emphasis on an interaction. They give us the order in which events
occur. Bearing that in mind, take another look at the sequence diagram that we created earlier. You can see
that the user first selects a customer, then a category and then a product. Once the product is selected, the
user enters the required quantity of that product. If you look at the form it is arranged in this order from the
top down:
221
Chapter 7
This allows the user to easily perform the task without having to move all over the form. We are not only
using our UML diagrams to keep a user within a single form to perform a single task, but we are also using
our diagrams to arrange the sections on the form in the order the user is going to use them.
The flexibility of the Visual Basic user interface will allow there to be many different ways to enter
information into the system and make requests for services to the system. Ideally, though, we want to find
the most efficient flow of events and design our form around this scenario.
By the time we reach the logical design stage we have already put together a great deal of information on
the corporation and their goals for the project. During our consensus meetings, we will have reviewed and
rated all of the business processes related to the project, listing their good, neutral and poor qualities. From
these ratings we should get a good idea of what is working and what is not working.
For example, if a company currently has a custom designed Visual Basic EXE application for entering
orders, used by people in the order entry clerk role; we can look at the features of this system to help design
an order entry web application for customers. If the forms for entering order information are rated as highly
efficient and easy to use (see our last form!), we should consider using similar forms on the web page for
the customer to enter the orders. If the order entry system has a highly efficient set of forms for reviewing
product information, once again we could use this as a basis for the product pages on the web site. Of
course, there may be some essential differences between the way we design a web page and the way we
design a regular Visual Basic form, but it is a starting point. There is no reason to be constantly reinventing
the wheel.
On the other hand, if the product forms received a very poor rating, and there is a general consensus that
these forms are difficult to understand or use, then we need a new way of presenting product information
for the web page. The users are a great source for recommendations on how to improve processes. By
reviewing their reasons why a process is poor, we can often see how to improve it.
To address this issue, let’s imagine that there is another use case called Review All Customers performed
by the Sales Manager actor. Part of this Review All Customers use case is to check if a customer’s
information is correct. If the information is incorrect, then the Sales Manager has to modify the customer
record. If the only place to modify customer information were on the Order Entry form, the Sales Manager
would have to perform this task in the Order Entry form, which would make no sense, as this task has
nothing to do with Order Entry.
222
Design Phase: Logical Stage
We could make a separate form that is specifically for Customer Review. While this may seem redundant,
as there are now two places to edit information, there are advantages to doing this. What if the Sales
Manager needed to look at a customer’s past sales history, balance information, and products purchased as
part of the customer review? Now it makes sense to have one individual form to handle customer review.
Most likely the top half of the form will have customer information on it, the bottom half will be a tab
control: one tab for sales history, a second for balance information, and a third for products purchased:
Security
An application that has different actors with different responsibilities will usually have a log in screen and
some form of security. If our application employs the Review All Customers use case, the application
should have security added and only allow a person logged in as a Sales Manager to view the Customer
Review form. The Customer Review form would not be accessible to a Sales Representative.
The Sales Representative has one main role, entering orders. There will only be one form she should have
access to, the Order Entry form. The Sales Representative would come in at the beginning of the day and
log in as a Sales Representative. The application would go directly to the Order Entry form, as this is the
only form a person in this role can access.
As for our Sales Manager, when he logs in there will either be special forms related to his role, such as the
Customer Review form, or one form which will provide different functionality for different users, such as
the Order Entry form.
223
Chapter 7
Internet Applications
There is one other advantage to this single user interface style of programming. Building Internet and
intranet applications is becoming more and more common. While we do have the ability to create dynamic
web pages that can build new pages on the fly, these only work with certain browsers. Users are usually not
too happy when they are constantly waiting for new pages to load. In this case, the usual standard is to
minimize the number of pages and try to complete a single task on one page. Internet solutions seem to
work best with a single user interface such as the one we have built above.
If we wanted to use an Internet browser to run this application on an intranet, we would not have to make
any major changes in the design of my user interface. As this application is being built from the three-tier
model, moving the entire project to an intranet solution would be fairly easy.
We must build our applications with a focus not only on current needs but also on future
needs. The technology is definitely moving toward building Internet and intranet solutions,
and our Visual Basic applications should be able to adapt to these changes.
This approach does not mean that two different actors may not use the same forms.
In our example, the Sales Representative is allowed to create an order, but not to delete or modify them.
The Sales Representative is also allowed to create and modify customers, but not delete them. The Sales
Manager, on the other hand, can modify and delete the orders and delete customers. It makes sense that the
Sales Manager uses the same form to edit and delete orders as the Sales Representative uses to create them,
as both of them will require the same information to perform their task, i.e. order details and customer
information.
Even though they are using the same form, the form may present itself differently to the two actors. When a
Sales Representative views the Order Entry form, they would only have the ability to add a new order, and
edit or add a customer. The buttons to delete or modify an order or delete a customer will be invisible to the
Sales Representative. However, when a Sales Manager logs into the system and accesses the same form,
they will have the command buttons allowing them to edit and delete orders, and delete customers - as these
are tasks this actor can do.
Thus, we have one form that performs several different tasks for two different actors, but this form is
designed to perform these tasks in the most efficient manner. This one form will add, delete, and modify
both customers and orders.
With this type of form there is always the possibility that it will become quite complex. This is something
to take account of when deciding the best way to create the GUI for a particular application.
Although this choice may be guided by the amount of coding that it requires, the main criterion when
creating forms should be the user requirements.
224
Design Phase: Logical Stage
Summary
The logical stage is the bridge between defining the goals of the users and defining components, and the
services and attributes they will need, to fulfil these goals. In this stage we define the interface for our
components, i.e. the public properties and methods of the components.
Our choice of framework will have a major influence on the interfaces that we will choose for our system.
We saw that a three-tier architecture is more scalable and makes it easier to upgrade our application; this
will result in us dividing the system services into three types: client, business and data. The client services
will interact with the user and usually not be reusable. The business services will be easily upgradeable,
reusable and allow for a design that can evolve as the needs of the business change. The internet-style
techniques of DNA, using stateless server-side components, allow our solution to be scalable. We can
further improve scalability by using Microsoft Transaction Server, which provides support for apartment
threading, allowing instances of each object to be created on the server, so more than one client can access
our server-side objects. MTS has the added advantage of providing support for transactions, which are a
prerequisite for any e-commerce application.
The primary tools used in the logical stage are the use cases and sequence diagrams that are built from the
use cases. In addition to these, the initial class diagrams can be created with public properties and methods.
This stage ends with a set of documents that will allow us to move on to the detailed design of our
components.
Finally, this stage also requires the prototype for the user interface to be built, so we also looked at some of
the principles behind building a user-friendly GUI, and saw how we should base the design of our GUI on
the sequence diagrams we created earlier in this stage.
225
Chapter 7
226
Design Phase: Physical Stage
In the logical stage we explicitly defined the components that the product will contain and the methods and
properties that they would require. These definitions were based on the information derived from UML use
cases and from the set of framework technologies that would support the product. The logical design was
totally independent of programming language. In the physical design stage we will translate this “abstract”
design into a concrete physical design for every component in the system and the means by which these
components communicate. Essentially, we will define exactly how the system will be implemented.
Demonstrate how to allocate services (methods and properties) to components for initial class diagrams.
Reach a final decision on the framework within which our product will operate.
Discuss the impact of the technological framework on component design.
Discuss communication between physically separated components
Fully specify a component interface.
Map out the Visual Basic code for selected services.
Thus the primary deliverables for the physical design stage are:
A library of class diagrams defining the properties and methods of each component. This represents the
final interface design of all system components.
A library of activity diagrams mapping out the Visual Basic code for each component.
Chapter 8
The final milestone for this stage represents the completion of the whole design. The team must reach a
consensus decision that the final solution embraces the required functionality and will operate at an
acceptable performance level. The final approved design will provide a complete functional specification
for the development phase.
As the design phase nears completion the solution will be comprehensively defined so that TCO and ROI
can be more accurately estimated. The logistician will be responsible for this.
The product manager will continue to work with the stakeholders and sponsors and will need to ensure that
their requirements, as defined by the use cases and sequence diagrams are carried through into the actual
physical design.
Testers will play a vital role in this stage. They will develop testing strategies and define criteria by which
to measure the product performance. They will create methods and procedures to track problems and bugs.
Based on the testing strategies, a testing plan and schedule will be created and documented. Testing will
also evaluate the overall design, assist in building applications to test new methodologies or technologies,
and select appropriate testing software.
Educators will review the design to determine how usable the project will be, and make recommendations
on how to make the final product more efficient for the end users. Towards the end of this phase, the
educators will make a more refined estimate of how long it will take to build the end-user documentation
and training materials
When it comes to the components we will be creating with Visual Basic, the physical stage is where we
map out the code of all of the internal and external properties and methods of these components. This will
complete the design of these components.
The physical stage will form a bridge from the interfaces we designed in the logical stage to the actual
implementation of the objects with Visual Basic code in the development phase. How you make this
mapping will be a topic of this chapter. We will also discuss the most efficient way to build our components
and give information on making the decisions that need to be made during this stage.
228
Design Phase: Physical Stage
There will be no coding done in the physical design stage, except to test various techniques or technologies.
The physical design stage will be about deciding how the components will be coded, what should be used to
code different parts of the system and a choice of technologies.
The physical stage will be based on three steps. The first step is performing research on the best way to
implement a component, the second step is evaluating the research material and choosing the best option
and the third step is mapping out the solution that has been chosen. This chapter will focus on these three
steps. Before we look at these three steps, we must first look at one of the most important concepts of
design: designing the product as a team.
Designing as a Team
One of the major advantages of using UML documents to design our components is that they give the
development team the ability to design the project as a team. In many organizations, once the initial design
of the interfaces is completed, the design is handed off to the developers. The developers will then divide
the components amongst themselves and then lock themselves away for a few days or weeks and hammer
out mountains of code. The result will be components that will all be coded differently, according to the
skill, style and experience of the developer who wrote the individual code module. Testing and debugging
will be difficult, as each component will be coded differently. Difficulties will be exacerbated by the lack
of clear, coordinated documentation showing how the code was written and how it all fits together.
Using a single set of coding standards is the first step towards solving this problem. One set of standards
will allow the testing team members to move from one developer’s code module to another developer’s code
module without having to spend time figuring out how the code was written. Yet, this still does not solve
the problem of different skill levels and different styles. Wouldn’t it be great if you could take the
combined knowledge and talent of the entire team to arrive at the best way to code each module? With
UML you can.
It becomes much easier to understand the code if there are design documents, such as activity diagrams, that
clearly map it out. Component managers should implement practices that encourage their team to clearly
map out the optimum coding solution in such diagrams. How do we arrive at the best solution? Meetings
can be arranged whereby the whole team decides the best way to code a particular component. When a
consensus as to the best solution is achieved, this can be documented in an activity diagram. Alternatively,
individual team members can work out the way to code a module and document their solution in an activity
diagram. These diagrams can be circulated to the rest of the team, who can review the coding techniques
outlined in the diagrams and comment on alternatives or better methods.
When the design process becomes a collective activity the solution will represent the
collective knowledge and experience of the entire team.
229
Chapter 8
It is important to remember that there will often be significant overlap between each stage of the design
phase. The physical stage does not wait for every sequence diagram to be complete before commencing.
When code mapping and testing begins, design faults or new ideas may emerge that mean a particular
component revisits the logical, or even conceptual, stage. Designing an effective solution requires a
significant amount of work and requires planning, creativity and a real commitment to finding the best
possible solution. I think it is safe to say that a team of peers working together, rather than a team of
individuals working separately, will achieve the best design.
We now need to discuss exactly what is involved in choosing the best solution for your product.
One editorial in Visual Basic Programmers Journal commented that one of the major reasons developers
chose Microsoft products to build their applications was the wealth of available information. With regard to
Visual Basic, this is especially true. A “Visual Basic” search on the Wrox Press site brings up 115 books.
The Amazon site lists over 90 books with Visual Basic in the title. Visual Basic has become an extremely
complex programming language but, no matter what the topic, there will almost certainly be a book or
article on it.
While the MSDN library (Microsoft’s library of information on their products - available on their web site
and on CD) has received quite a few complaints, it is still an incredibly valuable resource. There are also
many additional SDKs (Software Development Kits - special informational files for Microsoft products)
that provide additional help. One example is MDAC (Microsoft Data Access Components) that provides
information on data access technologies such as ADO, OLE DB, ODBC and ADO MD.
The MSDN allows you to do searches on key words. Unfortunately, the search often brings up dozens of
possible titles. Finding the right title might be difficult. Sometimes it is easier to highlight the word in your
code that you want help on and click F1 than it is to type the word into the MSDN and search.
In addition to the MSDN and books, we have magazines such as Visual Basic Professional Journal, dozens
of web sites such as devx.com and various groups around the world that provide assistance with Visual
Basic. If you still can’t find the answer, there are still more resources to turn to. Microsoft has the
Microsoft Consulting Services for solving the problems of large corporations and the Microsoft Solution
Providers for solving the problems of smaller corporations. Of course, if you have a coding problem, there
is always Microsoft Support.
230
Design Phase: Physical Stage
When approaching any new project, it is always best to start by searching through the MSDN,
Microsoft.com and the Visual Basic web sites. While you may not find the specific answer you are
looking for, you will often gather code samples and articles that give you enough information to experiment
and find the right answer for your problem.
Once information has been gathered from every available resource, you start testing in the environment that
your project will run under. You create small prototype testing applications that will test the code to see
what its limitations will be. How long will it take to return 1,000 records from a middle tier component
running under MTS with 50 simultaneous requests to the component? The answer to such questions depends
on the network, the server, the client and a host of other factors. Only through testing can you find the
answers for your physical configuration. Based on those answers, you can decide if the solution fits within
the constraints of the system. You can test your own coding solutions, third party solutions and your own
code that exists from previous projects. Your tests should see how well these solutions meet your project’s
requirements.
You should carefully document all of your research and your testing. You will use this information to
decide what is the best solution for your project. You can also use the results of your tests to determine
what are the best methods to code your components
Once you have performed a series of tests and gathered information, you must determine the best solutions
for your project. There will be many choices. The first choice is what are we going to use to build each
component. Let us look at this issue.
Writing code from the ground up is usually the most costly and difficult. Writing code requires time,
training and expertise. Writing your own code also means first performing tests to find the best way to code
your component, then performing unit testing of each portion of the component and finally, testing the
component as part of the whole system. All of this takes considerable time and money. There is one major
advantage to writing your own component: you can customize the component to meet the exact needs of
your project.
Using existing components has several advantages. If the component was properly built, it has been
documented and tested as an individual component. Therefore, you can save a great deal of time and
expense. The usual problem with using existing components is that they usually cannot do exactly what you
need them to do. If it is code written with components and you only need to modify a few components, it
may be well worth reusing the code.
The greatest danger of code reuse is that the code may not have been properly written. There is an old story
about someone using someone else’s code, completing a project with it, and then finding out that the code
does not work properly. When the person who used the code in the project goes to the person who wrote the
code and asks them about the problem, the person who wrote the code says that they had that problem with
the code, too. Make sure any code you are reusing or buying has been thoroughly tested and works properly
before using it. Also, make sure that you will not spend more time modifying it to your needs than the time
that it would take to build it from the ground up.
231
Chapter 8
Using third party components can save a great deal of time. Just be careful to get your components from a
reliable source and to use them in the way in the manner in which they were intended. Most third party
components are precompiled. This means that you cannot modify them, and that they often have many extra
methods and properties that you do not need for your application. This can bloat your application.
Each choice has positive and negative attributes. Which is best will depend on the application and the
components you are building. By choosing to build your application with components, you can choose the
best solution for each component.
Each choice you make during design has a set of risks. Each choice must be made based on the business
requirements of the application, the constraints on resources such as time, number of developers and costs,
and what is considered an acceptable risk. One choice Visual Basic programmers seem to hate to make is to
use something other than Visual Basic for any part of their Visual Basic application. Sometimes, though,
Visual Basic may not be the best choice.
An interesting story revolves around a book that is one of the better books on Visual Basic 5. This book
gave a great deal of detailed information on how to do some of the more difficult things in Visual Basic,
such as using API functions in Visual Basic. The book also showed how to make Visual Basic do all sorts
of things with pointers and other things that the language was never meant to do. This book came with a
very useful code library that thousands of people used in their projects.
Everything worked fine until the next release of Visual Basic. The author (and the users of his code)
discovered that some of the functions in the code library from the book did not work with the new version
of Visual Basic. It turned out that Microsoft plugged a few holes and changed a few things, and some of the
tricks the author used to work around Visual Basic no longer worked with Visual Basic 6.
He complained to Microsoft. Microsoft explained that he was doing things that were unsupported and that
Microsoft could not be expected to make sure that every unsupported technique people use with Visual
Basic is compatible from one version to the next. Microsoft spends a great deal of time and work making
sure that supported options work from one version to the next. The author was outraged that Microsoft
would not make a minor change in the next release of Visual Basic so that his unsupported techniques
would still work. The author published a letter and said that he was disappointed with Visual Basic and
would not program with the language anymore.
This situation, which really happened, led me to think about how I programmed in Visual Basic. I had made
Visual Basic do some intense things, such as using memory mapping and using pointers to get the parent in
class hierarchies.
232
Design Phase: Physical Stage
A pointer is a variable that you can use to store a memory address. The address stored in a
pointer usually corresponds to the position in memory where a variable is located, but it can
also be the address of a function.
I began to realize that there were other solutions than bending Visual Basic so that it could do things it was
not meant to do. I developed a simple set of rules to use when I found that Visual Basic could not do
something I needed. They are as follows:
If I need a control to do something that the control cannot do, I will first investigate third party controls.
If someone else has already built a control that does what I need, it makes sense to use it instead of
forcing a control to work in a way it was not designed to. If you want a control to do something that is
reasonable, you can almost be certain that many people needed the same thing. Where there is a need,
there is a market, and where there is a market, there usually is a solution. If no control exists that has this
functionality, I will try to find another way of doing it. Only when there is no third party alternative, and
there is no other solution, will I make a control do something it was not designed to do.
If Visual Basic cannot do a task and C or C++ can, write a C or C++ Dynamic Link Library (DLL). A
DLL is a COM-enabled file with a .dll extension. Generally, DLLs are made up of a set of classes that
that are blueprints for the creation of COM objects. The DLL will be used by Visual Basic to do the task
Visual Basic cannot do. Because we have designed COM components, and not a monolithic application,
we can choose to make any component from whatever is the best development tool. Thus, I can write
95% of my application using Visual Basic, but the last 5%, which consists of a few components, can be
written in C++. I can also write 75% of my code in Visual Basic, 5% in C++ and 20% using third party
add-ins. The goal of the physical stage is to choose the best option for each component, not find a way to
use Visual Basic for every part of your application no matter what it takes.
Using pointers in Visual Basic makes sense when it comes to using the AddressOf function to work
with the Windows API functions that require pointers as parameters. This is the one area in which Visual
Basic pointer use is supported by Microsoft and a great deal of work has gone into the language to make
it compatible with the Windows API functions. Other than accessing a Windows API function, if you are
thinking of using pointers in Visual Basic, you probably should be thinking about using a C++ DLL.
In general, any large Visual Basic development team should have at least one C/C++ programmer who can
write small DLLs to do the jobs Visual Basic cannot handle. If you are a smaller team and cannot afford a
C++ programmer, train one of your Visual Basic programmers to work in both languages. If you cannot get
or train a C++ programmer, look into third party solutions.
Using unsupported methods is not wrong - it’s just risky and time consuming. When I wrote the memory
map program (a program that stores data in an area of memory to be used by components in different
processes), I used a code sample from a reliable source. It worked sometimes and other times it did not. We
tried everything we could to get it to be stable, but we never made it work properly. Finally, we called
Microsoft Support. Microsoft Support helped us even though technically we were doing something we
should not have been doing. It turned out that the code sample had a number 2 in one of the pointer
formulas that should not have been there, so we were writing in memory somewhere we shouldn’t have. It
took us about two weeks to straighten it all out. I am certain that a C DLL could have been written in a few
days.
233
Chapter 8
For the most part, when you try to make Visual Basic do something it should not be doing, you end up
spending a long time making it work. Doing pointers in Visual Basic usually means creating a General
Protection Fault (i.e. a fatal error) in the Visual Basic IDE a few dozen times until you get it right. Even
worse, unsupported techniques may not work in the next release of Visual Basic. If you need to upgrade
your application, you may find yourself rewriting your entire application to work with the new version of
Visual Basic if you are using unsupported techniques. Finally, unsupported techniques may work on some
platforms, but fail on others.
Some of these techniques allow you to do very powerful things with Visual Basic, but you really need to
consider the possible consequences of using these methods in an Enterprise- wide application.
For the parts of your application that you do choose to use Visual Basic for, you should map out how they
will be coded in the physical stage.
Resource Estimates
Once the choices have been made, you can give an accurate estimate of what the total cost of the project is
going to be. You can also give a good estimate of how long the project will take and the number of people
that will be required to build the project.
You can use a tool such as Microsoft Project 98 to map out different solutions to help you find the best
project plan. For example, you may be considering how it will affect the overall project if you use three in-
house developers or if you hire a consultant for a fourth developer on the team. Will the extra time required
to develop with three in house developers be great enough to justify the expense of the consultant? What
will the consultant cost? Another question might be, “How much extra time and cost will be added to the
project if we use a third party component versus building the component ourselves?” All of these types of
questions can be answered by making different schedules and resource plans for each possible situation.
You can make a copy of the Microsoft Project 98 template we created earlier for each solution you want to
investigate. Using the templates, you can then map out each solution in terms of time and resources. Doing
this can give you a good estimate as to what will be required for each solution. These different solutions
can be shown to the client so they can see how each solution affects the available resources.
When the final solution is chosen, it should be documented. The risks associated with this solution should
also be documented as well as the resources required for this final solution.
234
Design Phase: Physical Stage
From this diagram we identified two methods for our Customers object: AddNew and Save. Our Update
Customer sequence diagram must include a request to return an existing customer. Thus we identified the
need for methods to navigate through the collection of existing customers to select the appropriate one:
Move Previous, Move Next, Move First and Move Last, Get Item, along with an Edit method.
In addition we will need a Delete method (we did not discuss the Delete Customer use case since this was
not a valid goal in the order entry clerk role).
We are building the customer component so that it has the ability to return a customer object thus the
component must contain all of the properties of a customer - Name, address etc. - that we defined in the
previous chapter.
235
Chapter 8
OK, we have identified methods and properties for our Customers component using our sequence
diagrams and use cases. We have to stop and think here. The first question we must ask ourselves is: “Does
it make sense to put all of these methods and properties into one class, say clsCustomers?” The answer,
as I’m sure you knew, is no.
For example, our Customers component needs to perform the service of returning an empty Customers
object when requested to create a new customer, that is, it must execute the AddNew method. If the
AddNew method were part of our clsCustomers class, we would first have to create the
clsCustomers object and then we would need to call the AddNew method in this object to make a new
clsCustomers object. We would be asking the customer object to make itself once it already existed!
Another property we might like to have is a Count property that gives us the total number of customer
objects in the Customers collection. Once again, it would make little sense to add the property to
clsCustomers. Each object in the Customers collection should be independent of any other object. If
an object has no knowledge of the other objects then it cannot perform a count. What we need to do here is
put all of these sorts of methods into a separate class: we need to create a class hierarchy.
Class Hierarchies
In the real world, objects are made somewhere. If we want a new car, we go to the dealer and have them
order us one from the factory. The factory will build our new car for us, and the dealer will deliver it. If we
want to change something on the car, then we must take the car back to the dealer, who will then arrange
for the repair. If we want to get some information on this type of car, such as how many were sold, we
would ask the dealer. The dealer manages all of the services we will need performed on the car. Just like the
car needs someone to manage all of the services related to the car, our components need a manager to
manage all of the services related to the component. In the case of our components, this manager will be
another class that performs these services on the clsCustomers class. Thus, in our two-class hierarchy
we would have a managed (bottom) class, clsCustomers, containing all of the relevant properties that
describe a customer:
236
Design Phase: Physical Stage
Normally when we list the properties and methods of a component in a class diagram, a plus
sign (+) means the method or property is public, a minus sign (-) means that the property or
method is private and a pound sign (#) is used for friend properties (properties that can be
seen by everything within the component but cannot be seen outside it). All of our customer
properties and methods are public, so in this case we have omitted these signs.
We can perform this process for all of our components. Our Products component, for example, will have
different properties but the same methods as the Customers component. Thus we will find that
clsProductsManger may well be identical to clsCustomersManager.
When designing a Visual Basic class, all of the methods in the class should be
services that the object created from the class will perform. If you have a method
that performs a service on the object, such as AddNew, then it belongs in a separate
managing class. Any property that belongs only to the object, such as customer
name, should be in the class that belongs to the object. Any property that is shared
amongst all of the objects, such as Count, belongs in a managing class.
Not all classes on the bottom of the hierarchy have only properties in their
interface. If we wanted to build an animation program with an animated cat, the
cat component might look as follows:
Walk, Meow and WagTail are all services that are performed by the cat object, not services performed on
the cat object. Our managed class does not perform any services, so it will not have any public methods.
237
Chapter 8
OK, so we have a two-class hierarchy consisting of a managed class (clsCustomers) and a managing
class (clsCustomersManager). Together, the two classes would make up our Customers component.
What happens, however, if we have more than one type of customer? Consider the following hypothetical
situation. Different users at Northwind may actually need to look at different types of customers. For
instance, a Sales Representative may need to view all customers during their working day; but a Sales
Analyst at Northwind might need to look at all the customers who have made orders very recently. Or a
rather interested Sales Manager somewhere may need to view all customers who are regularly spending
over $1000 an order, say. In other words, each different user may need to view a different Customers
collection. In this situation we would have to deal with three collections of customers. The best way to
handle this would be to create a three-level class hierarchy:
So what’s happening in this diagram? Well, if you think back to our two-level class hierarchy, you’ll recall
that we had a managing class and a managed class. In the diagram above, our managed class is represented
by the rightmost collections of actual customer details. And our managing class is in the middle of the
diagram, managing those collections of customer details. We’ve now introduced a third level class (the top
class) - which itself manages what was our original managing class.
This is a fairly complex hierarchy. To actually build this component we would need to map out what each
class would do and how it would communicate with the other classes. Bearing this in mind, you should not
use hierarchies unless you have a need for them. If you find yourself building a hierarchy and the methods
and properties all belong to one object, it is likely you should be building a single class. If all of the
methods act on one class, and all of the properties belong to that class, then it is unlikely that you need a
hierarchy.
A final point to note before we move on is that we can create, for example, a Products class hierarchy in
a similar manner. If you recall, we noted that the public methods for this class would be the same as for the
Customers class but the public properties would be different. When public properties are moved in to the
bottom class, then clsProuductsManager will be virtually identical to clsCustomersManager.
238
Design Phase: Physical Stage
We are still not at a stage where we know the exact design of our components. In Chapter 7 we discussed
our reasons for choosing a three-tier framework for our project: scalability and upgradability. We now have
to choose how to distribute our objects in within this framework.
Data services tier - where the components that communicate directly with the data source reside.
Business services tier - components that service the client application and usually encapsulate business
logic, which validates the data being passed to or from the server (see discussion on Business Rules in
Chapter 6).
Client service tier - the user interface.
How clear cut is this classification? The main responsibility of our top class
(clsCustomersCollectionManager) is simply to retrieve a particular Customers collection. This
functionality could be incorporated into a user control on the user interface. Thus, in effect we are logically
spreading our component over two tiers. The next question is: should we physically locate the managing
and managed classes on a separate server? With regard to our order processing application executable, the
answer is almost certainly “No”. Our managing class contains no methods for directly retrieving and
manipulating data on a database server, as this is handled by our data services component.
The presence of such methods would be a good reason for putting them on a separate server,
where they would be most effective in dealing with data manipulation and transactions. The
managed class could be placed on the client, where its responsibility would be to maintain
state.
Therefore it makes most sense for the Customers component to reside entirely on the client. When the
data services component receives a request from clsCustomersManager to update a Customers
object, a disconnected recordset will be passed from the data services server to the client. The managed
class objects will contain a disconnected recordset object that will be used to view and update that object’s
information. We could represent this as follows:
Of course, the “data tier” in our order processing application is simply an mdb file that will reside on the
data services server. Thus in a physical sense this is two-tier architecture.
239
Chapter 8
We must bear in mind what we are building here is a fairly fat client. The client will have numerous
components that will communicate with the interface and the data services tier. These client components
will not have a connection with the database and, since we don’t want them to be constantly communicating
with the database to get data, they will store data on the client-side. The client can read the records and
return the records to the data services tier to make changes to the database. Yet, having records on the
client-side makes this an even fatter client. If this is an order processing application being used by order
entry clerks connected to the server through the network, this is a good solution. You want the information
to be readily available. As long as you place limits on the amount of information on the client and don’t
allow huge amounts of data on the client, this will work efficiently.
Yet, this is not a very workable solution for the Internet, which requires a thin client. If we wanted a thin,
dynamic, interactive Internet client, we could only allow very small sets of data to reside on the client. To
resolve this we could place the client-side objects onto a web server. These objects could pass the data to an
ASP page, which properly formats the information and passes it back to the client in a standard HTML
page.
An ASP page is a web page associated with Internet Information Server (IIS), that allows a
request to be passed to a server, be processed, and return an HTML page built on the fly.
In this way, we could create a Products object that works in our order-processing project on the client,
but resides on the web server in an Internet application, which allows customers to view the products. The
Internet application will pass back HTML pages with product information to the client. Therefore, we can
use one object to build two applications that have completely different requirements, i.e. a thin and a fat
client.
Our Server object has no properties and so it will have no history and no memory of what was requested,
i.e. the server does not have any state. The middle-tier objects are simply performing a task. When the task
is done they have no memory that they did it.
240
Design Phase: Physical Stage
As we stated in the last chapter, there are no properties in the data services component because it is
stateless - every call the client application makes to the Server object is viewed as a new client. Afterwards,
the Server object has no memory of the client and the property values would not persist from one call to the
next.
This works the same way as an HTML page: using a browser you connect to a server, which
returns the page you are requesting. Once the data has been returned to the client, the
server and the browser have no knowledge of each other.
In the case of this component, all of the data resides on a single database and there are only two public
methods for each business component: Return and Update. We could further divide this into separate
classes so that we have one class for every business component, but there is no need to do that with only
two methods per object. Since all of the components will share the same databases they will have the same
internal code for connecting to the database.
241
Chapter 8
What would happen, though, if this data were contained in several databases? Perhaps the employee
information is in a completely different database than the rest of the data. In this case, if we were to keep
the employee information in the Visual Basic class with the rest of the components, we would need two
separate sets of database information. For those of you familiar with the ADO, this means that we will need
two connection strings and two connection objects. We would need to place Select Case statements in
our code to check which database we are connecting to. None of these are good coding techniques. Thus,
when it comes to the server component, it may make sense to create separate classes to service different
business components if the data comes from different databases. This will make a component that has tight
cohesion, as each component will be working from one database.
We’ve covered a lot of ground in defining the design of our components and their interfaces. However, we
are not finished yet. We know that our data services and business services components will reside on
different servers but we have not discussed how they will communicate. We have talked about passing data
between the two servers in disconnected recordsets, but we have not discussed in any detail the technology
that will facilitate this, namely ADO. These framework technologies, along with MTS, will have
considerable impact on the way in which we design our components.
The main reasons that we have chosen ADO is so that we can retrieve data from our data source (an .mdb
file) and pass it in a disconnected recordset from our data services server to our client, where it can be
manipulated locally (when the recordset is later reconnected, the server can be updated). ADO allows
applications to work in disconnected and stateless environments such as the Internet. Thus ADO is the
perfect method of data access in a Windows DNA environment. One of the major benefits we will derive
from the use of ADO, is the ability to pool connection objects.
Connection Pooling
The Connection object is what connects the consumer to the provider. That is, it’s the link between the
program and the data. You actually don’t need to explicitly create a connection object to do this (you pass a
Connection String directly to a Command or a Recordset object). However, establishing a connection to
a data source is a time-consuming event. If you are going to be getting data from the data source more than
once it is well worth creating a connection object because, as you will see, the connection won’t have to be
established each time.
242
Design Phase: Physical Stage
Connection Pooling means that ADO will not actually destroy Connection objects unless it really needs
to (this is subject to a timeout value - if the connection hasn’t been reused within this time, it will be
destroyed). So, you open a connection, perform some data access, close the connection and from your point
of view, the connection is closed. However, underneath OLEDB keeps the connection in a pool, ready for it
to be used again. If you then decide that you need to open the same connection again, you will be given a
Connection object from the pool of connections, and ADO doesn’t actually have to perform all of the
expensive data store stuff again. You may not necessarily get your original object back, but may get one
that matches the same connection details. In fact, existing objects will be given to anyone who requests
them, so this is even better in a multi-user system.
One important point to note about connection pooling is that connections will only be reused if they match
the exact connection details. So on multi-user systems, if you specify the same data store, but different user
names and passwords, then you will create a new connection, rather than having one reused from the pool.
This may seem a disadvantage, but pooling must be done this way to avoid breaking security.
With regard to our project, RDS is the perfect choice. For our web application, we
can use RDS to make the connection between the server object and the client
through a Microsoft Internet Information Server (IIS), using HTTP. RDS also
supports DCOM, so for our order processing application this can be our means of
communication across a local network.
243
Chapter 8
This is an ideal scenario for our E-commerce site. Let’s think again about this application, which allows
customers to view the products on a web site. Say a customer is browsing through one range of products
and then decides to look at a completely different range. Without RDS, the browser would have to request
new data, wait for a response from the server, receive the new data and then reload the page. With RDS, all
of the data is on the client so the speed of the web application approaches that of more traditional desktop
applications.
The data is held on the client in an ADOR Recordset object. This is a smaller, lightweight version of the
full ADO Recordset object (it doesn’t have the explicit Command and Connection objects). The
ADOR Recordset object is designed for transmission over the relatively low-bandwidth connections of
the Internet and so has a smaller footprint in memory. Our application won’t require a constant data
connection because the connection is severed without affecting the data. This is because RDS is very
closely associated with ADO, which, as we know, provides disconnected recordsets.
How does all this work? Essentially, RDS works by making the connection between the server object and
the client through a Microsoft Internet Information Server (IIS) web server. As we discussed earlier, COM
objects cannot communicate directly if they are not running in the same process space, therefore there needs
to be a mechanism by which they can communicate when they are running in different processes. A full
description of how this comes about would include a detailed discussion of the RDS object model. This is
beyond the scope of this book.
For a full description, I would refer you to Professional ADO RDS Programming with ASP,
ISBN 1861001649, published by Wrox Press.
However, we must briefly mention the RDS.DataSpace object. This object runs on the web client,
creates COM objects on an IIS server and returns an object reference from the server to the web client
application. These references are called proxies and are a bit like your television remote control. In a
similar manner that you can press a button on your remote control to make something happen on your
television, a client-side proxy object is the remote control that can be used to make something happen on a
server side object across the Internet.
RDS will make a proxy of the Server object on the client. The proxy will look exactly like the Server
object, that is, it will have the same public properties and methods as the Server object. As far as the client
application is concerned, the Proxy object is identical to the Server object. The client will make requests to
the Proxy object, and the RDS will pass this request to and from the Server object on the server. This is
called marshalling.
244
Design Phase: Physical Stage
Marshaling, through an IIS Web Server, is done using HyperText Transport Protocol (HTTP) - the
standard Web protocol. The following diagram may help to explain how marshalling works:
Marshaling is the process that must occur when a proxy communicates with a stub. When they communicate
with one another, the message must be packaged for transport across process boundaries. After the message
is packaged, it is sent (copied) form the proxy to the stub. When the stub receives the message, it must be
unpackaged and sent on to the server object. Marshaling does not include the instantiation or destruction of
objects, but is the activity of passing data across process boundaries.
245
Chapter 8
The major advantage of this technique is that the client only has to be configured to have an Internet or an
intranet connection. RDS using HTTP allows users to access the database on any client via an Internet
connection. The connection to the server may be made through a Domain Server Name (DSN). Therefore,
the client needs no knowledge of the server’s actual address or, in fact, any information on the server
whatsoever. This allows the DSN address to act as a gateway that may actually represent any number of
actual Web Servers.
The really great thing about RDS is that as well as supporting HTTP - it also supports DCOM.
DCOM is a Microsoft technology that enables COM components to communicate with each
other across a network. DCOM extends COM in a transparent fashion, such that any
existing COM component can be remotely used without ever changing a single line of code
(although it is important to remember that a COM component written without any
consideration to DCOM specific issues, probably won't be efficient or scalable). DCOM is
language neutral. This means that any language that can produce COM components can
have these components run over DCOM. A very good introduction to DCOM can be found in
the book VB COM, published by Wrox Press.
ADO disconnected recordsets are optimized for use with COM/DCOM so DCOM is the perfect means of
communication between remote COM components on a local area network, without HTTP. This is a perfect
solution for our order processing application!
246
Design Phase: Physical Stage
DCOM can be difficult to configure when there are thousands of clients (such as for
a web application) but is an excellent choice for Intranet or internal applications.
ADO
Visual Basic ActiveX DLL: You can actually build your server components as a Visual Basic ActiveX
DLL or as a Visual Basic IIS application. The ActiveX DLL will give you a greater degree of control
over who can access your data over the Internet than an IIS application. IIS applications, though, give
you more flexibility and perform better when there are dozens of forms.
Microsoft Internet Information Server: This is required for RDS to connect to the server using the
HTTP protocol and the Internet. This must be an NT 4.0 Web Server with the Option Pack installed
(RDS is installed with the Option Pack by default).
Database: A database for which there is an OLE DB provider.
Client Machine: This computer must also be connected to the Internet - usually through an Internet
service provider (ISP). To deploy the client application, use the Visual Basic Package and Deployment
wizard, which will ensure that both ADO and RDS are installed on the client machine.
Effect of MTS
Finally, before we start creating our activity diagrams we need to consider how the use of MTS will affect
the design of our components. Running our components in MTS will add some activities to our diagrams
and we at least need to discuss these MTS activities. As we discussed previously, MTS offers two main
advantages to our product:
Object Lifetimes
One of the principal reasons that MTS can easily allow many users to access our objects is that they are
only around as long as we need them. When we create an object that is being hosted in MTS, which requires
transactional support, the request is intercepted by MTS, which creates an MTS Context Wrapper object
for our object. Note that our ‘real’ object is not actually created.
It is only when we actually call a routine on the object that an instance of our object is actually created.
This is known as Just In Time (JIT) activation. This saves on resources because we don’t actually have an
instance of the object hanging around until we actually need it. Finally, when the routine ends the ‘real’
object is destroyed. This is known as As Soon As Possible (ASAP) deactivation. The client is completely
unaware of any of this happening because it’s holding a reference to the Context Wrapper object and not the
‘real’ object.
247
Chapter 8
Managing Transactions
In order for us to take advantage of many of the features that MTS offers, we need tell MTS when we have
finished a transaction and whether it was successful or something went wrong. In order to do this, we need
to use the context object (also referred to as the ObjectContext object). Each of our objects created
under MTS has its own context object. This object contains information about the ‘real’ object’s execution
environment, such as transactional status and security information.
SetComplete
SetAbort
If the transaction was successful then we need call SetComplete, and the changes will be committed. If
for any reason an error occurred, then we need to call SetAbort and all changes will be rolled back.
We only have to call SetComplete and SetAbort in public routines before we exit. In private methods
or properties, we don’t have to worry about finishing the transaction because we are not ready to destroy the
server object. When the private method or property is done, control will be passed back to the calling
routine, which will be responsible for telling MTS to SetAbort or SetComplete. Remember this rule
for making MTS properties and methods:
Every public method or property must end the transaction, one way or another,
before they finish.
Think of our public methods as the entry and exit points of our object. When we enter, MTS will create the
object; when we leave, we’ll be good guests and let our host know we are leaving, by calling
SetComplete or SetAbort.
If we need to call several properties or methods, there should be one method that starts the
transaction, calls all of the other private routines, and (if everything is successful) the initial
method will close the transaction when it is done.
The language that DTC uses to communicate with databases is based on a standard, and
most databases conform to this standard.
248
Design Phase: Physical Stage
When a method or property of an object hosted in MTS makes a connection to the database, the DTC will
automatically start a database transaction. Yet, to end or cancel the transaction, the component must send a
message to the DTC through MTS that the transaction is complete, or has failed.
Non-Transactional Objects
The best part of MTS is that it can manage any object, even one that is not participating in a transaction.
MTS does not care if our component does not have any transactions: it will still manage our component so
that many clients can access it efficiently. When our non-transactional component tells MTS that is done,
MTS will destroy our component at the appropriate time, just like it did with transactional components. The
only difference is that MTS will not pass any messages onto the DTC.
with how it looks now that we have taken into consideration the environment in which our components
must work(don’t forget, the managing class will be common to the Customers, Products, Orders
classes etc.):
249
Chapter 8
It is clear that we have now gone way beyond our initial interface, comprised exclusively of public
properties and methods. We have now defined some friend and private properties and methods. We are not
going to get into a full discussion of exactly what every property and method actually does but from our
previous discussion of our technological framework, you should have some understanding of where some of
them came from. The GetProxy() and SetProxyInformation(…) methods, for example, relate to
our component communication technology, RDS. The BOFAction and EOFAction properties will
describe what should happen if we go beyond the first and last records when navigating through our ADO
Recordset object. Hopefully, more of this will become clear in the Development phase, when I will show
you exactly how class diagrams (and the activity diagrams we will produce shortly) translate into actual
Visual Basic code.
One of the goals of this book is to bridge the gap between project management, who may not have extensive
coding experience, and developers. Hopefully it will give a much fuller appreciation of the amount of work
and consideration that must go in to designing a successful enterprise system and of how technical issues,
such as choice of a particular framework technology, can have a fundamental impact on the way in which a
component is coded, testing procedure etc.
250
Design Phase: Physical Stage
Before we start I would just like to re-emphasize the importance of creating and documenting UML
diagrams at every stage of the design process.
Every code module should be traceable back to the original user goal that the
module will help fulfill. By creating use cases, sequence diagrams, class diagrams
and activity diagrams one can trace back every code module. This allows the
developer to easily understand what the purpose of the code is and to optimize the
code to fulfill the goals of the user.
Just as we make code libraries, we can create libraries of UML activity diagrams. These diagrams can be
used to show the flow of the code and be used as teaching aids for junior developers or as a starting point
for code modules that perform a similar function. As we discussed earlier, activity diagrams can easily be
shown to different members of the team for suggestions on ways of improving the coding techniques. It will
only take a few seconds to understand the diagram and changes can be made easily and quickly.
Activity diagrams will have a black dot to mark the beginning of the diagram and a black dot with a circle
around it to mark the end of the diagram. A lozenge shaped box marks each activity in the diagram. If there
are decision points, they are marked by diamonds. First, let us take a look at a relatively simple activity
diagram, describing a very important event, that of creating a connection to our data source.
251
Chapter 8
Since this is a fairly straightforward example, we will walk through the code associated with this activity
diagram :
End Sub
252
Design Phase: Physical Stage
Even for a simple module such as this, it is much easier to understand the flow of the code and what is
going on in the code by looking at the activity diagram. This diagram can lead to discussions on the design.
To begin with, why do we need a special method to set the ADO connection? From our discussion on the
last chapter on ADO connection objects we know that these objects are pooled. We said that we wanted to
use them and then throw them back in the pool. This means that we will be opening our connection, using it
closing, and then opening it again, etc. Thus, every time we need to connect we will need to open a
Connection object. Because of connection object pooling, we are not actually opening a connection but
taking an existing connection out of the pool.
We can also see there are a few properties that will need to be set on the connection object. One of these is
the cursor location. The cursor location can be on the server or on the client. A detailed discussion of these
is beyond the level of this book, but they both are used in different situations for different types of data
access. The activity diagram makes it clear that we need to set this property, and that we must find the best
setting for our particular project.
There will be variables for a private ADO connection object and a private customer
recordset variable in our server component.
These steps are very high-level. They do not really get into any discussion of the ADO or how the ADO
works. They are just a logical series of steps that we need to perform to get information from the database
and return it to the client. The next step is to determine exactly how we do each of these steps using ADO.
Following is a table of the steps required to perform the general tasks we listed above using ADO. These
are the specific steps our server component must perform to get a customer recordset and pass back a
disconnected recordset with the client information in it using ADO. Each step also includes the framework
that places this requirement on the system, so you can see where you might have found information on how
to perform this step.
253
Chapter 8
Framework that
Activity Requirement
requires this activity
Create ADO connection ADO Framework You must make a connection to the
database by either creating a
Connection object prior to retrieving
data or passing in a connection string in the
open method of the recordset.
Three-Tier framework No information can be stored from one call
to the next. Therefore a Connection
object must be created first for every
request to get information to the data
If there is an error getting ADO Framework All errors must be handled
the connection, raise an
error and end
If there is no error, initialize Three-Tier framework No information can be stored from one
the customer recordset Call to the next; must initialize Recordset
object for each request
Set customer recordset ADO/RDS framework Updateable disconnected recordsets are
cursor location to the client required; these recordsets need a cursor
location to be on the client
Set customer recordset ADO framework If a recordset is going to retrieve data from
source equal to the the database, there must be a Query string
appropriate query string that specifies what information from which
tables will be retrieved (a query string is
not required if you accessing a stored
procedure).
Set customers recordset ADO framework To connect a recordset variable to a
connection database you must set the recordset
variable’s connection property to a valid
connection string.
If there is an error getting ADO Framework All errors must be handled
the connection, raise an
error and end
254
Design Phase: Physical Stage
Framework that
Activity Requirement
requires this activity
If there is no error, set ADO framework Must set LockType of a recordset
the customer recordset before retrieving data from the database
LockType to the (not required for the default optimistic
appropriate lock type lock)
and set the Recordset's
Connection object to
the Connection
object.
Open the customer ADO framework Must open a recordset to retrieve the
recordset object requirement data into the recordset
If there is an error ADO framework All errors must be handled
opening the recordset, requirement
raise an error
If there is no error, Three-Tier Return disconnected recordsets
return the recordset framework
Close the ADO recordset ADO framework Failing to close the Connection
and set the recordset and object leaves it open until it times out.
Connection object to There is a limited number of
nothing. Connection objects, so letting them
close by timing out ties up valuable
resources.
This table says a great deal about programming in Visual Basic. To make this chart, I had to understand
three frameworks (RDS, ADO and Three-Tier). Programming Visual Basic goes beyond knowing just the
language syntax. To make Visual Basic projects, we now have to understand the frameworks that our
projects are going to work under. We therefore need to do the following:
255
Chapter 8
From this table, we can now draw out our activity diagram. Each activity in the chart above will map to
some element of the activity diagram:
256
Design Phase: Physical Stage
The simultaneous flows that have arisen due to the possibility of errors will come back together at the thick
horizontal bar or concurrent join. Of course, as with any activity diagram, the ending point must be shown.
If we were to create a similar diagram for Retrieve Product, it would look very similar.
257
Chapter 8
If the transaction was successful we call SetComplete, and the changes will be committed. If for any
reason an error occurred (such as conflicting records being found) then we need to call SetAbort and all
changes will be rolled back:
Of course, the Reconcile step is a whole complicated activity diagram on its own. Also the steps that would
occur when determining the type of recordset and preparing to send it back would be the focus of yet
another activity diagram. As I said, not a simple process.
Listing all of the steps of each of our methods gives a clear, readable way of seeing everything your code
must do to perform this task. As such, an activity diagram provides a very useful learning tool. With an
activity diagram, a junior developer can go to a more senior developer and ask them “In this diagram, what
should I set the cursor property to and how should I raise the error?” Without the diagram, a junior
developer may not even know that they are supposed to set the cursor property to a value or that there is
any need to build a special error string. Activity diagrams make sure that all of the critical steps are
included in the code.
258
Design Phase: Physical Stage
Finding the best solution is usually an iterative process. First you have your initial concept, refine it, test it,
then you refine it more and test it more, etc. Activity diagrams will let us go through many refinements of
our object’s methods before we even write one line of code. Removing something from an activity diagram,
means deleting a graphic image. This takes about a second. Changing code means deleting lines of code that
may have taken hours to create and adjusting the rest of the code to deal with the deletion. Which one
would you rather do?
Effective Testing
We saw in the previous sections that, for example, Retrieve Recordset is a task that is required by nearly
every client component. Therefore the majority of the tasks the client will be performing will depend on
this task functioning correctly. Establishing an ADO connection is a key task performed by the server
object. Tasks that are essential to the entire system, such as these two tasks, should always be thoroughly
tested during the design phase. If either one of these tasks fails to work, or works inefficiently, the entire
project will fail.
With regard to retrieving recordsets from and updating recordsets to the server component, we will need to
answer these questions:
How efficiently will disconnected recordsets work for the Northwind order processing application? How
efficiently will they work for the web application?
Does RDS actually work? If so, how efficiently?
If RDS works, does it work efficiently enough for this system?
Can we quantify the benefits to our system derived from MTS?
The testing team should create small test projects to ensure that the chosen technology actually does
represent an effective solution for a particular system.
Security
When designing the security for your application, you have many choices. The basic four basic choices are:
component- based security, database-based security, MTS security and operating system-based security.
You can choose any of these security methods by themselves or you can use a combination of security
types.
MTS, database and system security are similar in that they require an administrator to physically add every
user into either a group or a role. Because NT system security information is placed in memory on the
server, there are limitations on the number of users that can be stored in this type of memory. These three
security types were designed prior to the Internet and are not designed to hold information on tens of
thousands of users.
259
Chapter 8
MTS security works on top of DCOM security. DCOM security can provide a high grain of security, that is,
it can limit access to a complete component such as a DLL. Often, one needs to limit security down to
particular parts of a component. For example, you may have an employee component, which has interfaces
that can be viewed by anyone within the corporation (such as name and department) and another interface
for payroll and personal information that is only available to the human resources and payroll department.
With DCOM, we can only create separate security by creating separate components. MTS, though, does
allow us to get down to a finer grain of security.
With MTS you can define roles for the users of your components. This will give us a much finer grain of
security. Each role can be allowed access to specific interfaces or methods. If you have designed your
application with UML and created use cases, you will have defined roles for your users. Based on these
roles associated with use cases we can determine the roles for our components, and what these roles are
allowed to do. Thus, building applications with UML and using MTS for role-based security go hand in
hand. For an excellent discussion of MTS security read Visual Basic 6 MTS Programming by Wrox press.
While DCOM and MTS provide excellent security models for intranet sites and internal distributed
applications, they do not provide a practical solution for large-scale web applications. If you are going to
need a way of keeping track of thousands of users, your best choice is using a directory service.
A directory service can hold information on each user, including their ID and their password. When
developing e-commerce web sites with Site Server, you can use Site Server membership directory to store
information. Information can be placed into the membership directory and retrieved from the directory
using LDAP (Lightweight Directory Access Protocol). Using the membership directory, we can keep track
of thousands of users. Based on the roles we define in our system, we will create different sets of users with
different access rights. Ideally, we will be able to tell programmatically what rights a user has, so we can
automate adding users to the directory instead of doing it manually. For example, on a web site we could
have three levels of membership, each with a different price and different type of access to the site. We can
place users into different roles depending on the type of site membership they pay for. This can be done
within our code and does not have to be done manually by an administrator. We can see that a directory
service will provide the ideal security solution for our large web sites. For more information on Site Servers
membership directory read Site Server 3.0 Personalization and Membership from Wrox press.
With Windows 2000, which is to be released sometime in mid 2000, the directory will be part of the
operating system. The active directory will allow you to identify both users and resources on the network
that can be managed at a single point. At this time there are no books out on the subject, but there certainly
will be many of them as we come close to the release of Windows 2000.
Component-based security places the responsibility of validating the user on the components we build. In a
data services component that does not maintain state, this type of security requires us to have a userID and
password as parameters of every method of the component. In this case, our component would need to have
code to actually check to see if the userID and password are valid for each method call. We could then
verify the userID and password against a directory.
260
Design Phase: Physical Stage
The userID and password can also be stored in a database or one can simply have regular security on the
database and check a user by trying to make a connection to the database. Any of these techniques will
work. Since the responsibility of validating users is now taken on by your component, it is important that
you code it carefully. This type of security is found in Internet applications and some 3-tier solutions that
have a stateless data services component. The Internet applications will usually use a directory. An Intranet
application using component security will probably also use either database security or operating system
security. If you use Remote Data Services, it is likely you will be using this type of security.
Regardless of the method you choose to use for security, your use cases can help you define roles for your
users. In the conceptual stage, we defined a set of roles for our users. These roles can form the basis of our
security. Our use cases also tell us what tasks each user is allowed to do.
Error Handling
By the end of the physical stage, you must have documented all of the error statements for your Visual
Basic application. The possible errors for your application can be found in the constraint business rules and
the alternative flows of the use cases.
Visual Basic allows you to use error numbers ranging from 512 to 32768. You should give each of your
components their own range of numbers. If each of your components has 100 possible user-defined errors,
this will allow you to make over 300 applications with no conflict of the error numbers. If you set a range
of numbers for each component, then you will know exactly which component raised an error when an error
occurs in your application. This will make debugging much easier, especially when there are dozens of
components that make up the application. For the situations where the same error message may be
presented in many different components, you should create a standard for the message, but each component
should have their own number assigned to this standard message.
Visual Basic now allows you to use resource files. Resource files are a great place to store error messages.
To use a resource file, you will need to add a method into your Visual Basic application to retrieve the
string associated with an error. Let us look at how this is done.
261
Chapter 8
In Visual Basic, go to the menu and select Add-Ins|Add-In Manager. The Add-in manager will come up.
Double click the VB 6 Resource Editor:
Click OK. Now you can edit resource files in Visual Basic. Go to the menu and select Tools|Resource
Editor to open up the resource editor.
262
Design Phase: Physical Stage
Click on the abc on the toolbar to open the string editor. You can assign each error number to a string that
gives a description of the error. It could look as follows:
Once you have created your error message strings, you must save them using the VB Resource Editor. The
.res file that is created can be shared by all of the components in your project. This .res file should be
made during the physical stage.
You can create a function that uses the LoadResString Visual Basic function to retrieve the correct
error string:
End Function
If the error number is not in the resource file, it will return the default unknown error message. Just to make
things a little easier for the Visual Basic programmer, we can make an enumerated type with the error
messages. This way the developer does not have to remember all of the error numbers. The enumerated type
would look as follows:
263
Chapter 8
These enumerated types should also be made in the physical stage. This type would look as follows to a
developer if they hit control-space bar and typed the letter e_ :
This makes it easy to find the correct error. I do realize this is a bit different than the way most error
messages are created. For the most part, developers start coding and as they find they need an error message
they add one to the list. This can lead to duplicate numbers and a lack of uniformity in the numbering and
content of the error messages.
By defining the errors in the physical stage and designing your technique of coding with activity diagrams
before the code is written, developers will know exactly where errors should be placed and which error
should be placed there. This is a much cleaner and easier way to code.
One final comment on error messages: try to word your error messages in a way that any user can
understand them and understand what has gone wrong. Try to build some intelligence into your applications
so that when an error occurs, not only does the user get an error message, but also suggestions on how they
may correct the error. Doing this will substantially reduce the number of help desk calls.
264
Design Phase: Physical Stage
Risk Assessment
Once the final design is put together, there will be risks associated with the choices that were made. Each of
these risks should be placed in the risk document so that they can be monitored. While risk assessment
should be part of every phase of a project, you will have the clearest understanding of the project’s risks at
the end of the physical stage. A careful review of all of the proposed risks should be done at this time.
The final interface design of all of your components is one of the final deliverables for the physical stage.
When all of your components have been designed and all of the issues, such as security and component
distribution have been resolved, the design of the project is complete.
Summary
The physical design stage will first focus on researching the best way to build the components defined in
the logical stage. Once the research is completed, you must weigh the options and choose the best solution
for each component. Once a solution is chosen, a way to implement that solution must be created and
documented.
The physical stage will focus around finding the best possible components for our system. Visual Basic has
a wide range of capabilities and can provide us with a wide range of solutions for our enterprise system.
When Visual Basic does not provide us with the solutions that we need, we can use other languages or third
party components. We can also use third party components when we want to save resources by not
reinventing the wheel.
By the end of the physical stage we have mapped out everything we need for our development phase. It is
like a play in which the entire script has been written. It is only a matter of the actors acting out their parts.
Just as a good actor can bring life to a good script, the skilled developer can take a good design and create a
powerful, efficient system.
265
Chapter 8
266
Development Phase
The development phase will focus on converting the design created in the physical stage into a working
application. This phase begins when the design has been frozen and locked into place. The key players in
this phase will be the developers and testers, but the entire team will have work to do in the phase. The two
most important activities will be building and testing the solution. This phase is complete when the first
release of the project is made.
It is impossible to give a detailed description here of the procedure for creating Visual Basic code from
UML activity and class diagrams. However, this can be found in Appendix B. Instead, we will cover some
of the issues facing developers in this phase and take an overview of the coding of our DNA application.
We will also look at the issue of code reusability, identifying patterns within code and seeing how we can
use these to help us write code - even to the extent of automating some code generation.
How we can identify patterns which will be repeated within our code
How we can use these patterns to cut development time and costs
An overview of coding the project
How we can automate code generation
Since this phase concentrates chiefly on writing code, the deliverables will be:
The final milestone for this phase will be the completion of all the source code, including the testing both
of each component individually and of the product as a whole.
The product manager will be responsible for keeping the client informed on the progress of the project, the
status of the schedule and costs, and an assessment of the current risks to the project. If there are any issues
the client has with the project, the product manager will act as the negotiator between the client and the
development team.
The component managers perform the same tasks as the project manager, within each component team.
They are responsible for managing the resources within their team and ensuring that the components written
by their team are completed on schedule. If personnel need to be reassigned within a component team, that
will be the responsibility of the component manager rather than the project manager.
The development team will be driving this phase of the project. They will be building and assembling the
components of the system. Development will have numerous deliverables as the code is built in stages from
components. These components, whether they are classes, complete business objects built from hierarchies
or completed user interfaces, must be thoroughly tested prior to being considered complete.
The testers will be testing the components that the development team is creating. As each component is
completed and tested, it will be added to the system and tested within the system. We will discuss the
different types of testing in the next chapter.
User education will be busy putting together documentation on the project, based on the design. Because
the design has been finalized by this phase, the educators are able write accurate support materials in the
knowledge that the system will work as designed. The educators could also be working on creating a web
site to support the new product, designing plans to educate the new users or even working with the users on
existing portions of the project.
Logistics will be working on procuring the physical components needed for the project and building the
required infrastructure for the project. They will work closely with the support groups and bring any issues
support may have back to the development team.
268
Development Phase
In the last chapter, we also saw that each component will need to consist of more than one class. For
example, as well as a clsCustomers class, which will represent an individual customer, we saw that we
will need a class to manage the customers: an object from which we will be able to create instances of our
customer object. Moreover, if we want to be able to group certain customers together (such as those who
spend more than $1,000 dollars a year), we will need yet another object to manage these different
collections of customers. We thus saw that we need a three-class system for our business components.
In the development phase, all this design work will be translated into Visual Basic source code. Code will
be written to implement all of the methods and properties exposed by our objects, which we identified in
the design phase. In other words, it is by this stage absolutely fixed what the application is going to do, but
there is still much leeway with regards to how it will perform those services.
The other major activity of this phase is testing. Each routine must be tested as it is written; then each
component must be tested as it is completed. Finally, the entire application must be thoroughly tested when
all of the code has been written. Bugs will be reported as they are found by the testers, and ranked
according to priority. When the code has been completed, the entire product will be beta-tested by end
users. This process of testing and debugging overlaps between the development and deployment stage, and
will be treated in more detail in the next chapter.
Most of this chapter will focus on the issues facing developers in this phase, but let's first take a quick look
at the most important task of the project and component managers: managing risks to the project and
ensuring that the project is completed to schedule and on budget.
Risk Management
Risk management is critically important in the development phase. Any risks that go unnoticed can result in
the project falling hopelessly behind schedule or over budget. A small problem that could easily be taken
care of in its initial stages can quickly snowball into a problem that can destroy an entire project. It is
amazing how a project that is properly planned and carefully designed can fall apart very quickly because
risks were not properly monitored. A problem that delays a critical task can cause this task to be delayed for
weeks. All of the tasks dependent on this critical task must now wait. If some of the dependent tasks are
also critical path tasks, then more tasks will wait. One critical task falling behind can cause a chain of
events that delay the entire project.
269
Chapter 9
It is the job of the project manager to watch the project and make sure that the risks are being managed
properly. It is the job of every single member of the team to document risks and make sure that they are
being dealt with. Every week, team members should be submitting a form listing all of the possible risks to
their project. Each team member can list risks to the goals they are trying to accomplish. The project
manager will then go through these reports from the team members and create a list of risks. Working with
team members, a ranking of the risks will be done.
It is likely that a risk will be reduced by the combined efforts of many members of the team, so it is also the
team's responsibility to eliminate the risks. The project and component managers should find solutions to
risks and divide the responsibility of eliminating the risk amongst the team members.
Another important role of the project manager is change control. If there is any need to make a change to
the plan after it is frozen, the component manager will assess the risks. The product manager will bring
these risk documents to the client and discuss the consequences of making a change. If the change is put
into effect, the project manager will make the necessary changes to the schedule and allocate resources to
compensate for this change.
The basic rule for naming variables is that all variable names should indicate what the
variable does, what the variable's type is and what the variable's scope is. It does not
matter what specific naming convention you use, as long as it meets this rule.
It is critical that you create standards for your project, as the code will be passed from the developers to the
testers. If the testers must spend days trying to understand each person's code, they will spend little time
testing. The code a Visual Basic team writes must be capable of being passed from one Visual Basic
developer to another and be understood within a reasonable time. The only way to accomplish this is by
using a set of standards, having a detailed design of the project and using deliverables that determine
exactly what has and what has not been done in the code. This can all be accomplished by the techniques
outlined in this book. Another very useful technique for ensuring that the code is standardized is to use
code reiviews.
Code Reviews
Code reviews serve many purposes. One can either review general techniques, such as how to code a
module, or review actual code. When reviewing techniques, activity diagrams can be used. A code review
can be used for the following:
270
Development Phase
Code reviews should never become personal. While I am promoting standards, I am not saying that each
person cannot write code in their own personal style. I am saying that a person's individual style should
work within the team's standards. Issues that need to be raised at a code review should be things that affect
the performance, readability and maintainability of the code. Issues that revolve around personal
preference, that have nothing to do with improving the code or working within the team's standards, should
not be included in code reviews.
An impartial moderator should oversee the review and make sure the review does not deteriorate into an
attack on the person who wrote the code. The moderator should make sure that comments are constructive
and geared towards making the code, and therefore the project, better. If there are mistakes in the code
someone writes, the code review should be a learning tool for this person.
In general, the developer or developers who wrote the code should walk through the code and explain the
function of the code and how it is supposed to work. The code is then reviewed by the reviewers. In
general, one should not try to fix problems during the review, only identify them. If there is time to discuss
solutions once all of the problems have been found, then solutions can also be discussed.
All suggestions for change should be logged. It is best to have someone taking notes and keeping a record
of all suggestions.
We made the comment in the last chapter that the client services component is not very reusable. The client
services component, which usually consists of the user interface, is very specific to each application. We
will therefore not examine this component in great detail; however, some guidelines for creating a user-
friendly user interface were given in Chapter 7.
271
Chapter 9
These business services objects are built so that they can provide the attributes of the managed object, such
as a customer or order object, by either using a recordset or the properties of the managed object. The
properties of the managed class are public. The recordset can only be accessed by binding a control, such as
a grid box or text box, to the managed object or to the managing object. This binding is done using Visual
Basic's new data source classes (which I call data provider classes, because they provide data).
Bottom Class
The bottom class, which represents objects such as customer, order or employee objects, has a public
interface that consists only of properties; these are the attributes of the object that we want to store. For a
Customer object, for example, we would find attributes such as Name, Address, City, etc. For this
application, we will connect to the Northwind database, so we will add a property for each of the fields of
the Customers table in that database. The class diagram looks as follows:
Notice that as well as the properties taken from the database, which we use to store the customer
information, we have three extra properties - EditMode, ItemsDataMember and ItemsRecordset -
and one friend method, ValidateFields.
For each of the properties, we need to write two routines - one for reading the value of the property
(Property Get) and one for setting it (Property Let). However, if the property contains an object
(rather than, say, a string or a numeric value), Visual Basic requires us to use Property Set instead of
Property Let.
Remember that we said that we would allow the attributes of the object to be accessed either through
properties or through a recordset? That means we need a property which contains a Recordset object.
The ItemsRecordset property holds an ADO recordset which contains this information. This recordset
has a field for each of our Customer object's properties, so when we want to read or set one of these
properties, we will actually access the appropriate field in this recordset. For example, the routine for
getting the value of the Address property looks like this:
272
Development Phase
The variable g_cstrFieldAddress is simply a constant (a variable whose value is set when the class is
initialized and cannot be changed) which is set to the name of the Address field in the database (i.e.
"Address"). The key line of this routine is therefore equivalent to:
Address = ItemsRecordset.Fields("Address")
So when the managing class attempts to read the value of the Address property, this routine will be
executed and the value of the Address field in ItemsRecordset will be returned. The managing class
can thus access the customer's address in two ways: by reading the property directly (that is, by calling
objCustomer.Address) or by accessing all the customer information by calling
objCustomer.ItemsRecordset. Similarly, when we wish to set the value of this property, we will set
the value of the appropriate field in ItemsRecordset:
AddressLetError:
Err.Raise Err.Number, "Address Let " & Err.Source, Err.Description
End Property
This code is considerably more complex than that for the corresponding Property Get because of the
need to ensure that we don't allow data conflicts if more than one user is accessing the same record. Firstly,
we check whether a change to the property is still being validated; if so, we abandon execution of this
routine. Then we check our EditMode property; this contains the value of an ADO constant which
indicates whether a record is currently being edited, or whether it is being added or deleted. We can use this
property to keep track of what operation is being performed, or to check whether a record is being edited by
another user. If the record to be changed is being edited or added to the recordset, then we set the field in
the recordset in order to set the property; otherwise, we raise an error.
The final property, ItemsDataMember, returns a reference to the set of data or 'data member' for the
object's attributes, in case the data source is exposing more than one set of data.
273
Chapter 9
The ValidateFields method is used to validate a field in our recordset. All of the validation of the
fields is done in the properties. However, we can change a field either by using a property or by using the
recordset, so we will also need a way to validate the fields when they have been changed using the
recordset. ValidateFields will be called any time a field changes using the recordset. Since the code to
validate a field is already in the properties, the ValidateFields method will pass the new field value
into the property.
Middle Class
As we noted earlier in the chapter, the middle class of each component will have an identical interface,
because the middle class is used not to store data but to manage instances of the bottom class. Each of these
objects will therefore require exactly the same functionality. In fact, almost the only difference in the
coding of these classes is that we will need a reference to the corresponding bottom class. We will need to
declare the reference in the General Declarations section of the code. For example,
clsCustomersManager will need a reference to clsCustomers:
Then, when the class is initialized, we will have to create an instance of the appropriate object:
The only other difference occurs when we use the Item property to return a specific instance of the class.
Since this property returns an instance of the managed object, it will have to be declared As
clsCustomers or As clsOrders, etc.:
With the exception of these three minor differences, the code will be identical (so long as we give the same
name to our managed object).
274
Development Phase
The methods and properties of this class are used mostly to retrieve a specific object of the bottom class, or
to obtain information about the collection as a whole; we have seen most of these, so we will just look at
those which we have not yet covered. Also, some of the properties are identical to those of the managed
objects, such as ItemsRecordset. This property returns the ItemsRecordset property for the current
managed object:
One consequence of using RDS is that we must create a 'proxy' of the server component in our middle-tier
object. That is, we must create an object which looks to our middle-tier object like the server component,
but will in fact only be a means for the two objects to communicate with each other. We need two methods
to handle this: the SetProxyInformation method will set up the information that the proxy needs.
Then, the GetProxy method will create the proxy object itself:
275
Chapter 9
There are two things to notice here: first we must create an instance of the RDS DataSpace object. Just as
we needed a managing object from which we could create our clsCustomers object, so we need an
object from which we can create our proxy server object; we can't just wish it out of thin air. The
DataSpace object fills this function.
The second point to note is that two parameters are passed into the DataSpace object's CreateObject
method (this is the function we use actually to create our proxy server object). The first is the ProgID of the
class we want to create: a string which identifies the sort of object of which we want to create an instance.
The second indicates the server on which the object itself exists. This can be in any of four formats:
HTTP (HyperText Transport Protocol, the usual format for transferring information over the Internet). In
this case the parameter will be an HTTP address, such as "http://www.northwind.com".
HTTPS (HTTP over Secure Sockets Layer - a secure form of HTTP). For example:
"https://www.northwind.com".
DCOM (Distributed COM, which works in a similar way to COM, but can operate over a network). The
parameter will be the name of the machine on which the server component resides, e.g.
"Northwind1".
In-process, which we use when the client-side and server-side components are on the same machine. In
this case, the parameter will be an empty string, as in the example above.
This illustrates the ease with which an RDS connection can be adapted to different circumstances, and
shows why RDS is a good choice for reusable components: all we have to do is change this one parameter,
and we can adapt a component used by our order entry application running over an intranet via DCOM to
run over the Internet via HTTP.
The UpdateManagedObjects method is called to update all of the components that are bound to the
object. This will happen any time the recordset changes, such as during a MoveNext or after an Edit or
AddNew has been saved.
Top Class
We will place the top class into a user control. This allows us to add the control to a form in the client
application; we consequently don't need to instantiate a separate component.
The top class will only have two methods, a Get... function to retrieve an instance of the corresponding
middle class and a ChangedManagedObjects method to refresh the bound controls when the recordset
changes. There is also one property, based on the primary key of the table. The class diagram for
ctlCustomers, for example, looks like this:
276
Development Phase
In addition to the object, each component will have a .bas module with a CreateErrorFunc for error
handling and various constants and enumerated types that will be needed for the component.
The following class diagram shows the methods for our clsServer class. Because our server component
contains only one class, there are no friend methods; all methods which are not public can be accessed only
by this class, so will be private:
For each of our middle-tier components, we will need two specific methods: a public
Return...Recordset method and a private Update...RS method. The class diagram above shows,
as examples of these, ReturnCustomersRecordset and UpdateCustomersRS methods; we would
also need a ReturnOrdersRecordset and an UpdateOrdersRS method, and so on. The
Return... methods are public, and can be called directly from our managing class to retrieve a recordset
for a specific object from the database. However, the Update... methods are private, because we have a
generic public UpdateRecordset method, which calls the appropriate specific function.
277
Chapter 9
Our decision to use MTS for transaction processing means that we must have some way of telling MTS
whether or not the operations within the transaction have succeeded. If all operations succeed, we can
'commit' the transaction: that is, we can tell the database that all the operations within the transaction can
actually be performed. We do this through an MTS object known as the ObjectContext object. Every
object running under MTS has an associated ObjectContext object, and it provides methods for
committing a transaction:
Similarly, we need to inform MTS if anything goes wrong and the transaction needs to be aborted or 'rolled
back', canceling all the operations within it. Again, we must use the ObjectContext object:
The other methods are used mostly for handling our ADO connection to the database: we have separate
methods for opening and closing the connection, and for retrieving an existing Connection object.
Extracting this functionality into separate methods avoids having to write the same code for each of the
Update... and Return... methods. We can just call the method whenever we need to open or close a
connection. These methods are all private, because only our server component may have direct access to the
database.
Building Visual Basic components from the ground up can be a daunting task. Even when the design is
created, everything documented, it still takes a long time actually to write and test the code. By reusing
code, one can substantially cut costs and time of development.
We can identify two general forms of code reuse. The first form is where we build a component and use the
same component in many different applications. An example of this would be building a product component
that can be used in an internet application, a Visual Basic EXE application and a Dynamic HTML
application. We will see an example of this in the next section.
The second form of reuse is where we identify a pattern, and reuse the same pattern (and coding techniques)
to build many different components. We will look at patterns in the next section.
278
Development Phase
Patterns
We saw in the previous chapters how sequence diagrams can help us to define the public interfaces for our
objects and to design a user-friendly GUI. Another great reason for creating sequence diagrams is that they
can help us identify patterns.
Patterns are becoming the hottest new idea in OOP. There is good reason for this. A pattern can provide us
with a basic blueprint that we can use to design our project.
Patterns can allow us to build our components in an assembly line manner. Patterns help a project stay
within time deadlines, keep costs down and significantly reduce the amount of coding that needs to be done.
Without a pattern telling us how to build our components, we will find ourselves asking questions such as,
“Will we build our customer object for the client as a single class or do we build it as a class hierarchy
from one, two or perhaps three classes?” Having a well-defined pattern, which shows exactly how we
should build a component, provides us with the answers to questions like these.
General Patterns
These apply to a general system and have nothing to do with choices of operating systems, programming
languages, or technologies. An example of this type of pattern would be a general pattern for making an
Order Entry application. Every order entry application will have certain features regardless of what you use
to build it. This type of pattern is useful because it can guide you in a general design of your project.
However, in this phase we're more concerned with specific patterns.
Specific Patterns
These can be used to build a particular component of a system, and they are dependent upon the system that
we're using. For example, if I were building a three-tier project, I might need to build dozens of client
components. It would be really helpful if I could find a pattern to build this type of component. I could then
reuse this pattern over and over again, to design and build all of my client components.
UML diagrams will not only provide us with the patterns that exist within our project's components, but
also show us how to code these objects. If we are fortunate, there will already be a coding solution for the
patterns we find in our UML diagrams. If there isn't already a pattern, we will need to create activity
diagrams in order to map out the coding solution.
Unfortunately, you see very little discussion of patterns in the Visual Basic literature, so there are very few
patterns for Visual Basic components. Visual Basic has only recently moved toward being object-oriented,
and I believe that many developers are still trying to write OO programs using non-OOP techniques. As the
Visual Basic community moves more toward using OOP techniques, I think they will also be jumping onto
the pattern bandwagon.
279
Chapter 9
There are many resources that can guide us in finding these patterns, but for the most part we will end up
designing the patterns for the individual components ourselves. This is especially true because many of the
frameworks are so new that there are often very few, if any, patterns created for the framework's
components. In addition, since these frameworks are new, they usually have not been thoroughly tested
either.
This means that before we use any framework we will have to first create our own patterns and thoroughly
test them. While this may sound difficult, it really is not.
These patterns can be found quite easily if we design our components with UML models. The patterns we
will use to design our project will be based on object-oriented principles, good coding techniques, and
sound project management.
If we are using the same internal system for all of our projects, then once we've designed and built the
internal components for the first time, we can reuse them for all of our projects based on this internal
system. By the same reasoning, once we've designed and coded our Enterprise patterns, in order to build
future Enterprise projects, we only need to be concerned with the user requirements and building the
external part of our project; the patterns will provide everything else.
If we take all of these patterns and put them together, we can build what can be considered our own Visual
Basic 6 Enterprise framework. This framework will have a set of rules that must be followed, and will
shape how we build the rest of our project, i.e. the external part built from the user requirements (and use
cases).
Creating entire frameworks to build a particular type of project is perhaps one of the most
efficient ways of building projects. Many companies and third-party software vendors are
working late hours trying to make frameworks like this for Visual Basic 6 Enterprise
projects.
We can think of this as building prefabricated houses. Every prefabricated house is built from a similar
structure, a basic framework that will underlie every house. This doesn't mean that the houses will all look
identical. Once we move beyond the basic framework, each house will have certain things added to make it
unique: landscaping, color arrangement, bathroom fixtures, carpeting, etc. While the framework of each
house is identical, we can place different things within this framework to make completely different houses.
280
Development Phase
When it comes to our Visual Basic projects, the idea is to make “prefabricated” projects. We make our
basic framework and then, based on the users' requirements and the needs of the particular project, we will
add the features to make the application unique.
Building the framework is usually the most difficult part of a project. From design to implementation, it can
take six months to a year. However, once these frameworks have been established, we don't have to worry
about things like making connections to databases. As long as we follow the rules of our Visual Basic
Enterprise framework, the framework will handle all of these things. We only need to be concerned with
adding features that are required by our project.
281
Chapter 9
If we were to look at the properties of these customer and product components, they would all seem very
different. A sequence diagram, though, only looks at the messages being passed back and forth, which
means that it only looks at the object's public methods. When we view these three objects' methods, we
see that they are all very similar. We can also see that the DB Business Logic component works in an
identical manner for all three objects. What does it mean when things have the same methods but different
properties?
To answer this question, let's step back for a moment and use cars for our next example. Each car is an
object with its own set of properties, but every car shares the same underlying functionality.
It might be worth just stopping and thinking about this for a moment. Every car has a unique set of
properties that helps us to identify them: color, shape, type of wheels, manufacturer, etc. Yet, even though
cars have different properties, they all perform pretty much the same activities: accelerating, braking,
turning corners, indicating at junctions, etc. Although every car has a different set of properties that makes
it unique, they all function in largely the same manner. We do not have to find a whole new way of making
a car each time we want to make a new, unique car. We can use the same technique to build a car whether it
is going to be red or metallic silver, four seats or two. Since the way every car works is essentially the
same, we only need one way to build an infinite number of unique cars. The way a car is put together
(wheels, steering wheel, lights, dashboard…) is a pattern. It is because of this pattern that we can use the
same technique to build an infinite number of unique cars (just look down your street).
282
Development Phase
Components work in the same way. Even though they may have different properties, they can still work in
exactly the same way. If we know how to design or build one of these objects, we know how to build all of
them. Once I figure out how to build my Customer object, I will also know how to build my order and
product objects, too. By building similar sequence diagrams from our Modify and Delete use cases, we will
find that these tasks are also alike for our Customer, Order and Product objects.
Interfaces
There's a lot of confusion about Visual Basic interfaces. A Visual Basic interface is a class with methods
and properties with no code. Another Visual Basic class can then implement this interface. The class that
implements an interface will get all of the methods and properties that are in the interface. These interfaces
allow you to have one standard set of methods and properties for a group of similar components.
For example, I could create an Animal interface that has a Move and a Sleep method. I could then
implement this interface into a Rabbit component. I would then have to write the code to make the
Rabbit object move or sleep the correct way for a rabbit when these methods are called. I could also make
a Cat component that implemented the Animal interface, and write the appropriate code for that object. If
I had an object built from the Animal interface, I could call the Move method and that object would
respond in the way that was appropriate; that is, the rabbit would jump and the cat would walk. This is a
form of polymorphism.
While this form of polymorphism could be useful in our current example (since we do want all of our
components to have the same methods), it will not offer us any advantage in actually coding our
components. Remember: an interface has no code within it, the classes that implement the interface must
write all of the code for the methods and properties in the interface. We are looking for a solution where we
can write code once, and reuse it for all of our components. Interfaces will not provide this type of solution.
While interfaces could apply here, they will greatly complicate the code and offer only a small
improvement in our coding solution. It is for this reason we will not discuss them any further.
283
Chapter 9
Object Hierarchies
The other option is to use an object hierarchy to build our
objects. The hierarchy would look something like the
following:
The hierarchy here is between the Managing Class and the Managed Class.
On the bottom of this hierarchy is a class that could contain the properties of the object (the Managed
Class). As all of these objects have different properties, this class will be completely different for each of
our objects.
Next up in the hierarchy, is a class that will manage the bottom class, which we will call the Managing
Class. This class will contain all of our client-side methods, such as Move to the Next Customer,
Add a New Product, Count Customers, Update Products, etc.
When considering this hierarchy, we discover one amazing fact: the Managing Class would be 99%
identical for every one of our objects! This is really something - a few hours of work talking to our users,
converting this information into use cases and sequence diagrams, has helped us find a pattern within our
system. Once we have the middle class coded, we can then build all of the rest of our client side objects by
simply making the upper and lower classes - which is a relatively easy task.
The Managing Class performs the same basic tasks for all of these objects.
We can see that our client components will have many methods that will be the same for all the
components. Using Visual Basic, we can build one of these client components, such as the Customer
component, and use it as a code template to build the other client components – such as the Order
component, the Product component, etc. When we look at the sequence diagrams for different components
and find patterns like this, we can turn these patterns into code templates. The relationship between patterns
and code templates is very similar to the relationship between a component and a class.
Without this ability to identify patterns, we would have been making these components separately… almost
certainly we have saved time and development funds by identifying patterns.
284
Development Phase
As we have seen, the managed class of an Employee and Customer component would be very different,
as each component would have a different set of properties. In general, we will find that any component
that we are building that is based on a managing class and a managed class will have a basic set of
functionality that will be identical in every component. Thus, we will find a pattern in all of our
components that have a managing class managing a collection of objects belonging to some managed class.
This form of code reuse allows one to build the foundation of your project using code generation. Code
generation is where the basic code for a project is generated based on a set of information. The information
to generate code can be UML class diagrams or a database. Once I define how to code a particular pattern, I
can reuse that code to generate code for any other component built from that pattern. Thus, if I find a way
to code my Customer component, I can use that method to also build my Employee, Order and Order
Details components. While we can do this manually (i.e. cut and paste code and rewrite the code for the
new components), we can also write Visual Basic code to generate the required code.
In this way, the basic components of our system can be generated with a Visual Basic code generation
project. While this may sound futuristic, it is not. The code for building a simple Visual Basic code
generator to create a DNA three-tier project is included in Appendix C. Whenever you find that you are
building components from a pattern, you should design and build a code generator. Once the generator is
built, the code that is generated can go through rigorous testing. Once the generated code has passed the
testing phase, future components should move through testing with a minimum of bugs. Ideally, once the
generator creates bug-free code, all future components built from the generator will be bug-free.
Realistically, there will always be one or two small things that will need to be adjusted. However, there will
be far less time debugging and cleaning the components from a tested code generator than if each
component is built from the ground up by developers.
Even if a pattern is found you will still have to write the initial code that will be used to generate future
components. Components that are reused in multiple applications will also have to be initially built. You
will also have components that cannot be built from either the first or second form of code reuse. In all of
these cases, you will have to build your component from the ground up. This will always be an expensive
process in terms of time and cost.
285
Chapter 9
If you have followed the rules of good design writing the actual code will be a matter of translating the
design into actual code. Providing you have performed thorough testing of your design by creating small
testing components, the majority of the hard work has been done. You will need to translate the UML
diagrams, in particular the sequence and class diagrams, to code.
Now that we have looked a little at code reuse with patterns, let's see how we can reuse components even in
a very different environment. We will take our Products component from a fat-client order entry
application and reuse it in a thin-client Internet application.
You could include files in your ASP pages for shared code, but this can be complicated. Another problem
with ASP pages is that they do not work as efficiently as a Visual Basic component. ASP pages do not have
typed variables so everything is a variant. In general, the more complicated the code is, the greater the
difference in performance between running the code in a Visual Basic component and running it in ASP
pages.
It is also easier to test and debug Visual Basic components. By writing your business logic into a Visual
Basic component, you can test the component using standard Visual Basic techniques. When you have
worked out all of the bugs in the code, you can integrate it with an ASP page.
The Products component was originally built for a Visual Basic EXE order entry application. The service
this component was to perform was to review, update and add product records by either using a recordset
bound to a control or by using properties of the object.
In our ASP application, we want a user to be able to submit a request to view all of the products of a
particular group. The information will be returned in a standard HTML table. This information is dynamic,
so the table must be made for each request.
We could build an ASP page that calls a Visual Basic component, which calls the Products component.
The Visual Basic component will then use this component to retrieve all of the products for all a particular
category.
286
Development Phase
In this scenario, we would not need the part of our Products component that binds to interface
components. We could though use the properties of our products component to get the information.
Thus, the products component can be used for our purposes.
Another possibility would be to create a stored procedure. For an application like this, a stored procedure
would be the usual choice, though it may not be the best choice. SQL Server 7.0 comes with a web wizard
that converts a recordset into an HTML page. With a few modifications, you could use this wizard to build
any HTML page you needed from the data. The problem with stored procedures is scalability. What if our
web site becomes very popular and we start having hundreds of requests a second? Eventually, our server
will reach a point where it will no longer be able to keep up with the requests to build web pages. Scaling
databases can be done, but it is difficult.
Let us go back to our original solution, where we had a Visual Basic web component being called from the
ASP page that called the products component. Let us place the Visual Basic web component and the
products component on the web server. As the demand for the site increases, you can create a web farm;
that is, you can use multiple identical web servers to share the load. Each web server will have the Visual
Basic web component and the products component on it. This solution will easily scale to be as large as
needed. Thus, using a Visual Basic component to build the HTML page makes sense. However, this still
does not justify using the Products component.
The Products component calls a server component that then requests the data from the database. Our
Visual Basic component could call the database directly and request the data from the database, or it could
also directly call the server component for the data. With regards to efficiency, it is possible that calling the
Products component, then calling the server component, which retrieves the data, is slightly slower than
calling the database directly. The actual difference will depend on the system and the load on the system.
There is one advantage, though, to using the Products component.
If, instead of having to create just one set of data, we had to write code to return hundreds of different data
sets, writing directly to the database would fill our Visual Basic web component with code to connect and
retrieve data from the database. We would need programmers who are experts in ADO and in using stored
procedures. We would also be mixing our business services logic with our data services logic. The code
could quickly become confusing and hard to maintain and upgrade. If there were a change in the database, it
would mean we would have to change our Visual Basic web component. Thus, using the Products
component means that the Visual Basic developer creating the component will not have to know anything
about ADO and, furthermore, the web component will not be affected by changes to the database. You
would have to perform tests comparing performance with and without the Products component to see if
the difference in performance is significant. It is very likely that under heavy loads the difference will be
very small between using the server component and directly connecting to the database.
Before I would make any decision, I would create small applications (prototypes) for all three methods
(using the Products component, calling the server component directly from the web component and
connecting directly to the database from the web component). I would then test each of the three solutions
under various loads. Based on the performance of each solution, I would make my final choice for the
project. Below we will show the code for the solution using the products component. The other two
solutions could be written by making minor changes to this application, i.e. by just changing how the data is
retrieved.
287
Chapter 9
It is likely that if we were going to use the Products component, we would probably not use our original
component. We only need to use the properties; all of the code for binding a recordset is excess code. In a
production environment, we would probably reuse all of the code from the products component that is
needed for the properties, and remove all of the code related to binding the recordset. Thus, we would reuse
the code and not the component. Because I want to show how to use a Visual Basic component from an
ASP page and not how to rewrite the Products component, I will only make a few modifications to the
Products component so that it will work with this project. We will begin our project with the page that
the user will use to make a request for product information.
The following sections will look quickly at the coding techniques involved in reusing
a component in a different environment. If you are not familiar with coding in
Visual Basic, you may find it advisable to skip to the section on 'The Future'
towards the end of the chapter.
288
Development Phase
When the user selects a category and clicks on the button, a request will be submitted to an ASP page
named GetProductsByCategory.asp in the same directory as the HTML page we just built. So, our
next task is to build this GetProductsByCategory.asp page.
</BODY>
</HTML>
The ASP code for this page is fairly simple. All this page does is call the Visual Basic component. There is
another very interesting thing to notice about this code. The method GetCategoryInformation takes
four parameters. The first two are the password and user ID, which are empty. The next two are the ASP
Response and Request objects. We are going to pass these into our Visual Basic component so that our
Visual Basic component can get all of the request information from the Request object. Our Visual Basic
component can send information back to the client using the Response object. First, though, let us look at
the Products component and see how we will have to modify it.
289
Chapter 9
Compile the new project with a new GUID (that is, with no version compatibility) into a new component.
290
Development Phase
Change the class name to clsWeb. Add the following code to the class:
Option Explicit
Private m_objContext As ObjectContext
Implements ObjectControl
We have implemented the ObjectControl interface so that our control can run under MTS. This means
we must implement all of the methods of the ObjectControl, so we need to add the following code to
the ObjectControl methods. When our object is instantiated, the ObjectControl_Activate event
will be fired. We can use this event to get a reference to the ObjectContext object:
When the object is destroyed, the ObjectControl_Deactivate event will be raised, and we must
destroy the ObjectContext object:
Finally, we will also have to implement the ObjectControl_CanBePooled function, although this
does not actually have any functionality at present. However, we may get an error if we don't implement the
entire ObjectControl interface:
We will use a custom function called CreateInstance to create our components. If the current
component is running under MTS, the CreateInstance function will use the MTS ObjectContext
object's CreateInstance function. Otherwise, we will use the New keyword:
End Function
291
Chapter 9
We will also create sub routines for SetComplete and SetAbort to commit or abort the transaction if
MTS is running:
This function will use the Products object to retrieve the data, so we will create the Products
component:
We can use the GetProductCollection method of this object to build a collection of products with the
ProductID that was passed into the function:
objProduct.GetProductCollection(e_ProductsCategoryID)
We will now build an HTML page to place this information into a table using the properties of the product
object. We will begin by building the header of the page:
292
Development Phase
We have hard coded the category options into the page as there are only a few of them and we did not build
a Category object in the VB6 UML book (though you can generate one with the code generator in a few
seconds). If there were only a few categories then it might save time to create an array of the product names
upon initialization to eliminate the need to look up the products every time. This array could then be looped
through in the code to get the category names. If a new category were added, only the code for initializing
the array would have to be changed. If the categories changed frequently, we would have to get the names
dynamically.
Now we will build the HTML table to put the product information in:
Then we set the CategoryID of the Product object and refresh the object:
objProduct.CategoryIDEquals = v_vCategoryID + 1
objProduct.GetProductCollection(e_ProductsCategoryID).Refresh
293
Chapter 9
With objProduct.GetProductCollection(e_ProductsCategoryID).Item
objProduct.GetProductCollection(e_ProductsCategoryID).MoveFirst
For lngProductCounter = 1 To _
objProduct.GetProductCollection(e_ProductsCategoryID).RecordCount
objProduct.GetProductCollection(e_ProductsCategoryID).MoveNext
strHTML = strHTML & "</TR>" & vbCrLf
Next
End With
strHTML = strHTML & " </TABLE> " & vbCrLf & "<BR>"
BuildProductsByCategoryTable = strHTML
End Function
We can also build another function that reads from the HTML page we initially created, with the combo
box with categories. In this case, we will need the ASP Request object so we can know which category
they selected. The code would look as follows:
294
Development Phase
v_oResponse.Write BuildProductsByCategoryTable(v_oRequest.QueryString("select1"))
End Sub
We can create an entire range of pages using Visual Basic. For example, we could create an error page as
follows:
There are many different options when it comes to building HTML pages. You could also store the HTML
as text in a database and create a component to retrieve and save the HTML pages. There would, however,
be extra overhead to connect to the database to get the HTML text. It is only through testing that you could
tell if this was a workable solution for your system. If the HTML pages were in the database, hackers could
not alter them. You would, though, have to create a staging area where your developers would first place
the pages for initial testing. Once the text was correct, they could be moved into the database.
295
Chapter 9
The process of moving pages could be automated. The only pages that could be accessed by a hacker would
be the ASP pages that call your Visual Basic components. Even these could be protected by placing the
ASP pages in a database and pushing the correct ASP pages out onto the web server periodically. If you
needed to make a change to the ASP pages, you would place the new ASP page into the database and when
the next push came the new version would go out onto the web server. In this way, no one would have
permission to change the ASP pages directly. If someone did find a way to hack into the system and change
the ASP pages, the hacked pages would automatically be replaced during the next refresh of the pages.
Unfortunately, we must take these things into consideration.
While ASP pages can be replaced without shutting the server down, the same is not true of Visual Basic
web classes. Because web classes are DLLs, they will require the web server to be stopped before you can
replace them. This is a serious limitation and one of the reasons why ASP is still a better option than web
classes.
Let us now turn to a different example where our products component can be used.
Using DHTML
Dynamic HTML is a great tool for the intranet. Unfortunately, Netscape Navigator 4.0 and Microsoft
Internet Explorer 4.0/5.0 differ considerably in their implementations of DHTML, so DHTML solutions are
not useful on the Internet (unless you do not mind creating solutions only for people with current releases
of one or the other major browser). On an intranet, you can control what browsers are on the client
machines and make sure that everyone has a DHTML-compliant machine.
In this example, we will again use the original Products component. We will create the same HTML
page with a combo box on it. In addition to the HTML code for the combo box, we will now also have
VBScript code in our HTML page. This VBScript code will use the Products component to retrieve the
products for the category selected and insert a table with those products into the HTML page. This means
that we will get the product information directly and rebuild the page without ever going to the web server.
This eliminates delay times and makes the web application run just like a Visual Basic EXE application.
<HTML>
<SCRIPT LANGUAGE=VBSCRIPT>
We will later place a list box onto the page. We will call that list box lstCategory. When that list box
has been clicked, we will want to place a table with the current products into our HTML page without
calling the web server. We will place our code into the OnPropertyChange event of the lstCategory
list box. Add this to your HTML page:
296
Development Phase
Sub lstCategory_OnPropertyChange
Dim strHTML
Dim strQuery
Dim lngProductCounter
Dim e_ProductsCategoryID
e_ProductsCategoryID=1
Notice that in VBScript all variables are late-binding variants. With DHTML, you do not create your
components with the New keyword. You will create the object in the HTML section of your code. The
HTML code later in the page will create an object called objProduct, which is a reference to the product
object. We will first initialize the product collection:
objProduct.GetProductCollection(e_ProductsCategoryID)
We want to place the name of the category selected above our product table. We can access the value of the
item selected in the listbox using the expression lstCategory.value.
Select Case lstCategory.value
Case 0
strHTML = strHTML & "<B> Beverages Category </B>" & "<BR>" & vbCrLf
Case 1
strHTML = strHTML & "<B> Condiments Category </B>" & "<BR>" & vbCrLf
Case 2
strHTML = strHTML & "<B> Confections Category </B>" & "<BR>" & vbCrLf
Case 3
strHTML = strHTML & "<B> Dairy Products Category </B>" & "<BR>" & vbCrLf
Case 4
strHTML = strHTML & "<B> Grains/Cereals Category </B>" & "<BR>" & vbCrLf
Case 5
strHTML = strHTML & "<B> Meat/Poultry Category </B>" & "<BR>" & vbCrLf
Case 6
strHTML = strHTML & "<B> Produce Category </B>" & "<BR>" & vbCrLf
Case 7
strHTML = strHTML & "<B> Seafood Category </B>" & "<BR>" & vbCrLf
End Select
297
Chapter 9
We need to set the CategoryIDEquals property of the Products component. The CategoryID field
is one-based, but lstCategory.value is zero-based, so we will have to add one first:
objProduct.CategoryIDEquals = lstCategory.value + 1
Next, we refresh the Products component and move through the items. You will notice this is the same
code we used in the Visual Basic web component:
objProduct.GetProductCollection(e_ProductsCategoryID).Refresh
With objProduct.GetProductCollection(e_ProductsCategoryID).Item
objProduct.GetProductCollection(e_ProductsCategoryID).MoveFirst
For lngProductCounter = 1 To _
objProduct.GetProductCollection(e_ProductsCategoryID).RecordCount
strHTML = strHTML & "<TR>"
strHTML = strHTML & "<TD align =" & Chr(34) & "center" & Chr(34) & ">"
strHTML = strHTML & .ProductName & "</TD>"
strHTML = strHTML & "<TD align =" & Chr(34) & "center" & Chr(34) & ">"
strHTML = strHTML & .QuantityPerUnit & "</TD>"
strHTML = strHTML & "<TD align =" & Chr(34) & "center" & Chr(34) & ">"
strHTML = strHTML & "$" & .UnitPrice & "</TD>"
strHTML = strHTML & "<TD align =" & Chr(34) & "center" & Chr(34) & ">"
strHTML = strHTML & .UnitsInStock & "</TD>"
strHTML = strHTML & "<TD align =" & Chr(34) & "center" & Chr(34) & ">"
objProduct.GetProductCollection(e_ProductsCategoryID).MoveNext
strHTML = strHTML & "</TR>" & vbCrLf
Next
End With
strHTML = strHTML & " </TABLE> " & vbCrLf & "<BR>"
We will use something that is called a <DIV> element. A <DIV> element is one of the most important
parts of a DHTML application. We can place a <DIV> element into our HTML code, and then we can insert
text between the element's opening and closing tags. We can also replace text between the <DIV> tags.
This allows you to add, remove or change sections of your HTML page using script code. In this case, we
are inserting strHTML, which contains our table in HTML format, into our <DIV> element, which we will
call "proddiv". The innerhtml property contains everything between the opening <DIV> tag and the
closing </DIV> tag, including any other HTML tags. Thus, using the innerhtml property, we can insert
text between the two tags.
document.all.tags("div").Item("proddiv").innerhtml=strHTML
End Sub
Finally, we have the closing </SCRIPT> tag, and we begin the regular HTML part of our HTML page:
</SCRIPT>
<HEAD>
<META NAME="GENERATOR" Content="Microsoft Visual Studio 6.0">
<TITLE></TITLE>
</HEAD>
<BODY>
298
Development Phase
To get a reference to our object, we will use an <OBJECT> element in our HTML page. The object tag has
a classid attribute, which must be set to the GUID of a public creatable class. Notice that there is the
word clsid included with the GUID. The id attribute gives the object a name that can be referenced in
code. CODEBASE gives us the location of the object if it is not on the client machine. You should create a
package called a Cab file to distribute your files through the Inter/Intranet. The Visual Basic Package and
Deployment wizard can make your Cab files for you (see Chapter 11). In this case, I have created a Cab file
called prjProducts.cab that is located in the same directory as this HTML file. The string
"1,0,0,0" is the version number. If there is a copy of prjProducts on the client and the version
number is higher or equal to this number, the file will not be downloaded. If there is no copy of
prjProducts on the computer or a copy with a lower version number, the file will be downloaded. We
have also set CategoryIDEquals to a default of 1.
<P><STRONG>Select A Category</STRONG>
<P></P>
<P>
<P>
<SELECT id=LstCategory name=lstCategory style="HEIGHT: 22px; WIDTH: 150px">
<OPTION Value="0" selected>Beverages Category</OPTION>
<OPTION Value="1" >Condiments Category</OPTION>
<OPTION Value="2" >Confections Category</OPTION>
<OPTION Value="3" >Dairy Products Category</OPTION>
<OPTION Value="4" >Grains/Cereals Category</OPTION>
<OPTION Value="5" >Meat/Poultry Category</OPTION>
<OPTION Value="6" >Produce Category</OPTION>
<OPTION Value="7" >Seafood Category</OPTION>
</SELECT></P>
<P><INPUT id=ChooseCatagory name=ChooseCatagory Onclick=ChooseCategory type=Button
value=Submit></P>
<P></P>
<INPUT id=text1 name=text1>
We will now put our <DIV> tag in. We are placing it below the listbox so we can insert the data directly
below the list box.
<div ID="proddiv">
</div>
</BODY>
</HTML>
There are many possibilities with DHTML. For example, you could bring over information in the form of
XML and use that data to create a dynamic application on the client that does not need to communicate to a
server. We have only had a glimpse of its potential for use with Visual Basic components.
299
Chapter 9
The Future
Looking at what we have discussed in this book leads us to ask a simple question: “What will be the best
way to develop our projects over the next few years?” There will be fundamental principles that will not
change in the near future. The basic concept of the logical three-tier model is not likely to change for some
time. Building components based on client, business and data services will form the foundation of our
object-oriented projects regardless of changes in technology, coding techniques and Visual Basic. Even
more importantly, building components based on these three services will shield us from the changes by
encapsulating the components of the system.
What we will find changing and becoming more fluid is where we place these components in the physical
three-tier model, that is whether these components belong on the client, middle tier server or database
server. Technology such as 64 processor NT machines and Windows 2000 with COM + (essentially the next
version of MTS) on workstation and server versions will completely rewrite where we place the various
components of our system. All assumptions must be assumed false. Never believe what is written or assume
that an old technique still applies until you have tested if for yourself and seen that it is really true.
Just because you should get maximum efficiency from one solution does not mean you will. The newer
technology may have made something else more efficient, or rendered a previously efficient solution
useless. The point is, writing testing applications during the development phase will become one of the
critical elements in creating an efficient system that fulfills the goals of the client.
This brings out another advantage of using patterns and the second form of code reuse. Imagine that your
team develops a set of five workable patterns for a DNA project. For each of the five patterns, you could
create a set of testing applications that will test the efficiency of each of the five solutions.
The testing applications could be based on a set of benchmarks that you create, such as the time taken to
retrieve or update a recordset or the response time with different numbers of simultaneous users. You can
place these testing applications in different arrangements on either the real system or a test system that
simulates the production system. You can run the test applications and see how each of the five solutions
performs in the real system. Based on these tests, you can determine which solution meets the needs of the
system. Using the code generators, you can then generate the framework of your code based on the best
solution.
Another vision I have of the future is the inclusion of UML diagrams with code samples. Every developer
can relate the story of spending hours stepping through a coding sample trying to figure out what it was
doing and how it worked. A simple sequence diagram can explain in a few minutes what could take hours or
days to understand by stepping through the code. I would like to see class diagrams and sequence diagrams
become a standard for code samples.
300
Development Phase
Of course, UML diagrams should also become an essential part of every project. Just as it can be very
frustrating to step through a code sample, it can be twice as frustrating to spend days trying to understand
someone else's code that you must upgrade or debug. A simple sequence diagram could save hours and even
days of work when code must pass from one developer to the next. I would hope that the future of Visual
Basic development will include the usage of UML and good documentation practices, as outlined in this
book.
These are a few of the things I believe will happen over the next few years. We need to reduce the risks of
our projects, reduce the amount of time to develop our projects and reduce the costs of our projects. Good
project management, proper documentation, a team that manages the project, documentation and managing
risks, the usage of UML to perform a thorough design of the system and testing of any assumptions with
testing applications will all help our Visual Basic projects meet these requirements. Part of my vision is that
through proper project management, Visual Basic projects will begin to reach a 100% success rate.
Summary
In the previous stage of the project, the final decisions were made as to what components will be used.
There were many decisions to make in this stage. Do you buy a third party component, reuse existing code
or write the code from the ground up? Is using a component the most logical choice or should you use
stored procedures? Often, questions can only be answered by creating test applications and finding what
solution fits within the parameters of the project. This chapter has shown how these choices can affect your
final coding in the development phase.
Visual Basic offers the developer many different ways of doing the same thing. Our Visual Basic order
entry application can be built as an EXE with the business and client services on the client machine, as an
EXE with the client services on the client and business services on the server (running under MTS or
without MTS), or we could make a DHTML application using components. We could also make DHTML
applications with XML or a regular Internet application. The choices can make you dizzy. Yet this is what
Microsoft Visual Basic is all about: choices. Because we have all of these options, we can choose the best
one for our project in the physical design stage.
If you choose to build your components, you have three choices: the first and second form of reuse or
building from the ground up. Code reuse in both forms is the best option as it will reduce costs and time.
When components are built from the ground up, UML diagrams provide an indispensable tool to allow you
to turn the goals of the user into Visual Basic code.
301
Chapter 9
302
Testing
This chapter will provide details of techniques - some general, some specific - for testing and debugging
Visual Basic components and products. The testing team can begin to implement some of these techniques
as early of the envisionment phase. By carrying out continuous and rigorous testing, with detailed
documentation, the team has the best chance of ensuring that the quality of the final product is high and that
it meets all requirements.
The testing that is carried out on the completed product during the "stabilization" stage,
leading to product release, is discussed in Chapter 11.
There are two broad categories of testing: usability testing and functional testing. Usability testing gives
the team an idea of how well their solution meets the users’ requirements and expectations. Of course,
usability testing is performed on the finished product, in order to ensure that it lives up to the expectations
of the business and users, but it should be a continuous process starting as early as the envisionment phase.
The testing team should create prototype applications to test user interfaces, different methodologies,
techniques or technologies and thus arrive at the most effective solution, within the constraints of budget,
time and the goals defined in the scope of the project cycle.
Functional testing is the testing of the components of the system, or the system as a whole, to make sure it
functions as it is supposed to. Any prototype built for usability testing should first go through functional
testing, in order to be sure that the poor performance is not due to a bug in the code. Functional testing will
therefore begin in the design phase and extend into the deployment phase (all of the components built in the
development phase must undergo functional testing).
We will look at both types of testing in this chapter and also discuss debugging MTS components.
Chapter 10
Usability Testing
Usability testing is a very important step in proper design of the project and one of the most often skipped
steps of design. I have seen entire projects run for over one year and reach the deployment phase before it is
realized that the design that was chosen would not work in the environment in which the application was
being deployed. One week of usability testing in the design phase would have found these problems and
saved a year of wasted development. Often, there are many possible ways to build a product. The only sure
way of finding the one that is best for your project is to build prototypes and usability test each solution.
For the most part, usability testing is divided into two subcategories. The first is testing how usable the user
interface is and the second is testing to find the best solution for the business or data services.
The developers and testers may also be involved in making the prototypes, and ensuring that they allow the
user to perform all necessary services. In order to do this, testers can go through the use cases and make
sure every use case can be performed with the user interface prototype. Testers must also make sure that
objects on the form and tasks that the forms perform are grouped according to the roles and the tasks
performed by people in those roles.
Screenshots of the interfaces can be passed amongst the entire team for suggestions for improvement. Just
as we suggested passing around activity diagrams to the entire team to find the best design, we can pass
screenshots around to find the best user interface design. You can also post screenshots on an Intranet or
build a web application with a user interface prototype and have the entire team (including the users) test
the interface.
There are specialized applications that create user interface prototypes or, alternatively, you can just use
Visual Basic. The important thing is to remember that a prototype is not the final application and may not
be put together in exactly the same way. For this reason, all of the code in the prototype should be
discarded and the final product GUI should be built from the ground up based on the best design found by
prototyping.
304
Testing
Should the business services go on the client machine or on the middle-tier server?
Should you use MTS on server components?
Does an existing component work efficiently enough or does it need to be redesigned for this
application?
The testing of business and data services will either be the testing of component solutions or the testing of
infrastructure. The component manager should oversee the component solution testing. Testing the
infrastructure is the responsibility of the logistician. Our first task is to identify the data and business
services that our application will have to perform, and then we can begin searching for the best way for our
application to perform these services. For each service, one should document the best way of fulfilling the
service. When there are multiple solutions, it is time to do usability testing.
Test Applications
Any development team that is developing more than a few products a year or is developing large enterprise
systems, should have a test lab available to test the latest technologies and coding solutions. Ideally, a lab
should not only have servers available for testing but also have a repository of information. Each test
application should be carefully documented with UML diagrams and text explaining what was tested and
what the outcome was. The final conclusions of the tests, such as what was the best way of doing something
and why, should be carefully documented. This will provide an invaluable source of information as
products evolve in later cycles or new products are designed.
Ideally, the lab should recreate the final production environment as closely as possible. The best situation is
to have the same servers and client machines in the lab as in the production environment. The tests should
be exhaustive and cover every possible real case scenario.
Test applications can either be structured or unstructured and we will have a brief look at each type.
Just as we should discard the user interface prototype, we should also discard our unstructured test
applications. These test applications are used to find the best solutions and are not intended for use in the
final applications. We can use activity diagrams to map out the best coding solutions, and document the
best technology, but, ultimately, we should not reuse these test applications.
305
Chapter 10
Creating test applications and exploring options are essential to the success of the project and should be
allotted adequate time in the project schedule. You should make a plan for usability testing just as you
would for any other part of the project. The weeks you spend finding the best solution, or proving a coding
solution, can prevent months of time that could be lost doing the wrong thing.
Functional Testing
Every component that will become part of your system, whether it is a precompiled third party component,
a Visual Basic class (or class hierarchy) should be thoroughly tested by itself (unit testing) and within the
system. Functional testing begins as soon as components are being built (including components for usability
testing). Such testing provides an essential monitor of a project’s progress and ensures that, at each step
along the way, all of the code modules can be successfully integrated. Functional testing and development
occur at the same time, with the testing continuing into the deployment phase.
We should start creating our testing plan in the logical design phase and have it completed by the physical
design stage. Complete documentation of the testing plan should be created. Testers should develop testing
modules and the development team should develop further modules in the development phase.
Let’s consider how we could functionally test our three-level class hierarchy that comprises our Customer
component in the Northwind project. We could write a sub-routine to test each of the three classes
separately, a module to test the middle and bottom classes together and a class to test all three classes
together.
To function properly, the bottom class (clsCustomer) requires a customer recordset, which is retrieved
from the database by the middle class (clsCustomerManager,) to be passed in. If we are to test the
bottom class separately, our test module will need to retrieve this recordset and then pass it into the bottom
class.
Often, when we are testing individual components, we will have to create values for variables that, under
normal operating conditions, would be passed into the component.
We may only know the exact values for these variables once the design is complete.
We should test the component with values that are within the boundary conditions of the variable, at
boundary conditions of the variable and outside the acceptable range for the variable. For example, our
variable might be the index for a 1-based array that has 10 members.
306
Testing
A one based array variable named strArray with ten members will have the following
members: strArray(1), strArray(2), strArray(3), strArray(4), strArray(5), strArray(6),
strArray(7), strArray(8), strArray(9), strArray(10).
Test performed outside the boundary conditions will ensure that we have proper error handling within our
code to handle these errors.
Coverage Testing: This type of test aims to thoroughly test each major feature of the project. Component
coverage testing (white box testing) follows every code path. System or product coverage testing (black box
testing) attempts to perform every service without knowing what code is being executed beneath the
surface.
Usage Testing: Usage testing is different than coverage testing in that you make each component perform
its services. As we said before, you will want to use boundary conditions and values within and out of the
range of acceptable values.
Compatibility Tests: These tests make sure that each component is compatible with the other components
of the project. As each component is added to other components, compatibility tests must be made to make
sure that all of the components work properly together.
Stress Tests: These tests place either the project or components under severe conditions. These are
commonly used for the middle tier data services components to see if they can handle the expected loads.
They are also commonly used with web components to see if they can handle the expected load of the web
server. You can write your own stress tests or, alternatively, there are many programs available that can
perform stress testing of your application.
Performance Tests: These tests will see how well a component performs critical tasks. These are
commonly used to see if a component will meet the required specifications.
There are other tests, but these are the most important for the Visual Basic development team. Tools such as
Radview, which comes with the Interdev Web solutions kit, are essential tools for planning web sites.
Testing with automated tools is sometimes useful. Creating your own customized tests may take some time,
but if they are carefully planned, they will give you the most accurate testing of your project.
307
Chapter 10
The ultimate goal of all this testing should always be to have no defects in the code. When designing our
application with use cases and business rules, we will have a clear set of guidelines as to how our
application is supposed to perform. A defect or bug is any system performance that is a deviation from the
design of the project. Our use cases should define not only how the system should operate when everything
is done correctly, but also how the system handles incorrect input. Any deviation from this is a bug.
Bug Tracking
There are many ways to find bugs. In addition to writing test modules, we can create special programs that
test our applications (these are often called test drivers). For example, when writing the code to generate the
HTML page for our Northwind project (see Chapter 9), I added a second Visual Basic project. Using this
project, I called the function to build product tables. I took the HTML code that was returned and put it into
a file with an .HTM file extension. I then opened the file with Explorer and viewed the HTML code in the
browser. If there were mistakes, I went back and made the corrections. I often test DLLs by adding an EXE
Visual Basic project and using this second project to test the first.
No matter how carefully you program there will always be bugs in your code. Using Option Explicit
at the beginning of all of your code modules makes sure all variables in a project have been properly
declared and is a good way of reducing typing errors. Declaring all of your variables and using variants
very sparingly will also help the compiler find type errors. In a large project, these two activities can save
countless hours of debugging.
Bugs that are trivial to fix, or bugs that are found and fixed during unit testing do not need to be
documented or tracked (unless it is an issue that may occur again, such as a bug in Visual Basic,
documented knowledge of which could help future development).
However, all non-trivial bugs found by the testing team should be carefully documented and tracked. A
non-trivial bug is one whose source is not readily identifiable. These bugs are usually found during
integration testing versus component testing. This tracking serves as a communication between the testers
and the developers. There are several good products on the market to help you track and prioritize bugs.
Three of them are PVCS Tracker by Microfocus (InterSolv), Track/TrackWeb by Soffront and Visual
Intercept by Elsinore. It is possible to create your own bug tracking documents but, when you have a large
project, use of a commercial bug-tracking tool probably represents a better solution.
In general, the following procedure should be followed for every nontrivial bug found by the testing team:
Create a Bug Report: A report on the bug should be made. This report should list the steps that are
needed to reproduce the bug, what should happen and what does happen, the severity of the bug (see
Chapter 11), the priority of the bug, the component the bug is in, and a name assigned to the bug.
308
Testing
Create a Plan to Resolve the Bug: Once the bug has been reported, you should create and document a
plan to fix the bug. It is possible that a certain reported bug was known about when the project was
designed and was considered minor enough to ignore. These bugs will be labeled as "By Design". There
may also be bugs reported that are actually minor enough to ignore and will be labeled "Will Not Fix".
Usually "Will Not Fix bugs" are ones that would require a large amount of time and money to repair and
will have little effect on the performance of the project. A minor bug that will be fixed when there is
time or in the next release will be called "Postponed". Labeling any bug as Will Not Fix, By Design or
Postponed should require the signature of the senior members of the team, usually the component
manager and the product manager. The stakeholder may also be informed of these decisions if it will
have any significant impact on functionality or performance. If the bug has been previously noted, it will
be labeled "Duplicate" and closed. If the bug cannot be reproduced, it is labeled "Cannot Reproduce".
For the most part, all non-trivial bugs should be taken care of as soon as they are discovered.
Repair the Bug: The developers must find the cause of the bug and repair it.
Retest the components when the bug is fixed: Once the bug has been fixed, the testers need to retest
the components to make sure that the repair did not affect another part of the code.
A bug found in a smaller component is usually easy to find. Testing done on assembled components tends
be more complicated and usually requires a standardized, careful method of debugging. There is often a lot
of work involved in debugging/testing components and it is often not possible to rely on just one method of
debugging. Some testing techniques might require test drivers etc. that have to be planned for and built.
This should be taken into account when estimating time and other resource requirements for component
testing.
Some of the most difficult components to debug are MTS components. For this reason, we are now going to
walk through some specific techniques for debugging MTS components. It will illustrate some of these
points and act as an illustration of how we debug assembled components in general. Hopefully, for those
not experienced with Visual Basic code, Chapter 8 will have given you a firm enough understanding of
ADO and MTS to follow through the code and gain some valuable insight into the complexities involved in
the debugging process. Of course, it will also give you some valuable code that you can use in your
projects.
If service pack 3 is installed, you can go to Help | About and you should see Service Pack
3 in the About box.
Let us take a look at an example that shows how this works. We are going to make a request for an ADO
recordset from a MTS middle tier component. As we want our MTS component to be stateless, we will
make this a disconnected recordset. This example will illustrate perfectly things do not always work in the
debugger as they do when the application is compiled.
309
Chapter 10
Begin by creating a new ActiveX DLL project. Add a reference to ADO 2.x. Name the project prjLog.
You should have one class, which you should name LogFile. In the properties of the class, set the
MTSTransactionMode property to 3-UsesTransaction. Save the class as Logging and the project as
prjLog. We are now ready to start adding code.
We want to see how the context object looks under the debugger, so we will definitively want a reference to
the object context.
As you may recall from Chapter 8, the context object can be thought of as a wrapper MTS
places around our components. The context object allows us to share security and a
transaction across several objects.
We will need to have a private variable that references the ObjectContext object. We will also
implement the ObjectControl interface. The ObjectControl interface will give us access to two
events associated with the object context: Activate and Deactivate. The ObjectControl will also
give us a property, CanBePooled, which we do not really need but will have to implement.
We must implement all of the methods and properties of an interface, even the ones
we may not need.
We will need to retrieve an ADO Connection object, so we will also need a private variable for it.
Finally we declare a constant that contains the path and filename of our database. Thus we have the
following declarations in our LogFile class:
Option Explicit
Don’t forget to add a reference to the Microsoft Transaction Server Type library. As we discussed
earlier, the ObjectControl interface will give us three events. Go to the Object drop down list box in
the code window, and select ObjectControl. You should now have the Activate event listed in the
Procedure list box. Add the following code to this event:
With this line of code we are setting a reference to the instance of the ObjectContext object that MTS
has automatically created for us. Our ADO Connection object, though, does not exist until we initialize
it. If we initialize it as soon as the component is created, there may be some amount of time before that
Connection object is actually used. As there are a limited number of connections that can be made to the
database, Connection objects are a valuable resource that we want to quickly use, and then destroy.
Thus, we do not want to initialise our ADO Connection object until we are ready to use it.
310
Testing
Go to the drop down Procedure window and select CanBePooled for the ObjectControl object.
We will need to fill out this code as all parts of the interface must be coded:
Finally, we want to deactivate our ADO Connection object as well as our ObjectContext object. We
should destroy our ADO connection as soon as we are done using it, but just in case we forget we include a
line of code to set the ADO connection to nothing. If it is already set to nothing, then no harm done. Better
to be cautious than take a chance that something is overlooked:
We will want to see how MTS works with and without an ObjectContext object. When there is an
ObjectContext object, we will want to use its CreateInstance method to create our objects. When
we use CreateInstance, MTS will create the new object within the ObjectContext object. Using
CreateInstance allows security and transactions to be shared over the different objects.
If for some reason something has gone wrong and we do not have an ObjectContext object, we would
still like our component to function so we can see how an MTS component works without an
ObjectContext object. Thus, we want the ability to create objects with the New keyword. Thus, we will
create a function called CreateInstance that will allow us to create objects under MTS. Using the
CreateInstance method when we do have an ObjectContext object, and the New keyword when we
do not have one.
We will need to pass in an identifier for the component we want to build. The ID for a Recordset object
is ADODB.Recordset, and for a Connection object it is ADODB.Connection. These will be the
only two objects we will be creating in our MTS component. Add the following code to your project:
Exit Function
CreateInstanceError:
311
Chapter 10
We now want to add three functions to open an ADO connection, close an ADO connection and finally one
to set a reference to the ADO connection. Let us begin with the function to set a reference to the ADO
connection, which I will call SetADOConnection. Each component - Customers, Orders etc. - will have
its own function for calling an ADO connection in the Server component so it makes sense to have one
routine which defines and opens the ADO connection, which each function can call (instead of having each
function opening connections individually). We will need parameters for the userID and the password in
order to make a connection to the database. We will also include an optional parameter for the connection
string in case we want to use something other than the default:
We would like some way of knowing when our variable value has been passed in. The IsMissing
function is used to tell if an optional parameter is passed but it only works with variants. As we have made
our v_sConnectionString a string, the IsMissing function will not work. Therefore, we have set a
default value of Empty for v_sConnectionString so we can know when it actually has a value passed
in. We will now put in our error handler:
Next we want to use our CreateInstance function to create our ADO connection:
With m_objADOConnection
.CursorLocation = adUseServer
If v_sConnectionString = "Empty" Then
.ConnectionString = "Provider=Microsoft.Jet.OLEDB.4.0;" & _
"Persist Security Info=False;Data Source=" & _
m_cstrDatabasePath
Else
.ConnectionString = v_sConnectionString
End If
.Open
End With
Exit Sub
312
Testing
The ADO has its own collection of errors, so we will loop through this error collection to get any errors in
this collection:
SetADOConnectionError:
End If
Err.Raise Err.Number, "SetADOConnection", strErrors
End Sub
We will create a function to retrieve an ADO connection. We will first make sure the function has been set
before we actually return a connection:
End If
End Function
Finally, we will close the connection. As an error would be raised if the connection were not open, we will
first check to see if the connection is open:
End With
End Sub
Now that we have everything set up to get a connection, we can retrieve a disconnected recordset. Let us
create a function called GetRecordset, which will return a Customer recordset from the Northwind
database:
313
Chapter 10
We will need a string variable to store the connection string, and a recordset variable to build the
disconnected recordset:
Next we will set the ADO connection, and set all of the properties of the recordset:
We will open the Recordset object, and disconnect it by setting the ActiveConnection to nothing:
ObjCustomersRS.Open
Set objCustomersRS.ActiveConnection = Nothing
CloseADOConnection
Exit Function
GetRecordsetError:
CloseADOConnection
Err.Raise Err.Number, Err.Source & " GetRecordset", Err.Description
End Function
The final part of our middle tier component will be a sub that will change the value of one of the fields of
the recordset:
Notice that we intend to pass in the parameter v_oCustomerRS by value (the actual value represented by the
variable), as we want to test if the recordset is really going to be passed in by value or by reference.
314
Testing
If a variable is passed into the middle tier by reference, then any changes to the
parameter v_oCustomerRS made here will also change the variable value on the
client. If we pass it in by value, any changes made on the middle tier will not affect
the values of the recordset on the client.
Add a reference to the ADO 2.x library, the Microsoft Transaction Server Type library and to the
prjLog project. Open up the code window for frmTest and put this in the declarations:
Option Explicit
Dim WithEvents m_oCustomerRS As ADODB.Recordset
315
Chapter 10
We have created a recordset with events so we can use the events associated with the recordset. The event
we are interested in is the WillChangeField event. If we pass this recordset into the middle tier object
by value, and the middle tier changes a field on the recordset, the field event should not be raised on the
client. If the recordset is passed in by reference, and we try to change a field value in the recordset on the
middle tier component, the field change event should be raised. Go to the Object drop down of the code
window, select m_oCustomerRS and type the following code into the WillChangeField event, by
way of notification if the event is raised:
Add a command button onto the form and call it cmdTest. Add the following code to the click event of the
button:
End Sub
316
Testing
Run the project and click the cmdTest button. When you get to the break point, step through the code
using the F8 key on your keyboard. This project runs even though we did not set up the package in MTS.
You should notice a few very strange things happen. To begin with, you should not have entered into the
ObjectControl event. You will not enter the middle tier component until you reach the Set
m_oCustomerRS = oLog.GetRecordset line of code.
This is why we did not get the ObjectControl events; there is no ObjectContext object. Thus, we
have found out something interesting about the Visual Basic debugger: If you do not register the component
in MTS, you do not have a reference to the ObjectContext object.
Keep stepping through the code until you reach the point where the client calls the ChangeRecordset
sub of the middle tier component. In theory, when we call the ChangeRecordset sub, and the sub
changes the value of the field, the FieldChanged event of the recordset on the client should not be
raised. Step through the code and you will discover that the FieldChanged event is raised. This means
that the parameter has not been passed by value, but actually by reference.
317
Chapter 10
The reason this happens is not important, it has to do with the properties of the ADO recordset. What is
important to realize is that very strange things happen in the debug environment that will probably not
happen with the final, compiled DLL. In this case, a by value parameter became by reference and we did
not get an ObjectContext object for our MTS component. If you were not careful, you may think the
problem is with your code, and not with the debugger. This in turn could result in hours of wasted testing
and rewriting of your code.
This perfectly illustrates the point we made earlier: we need to have several methods of debugging to test
our components. The Visual Basic IDE is great for finding errors cause by typos, improper logic (setting the
wrong path to the database, not initialising an object, etc.). Yet, it is not our definitive test, as things may
behave very differently in the compiled component than in the Visual Basic IDE.
Now run your project again. You will notice that nothing has changed, we are still referencing the ADO
recordset by reference and we are still not getting an ObjectContext object. What is wrong here? The
answer to this question is simple: we are running the client and server components together. When we do
this, we will never get an ObjectContext object, nor will our by value ADO objects be by value.
318
Testing
Click OK. Open another instance of the Visual Basic IDE, open the prjTest project. Put the break point
in the cmdTest click event again. Run prjTest, click the command button and step through the code.
This time you will find that your ADO recordset is actually passed in by value (the FieldChanged event
on the client will not be raised when you change the field). You may not actually enter the
ObjectControl events, but when you go into the CreateInstance function you can check and you
will see that m_objContext is no longer Nothing.
Thus, we have discovered that to properly debug our MTS component using the Visual Basic IDE we need
to run our client and server component in two different instances of the Visual Basic IDE, and the
component needs to be registered in MTS. Once we do this, we can actually get the behaviour we expect.
319
Chapter 10
You can play around with the code here. You will something very interesting: now that the parameter is
behaving properly, that is, it is now being passed by value, Visual Basic still allows you to change the
values of the parameter in the sub. These changes, though, are not passed back to the client.
By the way, if you are wondering why we are concerned with using by reference parameters versus using by
value parameters, remember that the communication between the client and server is over the network. This
means that every change you make to a by reference parameter on the server needs to be passed back to the
client. This is not very efficient and limits the scalability of your MTS component. Let us now take a look
at some other ways of debugging our component.
If a database is available, such as SQL Server 7, and is legally available (has the proper licensing), it is
usually the best option for testing. Test information can be placed into the database. Specialized
applications can be written to analyse the data, and these applications can be run from anywhere on the
network. This allows everyone from management to development to see the results of the tests. It is
possible that something could go wrong, and your component may not be able to write to the database. In
this case, you should write to a text file so the information on why this happened is not lost.
Writing to the event log is a good choice for when the final application is rolled out. The event log can keep
track of errors, or provide information on how your component is functioning. The major problem with the
event log is that someone needs to be looking into the log to find an error. As this may be forgotten, or not
done at all, it is advisable to have an additional function that would send an alert to a system administrator.
This can be accomplished by creating a function that will e-mail the system administrator, or send a
message through the Internet to the system administrator’s beeper. Building these components goes beyond
the level of this text, but I will show you how to make a function to write to the event log.
We will expand our existing class so that it has the ability to write to a database, a text file and the event
log. We will begin by creating a database that will allow us to log information from our MTS component.
320
Testing
Create a table in a database called ApplicationLog with the following fields and data types:
Create a second table called ErrorLog with the same fields. Call the database log.
Declarations
We will now add an enumerated type to our declaration for the different types of error levels we may have.
The standard levels for the event log are Informational, Warning and Error and we will use these
for our enumerated type. We will also make private constants for all of the field names. We will add a
constant for the path to the database, for example C:\log.mdb:
Now, let us add a function called WriteToDatabase to log information to the database. We will need to
pass in as parameters the name of the application that has requested this log, the name of the class (module,
form etc.) that has made the log, the name of the method or property that has made the log, the actual
message, and the level of error:
321
Chapter 10
We will need a local Recordset object to get a reference to the table we need in the logging database and
we need to include our usual error handler:
We will call SetADOConnection and we will not need to pass the path in as we will use the default path:
If the level is informational, we will put in the ApplicationLog table. Otherwise, the log is an error and
will go into the ErrorLog table:
We will set the ActiveConnection of the recordset next, and then open it. Once the recordset is open,
we can call an AddNew method:
Next we will set all of the fields to the values that have been passed in. In a final production version, you
would probably want to make sure the parameters have actual values passed in:
recLogRS.Fields(m_cApplicationField) = v_sAppName
recLogRS.Fields(m_cClassField) = v_sClass
recLogRS.Fields(m_cDateField) = Now
recLogRS.Fields(m_cLevelField) = v_eLevel
recLogRS.Fields(m_cMessageField) = v_sMessage
recLogRS.Fields(m_cMethodPropertyField) = v_sMethodProperty
Finally we update our recordset, exit our function and close the connection:
recLogRS.Update
ExitWriteToDatabase:
CloseADOConnection
Exit Function
WriteToDatabaseError:
322
Testing
In our error handler, we will set the return value of our function to a string showing the errors. This
information can then be written to a text file. You could also write to a text file in the error handler:
Err.Clear
GoTo ExitWriteToDatabase
End Function
We will create a text file that has fields of a uniform length so it will be easier to read the text file with an
application. To do this, we will create string fields for each of the parameters. We will also need a file
number for the log file we are about to open:
Notice that we have made the fields the same size as they are in the database. We will now set the local
strings equal to the parameters that were passed in:
strLevel = str(v_eLevel)
strAppName = v_sAppName
strClass = v_sClass
strMethodProperty = v_sMethodProperty
strMessage = v_sMessage
323
Chapter 10
We will now use the standard text file methods. We will get a file number using FreeFile. If it is
Informational, we will write to a log file, otherwise we will write to an error file:
intFileNumber = FreeFile
If v_eLevel = Informational Then
Open "c:\" & v_sAppName & "Log.txt" For Append As #intFileNumber
Write #intFileNumber, intFileNumber & Chr(34) & _
strAppName & Chr(34) & _
strClass & Chr(34) & _
strMethodProperty & Chr(34) & _
strMessage
Else
strLevel = Str(v_eLevel)
Open "c:\" & v_sAppName & "ErrLog.txt" For Append As _
#intFileNumber
Write #intFileNumber, intFileNumber & Chr(34) & _
strAppName & Chr(34) & _
strClass & Chr(34) & _
strMethodProperty & Chr(34) & _
strMessage & Chr(34) & _
strLevel
End If
Close #intFileNumber
End Function
We have not put any error handling in this function, for a final production version you should do this. In
this case, it is likely you would raise an error back to the calling application.
If App.LogMode is vbLogAuto or vbLogToNT then we are logging to the event log in NT. If we are in
Windows 95 or 98, we will log to a text file:
End Sub
324
Testing
We will now modify some of our previous functions and procedures so that we have a log of any critical
errors, such as failing to retrieve an ADO connection.
Exit Function
CreateInstanceError:
With m_objADOConnection
.CursorLocation = adUseServer
If v_sConnectionString = "Empty" Then
.ConnectionString = "Provider=Microsoft.Jet.OLEDB.4.0;" & _
Persist Security Info=False;Data Source=" & m_cstrDatabasePath
Else
.ConnectionString = v_sConnectionString
End If
.Open
End With
Continued on following page.
325
Chapter 10
Exit Sub
SetADOConnectionError:
End If
WriteToTextFile App.EXEName, "LogFile", "SetADOConnection", _
"Connection Failed", Informational
End Sub
Now, go to frmTest and add another command button called cmdTest2. In the click event for
cmdTest2 add the following code:
End Sub
You will notice something rather interesting about this code. Our MTS object is created and held open until
the end of the sub. This means we are holding our server component for a long time, and also maintaining
state across many calls. This will not scale, and is not how we should build our components. A better way
to code this would be as follows:
326
Testing
This is still not too readable, though. It would be best to make a log object for each situation: oLogText,
oLogDatabase etc. If you are concerned about the work to create the MTS component, MTS will not
completely destroy the object when you set it to nothing. It will keep a copy around for the next call, so you
are not losing any performance by doing this.
Before you can run this, you will need to
remove your component from the MTS
package:
327
Chapter 10
Next recompile the DLL and then add the DLL back into MTS. You will not need to make any changes in
prjTest as you are adding to the interface and you set binary compatibility (which means that the
component will recompile with the same GUID).
As a final comment, you may find that the event log will not work when you debug your component. But,
when you compile the component, it will work fine. Once again, things do not always work the same in the
debugger as they do in the compiled component.
Conclusion
Testing is an essential part of creating a successful Visual Basic project. Testing begins in the design phase
as you build prototypes to find the best way to build your project. Testing continues in the development
phase as individual components are tested. In the deployment phase the finished system is beta tested.
There are many different types of testing and many aspects of testing. Smaller problems discovered while
testing individual components can usually be fixed quickly without documentation. More complex bugs
found during beta testing may require thorough documentation and testing to reveal their causes.
The most essential parts of testing are good coding standards, accurate documentation and a means for
excellent communication between team members, including the end users. With these in place, your testing
should go smoothly, and it should be easy to find and fix bugs.
328
Testing
329
Chapter 10
330
Deployment Phase
The deployment phase is where the completed components are deployed. During this phase, the system will
be prepared for handover to the end users. Up to this phase, the focus has been on building the components
and making sure that the functionality is according to specifications. At this point, the coding and
components are complete, but they still need to be prepared for giving to the user. Testing in the final
environment, including Beta testing, can occur at this time. The end users must be shown how to use the
new application before it goes live. The infrastructure must be in place and the compiled Visual Basic
project must be placed on this infrastructure. The documentation for the project must also be completed and
given to the users. The final performance of the system must also be determined. The whole team will be
heavily involved in the process of deploying the project. The main aim of this phase is to release the system
to the users, making sure that all components function accordingly and that users have the backup of good
support, should they need it. The end result of this phase is that the system goes live.
The component manager continues to manage the schedule, create status reports and oversee debugging of
the components. If new risks for the project present themselves, the appropriate team members will report
them to the team leaders; the component manager will manage them and balance resources so that the
schedule is met and costs stay within budget.
The developers will work closely with testers and the users to identify flaws or bugs in the project, and fix
them. Logistics will also be involved, helping to deploy the components, prepare the infrastructure and set
up the data stores. Any conflicts between the users and the development team will be handled by the
educators. If the educators cannot resolve the issue, the product manager will resolve the issue with the
stakeholders. If beta testing is done, logistics will prepare the infrastructure required for the beta test. The
educator will find the appropriate testers.
The educators will complete all of the documentation for the user. The documentation will include all help
and support files. If a web page is to be used for documenting the application, the educators need to get the
page completed and live at this time. The educators will also perform training based on a training plan
developed in the design phase.
The entire team, including the client, must work together to deploy the project. Good communication will
be essential. The deployment phase is one of the most hectic times of the project. This phase requires
constant adjustments to the schedule and a reassignment of resources to deal with serious bugs. If good
design is used, as well as many components that have already been thoroughly tested, there should be a
minimum of bugs and the adjustments to the schedule should be minimal.
You have to be very careful during the final deployment phase. As the pace picks up, and the need to fix
bugs becomes more urgent, there is a tendency to forget formal procedures and to just start making fixes.
There is no better way to destroy Visual Basic code than to perform haphazard fixes. Of course, there are
many other issues in the deployment phase, as we shall now see.
332
Deployment Phase
It is important also to communicate this schedule to the end users - although they may only be concerned
with getting their new system, it must be explained that testing still has to be done and some repairs will
have to be made before the system is of a satisfactory level. The system also has to be prepared for
deployment, an issue that I will talk more about later.
Beta Testing
Beta testing will involve the testing of the completed system in the production environment by a limited
number of people before the final 'usable' version is handed over to the end users. While the key players
will be the testers, logisticians and the educators, beta testing will involve the entire team. The educators
will meet with the users who will do the beta testing, prepare and train the testers on the new system and
help choose appropriate users. The logisticians will be involved in installing the new system. Part of the
beta testing may be to see if the software is successfully installed onto the servers and the beta tester's
computers. The testers will monitor the end users and, with the educators, document the end users'
comments.
One part of beta testing is usability testing. Usability testing is the process of making certain that the
system is usable by the end users. Testers and educators should find out what is confusing to the users, and
if there are ways of solving these problems without changing the system. If there are problems with how
usable the system is that may require a change to the system, these problems will be evaluated and go
through change control.
Every change should be carefully evaluated. Even the smallest changes can require a
large amount of resources.
Depending on the cost of making the change and the urgency of the change, a decision will be made by the
stakeholder, product, project and component managers whether or not to make a usability change.
Hopefully, with good user interface prototyping there should not be any usability issues.
Communication is one of the most important parts of a successful beta test. Communication should flow
between all team members in this phase. A clear set of tasks for the end users should be developed and be
part of the testing plan. Testing may also include automated testing, using testing modules and performing
stress tests. Feedback will be essential, and there should be a simple communication system, such as email,
intranet or verbal, in place to allow information to flow through the team.
333
Chapter 11
The system is ready for beta testing when it is stable and the testers have tested the entire system. A beta
test should have a plan and be documented.
Beta testing allows the whole system to be tested from the viewpoint of a user, rather than a developer. If
there are any bugs, or errors, or missing functionality, these can be reported, the system can be refined, and
there is a greater likelihood of the system actually representing what the end users expect of it.
Finding bugs during testing should not be difficult if your tests are done properly. Each test should only test
one part of your project. In this way, you can find where the problem comes from. This is why we start by
testing each component separately. We also test each time we add a component to the system. This helps us
limit the places where bugs can be. Unfortunately, when bugs are found in the finished application, it can
be difficult to pin down their exact location. If clicking a command button causes an error, did the error
come from the command button, the business services component, the data services component or
somewhere else? Fortunately, this dilemma can easily be solved by using proper error handling.
Some of the most difficult problems are the ones where something worked perfectly in the testing
environment but did not work properly in the production environment. Commonly, these are performance
related issues. When the system is actually deployed and used by a multitude of users in different ways, we
often find that the system does not perform as expected. The worst situations are where the problems are
hard to reproduce. A common example is where some service of the system, such as retrieving data, will
normally occur within a second, but occasionally it will take ten or fifteen seconds. Trying to recreate this
can be very difficult. Sometimes a component will work flawlessly a certain number of times, but it will
fail once in a while. These are all very difficult problems to track down. These are all reasons that Beta
testing the components in the production environment is critical.
Every property, function and sub should have error handling. The most important part of your error
handling is including the name of the module in the err.raise statement. This would look as follows:
If you had a class named clsServer and a module called RetrieveCustomer you would have:
If you place this code in an error handler for every single code module, then when an error is raised the
place where the error was initially raised will be in the error string. What will also be in the error message
is the name of every code module that the error was passed through. Thus, if frmMain has a command
button called cmdGetCustomer that calls a method called GetCustomer in a business component called
clsCustomer, and there is an error in GetCustomer, our error source would include the following
information:
FrmMain.cmdGetCustomer clsCustomer.GetCustomer
334
Deployment Phase
Thus, we know where the error occurred and what the calling module is. This information can save you
hours and hours of searching to find the source of a bug. Placing error handling in every code module does
not take much time and it can save you days of frustration.
Ranking Bugs
Bugs can be a serious problem with any application. If an application has already been deployed and is
being used by the client, any serious bugs must be taken care of immediately. If the deadline for deploying
the application is quickly approaching, it will also be necessary to begin working on the high priority bugs.
Bugs can be ranked two ways. The first way is by how severe the bug is. The second is how reproducible
the bug is. Severity can be ranked as follows:
Level 4: Cosmetic:
A level 4 is where one or more users do not like the way something looks, but it in no way affects
performance.
Level 1 and 2 must be taken care of immediately. They are severe. They can be difficult to debug if the
problem does not exist in the test environment and does exist in the production environment as you usually
will not have any error messages before the system fails. In this case, you will have to create logs to track
the bug. A thorough testing phase should catch any level 1 or 2 bugs, but sometimes components perform
differently in the production environment than in the development environment. This is one reason that a
beta test should be done before a critical application is installed into an entire corporation. If the application
is critical for business, and there is a major bug that prevents the application from running, the corporation
can lose a great deal of money.
Even level 3 bugs sometimes can be a serious problem. Imagine building a Visual Basic component that
bills credit cards for an E-Commerce site. What happens if this component has a bug such that the
component does not actually bill the card; it only appears to bill the card. Thousands of dollars of business
may occur and thousands of orders may go out before anyone realizes that the company has been giving out
free merchandise. This can happen a lot easier than you would imagine. It might be that testing was done
with dummy credit card numbers, as you would not want to really charge your credit card when you are
testing. These are real issues and this is why beta testing in the production environment is important.
335
Chapter 11
Some level 3 bugs may not be serious enough to fix in this release. Most level 4 bugs will not be fixed,
unless they are very easy to fix. Reproducibility is broken into three categories:
Category 1: Completely Reproducible Simple - The bug can be reproduced every time by following a set of
simple steps. Usually, the user would normally perform these steps. It is possible this bug only occurs on
one type of computer.
Category 2: Completely Reproducible Complex - This is a bug that can be reproduced, but it takes a very
complex set of steps to create the bug. A user will rarely do these steps.
Category 3: Intermittently Reproducible – This is a bug that occurs sometimes, but cannot always be
reproduced.
These categories must be combined with the levels to determine the priority of fixing the bug. Category 2
bugs are usually not a high priority, unless they are a level 1 or 2. Category 3 bugs can be very frustrating. I
can recall spending days trying to hunt down one of these flaky bugs with Visual Basic 5. It turned out that
we had an object hierarchy that we were referencing down to the bottom level in one line, such as:
Using the With statement and breaking up the hierarchy fixed the problem, though I never once saw the
error while debugging and only saw it once every twenty or so runs through the application. The working
version looked as follows:
With Object1.Object2.Object3
. Object4. Object5.Method
End With
If you are using pointers in Visual Basic, it is easy to get these types of intermittent bugs as you will
sometimes write to a safe place in memory and other times not.
User Training
The clearer the interface to the application is, the less training the user will require to learn how to use it.
The first step in achieving this is a good user prototype and good user interface design. If every form is
centered on accomplishing a single task and the controls on the form follow the flow of the task, there
should be a minimum of training required. Similarly, if the nature of each form reflects the business process
it is supporting, it will be easier for the user to understand what they should do, and in what order. If you
have spent time creating user interface prototypes and properly testing them, you will save time and money
during training.
However, if your project has introduced a new business process then there are a number of other issues that
need addressing. Of course, you will have to tell the users how the new business process is going to work,
and how the application follows the new process. There could also be the added difficulty of trying to
integrate the new system with the old system - if the new system only covers some functionality, the users
will have to know when to use the old system and when to use the new system.
336
Deployment Phase
It is very useful to create an internal web site that explains the application and how it functions and answers
some of the common questions you would expect to be asked. It can save the help desk people a great deal
of work if questions asked to the help desk personnel are posted to a web page with answers. Each question
should then only be asked once, which prevents the same question from being asked repeatedly.
User training should use as many different mediums and self-service tools as possible, such as placing
information about the application on an Intranet site. The more the user can do on their own, the easier it
will be for them to use the application. If the users can teach themselves, it can serve to give them greater
confidence in their ability to use the application, and so therefore they will feel more at ease using it.
The educators will work closely with the users on the user education program. If the educators do not have
any programming experience, they may need the assistance of the developers to make web pages or help
files, which will assist the users in their understanding of the application and how they are supposed to use
it.
Prepare Infrastructure
The amount of work the logistician will have to do in preparing the infrastructure depends on what is
currently in place in the corporation. There may be large amounts of data in legacy systems that will have to
be moved. The Visual Basic programmer may find themselves writing applications to perform these
transformations using SQL Server 7's Data Transformation Services. Visual Basic developers may also be
called on to create test applications for new systems and to assist in stress testing or performance testing.
When the project is done, the development team should have a review meeting to discuss the project's
successes and failures. This information should be included in the developer's documentation and used for
future projects. Knowledge is one of the most valuable resources; keeping accurate records allows you to
pass knowledge from one project to the next. This is not only important if your project was a failure; future
project teams can also learn from the success of this project and incorporate the goal-oriented teams and
cyclic methodology into their working life. In this way, good design will become the norm and future
projects have a greater chance of success.
337
Chapter 11
Changes to the code should result in the updating of the design documents and the addition of comments in
your code. One easy way to document your code is by adding a comment in the beginning of the module
such as the following:
In the code where changes are made you would add a comment with '20-06-99. You should also have some
form of document control, such as SourceSafe, that has the original version of the code prior to the changes.
This should be part of the coding standards.
By adding these comments into your code, it becomes easy to see what changes were made, why and by
whom. If a change results in additional problems, it will be easy to track down where the changes were
made.
Deployment Strategies
One thing to consider is how to get your system or application onto the computers of the end users.
However, there is not just your application to think about, but also any other files that are needed to make
your application work. You cannot be sure that each user computer will have the necessary secondary files
needed to make your application work. Some extra files needed to ensure that your application can be used
might be:
338
Deployment Phase
Any ActiveX controls used in the application. Many computers will already have a copy of the controls;
however, if any of them are missing, the application will generate an error. These controls will need to be
registered during the setup process when users install them onto their computer.
The Visual Basic Runtime library. For Visual Basic 6.0, the file is MSVBM60.DLL.
Any supporting files. If the application is to have its own version of a database, such as Access, you'll
need to distribute a copy of it. Don't forget any text files, data files, report files or registry files.
Other Dependency Files. These include DLLs, which are called by the application.
Documentation and Help Files. Many products are available to assist you in creating help files. One of the
most popular is RoboHelp.
Of course, some of these files may have to reside in specific directories, and it cannot always be assumed
that the user will have read the installation instructions correctly, or that they know how to install a product
at all. For this reason, we create a setup program, which will install all included necessary files into the
correct subdirectories on the target computer. This is one way of preparing your application for deployment
and, luckily, Visual Basic provides us with a Package and Deployment Wizard to help us do just this. Let us
look at this facility in more detail.
Open the package and Deployment Wizard from the Visual Basic folder (or the Visual Studio 6.0 Tools
folder if you have Visual Studio) from the Programs menu. The Package and Deployment Wizard will
open and prompt you to select the project you want to deploy. Locate the project file on your computer that
you wish to deploy.
339
Chapter 11
This first screen shows us options for creating, deploying and maintaining application setup files. For now,
the only option we are interested in is the Package function, which allows us to create a setup facility, so
click on the Package button.
This stage allows us to specify the type of package we wish to create: as you can see, we can say that we
want a standard executable package, an Internet package or we can specify it as a dependency file. A
dependency file is a file that our application, or components within our application, requires in order to run.
It might consist of a DLL, for example, that is used by many clients. If we made revisions to our
dependency file, we would want to redistribute it to all users; this utility allows us to do this. We want to
create a standard executable file, so select Standard Setup Package and click the Next button.
340
Deployment Phase
This dialog allows us to specify where we want the setup files to be saved once they have been created.
Select where you want them to be saved and then click the Next button
The Included Files dialog shows us what files will be automatically included in the package by Visual
Basic. This list is created from the references and components we added to the project. If there are any that
we are sure are not needed, we can uncheck the boxes and exclude them from the package. Similarly, if
there are any missing, we can make sure they are included by clicking on the Add button and locating the
appropriate files.
Dependency Files
A dependency file, which ends in the extension.dep, contains information about what additional files are
needed for an application, how these files are to be registered for use and into which specific directories the
installed files must be placed on the user's computer. The '.dep' files are what the Package and
Deployment Wizard looks for when packaging the application - this file gives the wizard the information it
needs to be able to include all of the relevant files in a setup file.
A standard packaged application will have its dependency information stored in a file called Setup.1st,
which is separate to the package. An Internet package will store its dependency information in a file ending
with the extension '.ini', which is part of the packaged application.
There are two types of file that can contain dependency information:
Component '.dep' files; thesefiles list all of the files that are needed for an individual component to work.
If a component you have developed can be used in another project, you would create one of these '.dep'
files to tell the next user what information they need and where to find it.
341
Chapter 11
VB6dep.ini file; this file contains the dependency information for the whole environment of Visual Basic
and can be found in the '\Wizards\PDWizard' subdirectory of the main Visual Basic directory. This file also
contains information on what files are not to be included with your packaged application - this may be
because the files need another component to install them.
This dialog allows us to specify whether we wish to distribute our application in a single file or in several
smaller files. The application will be distributed in Cabinet (Cab) files. These are compressed files, which
work similarly to Zip files; each Cab file can contain a number of files which must be extracted before they
can be used. In this dialog, we can specify the number of Cab files we want to create and the size of each
file. If we plan to distribute this application on floppy disks, then we will want to select the Multiple Cabs
option and limit the size of each Cab to 1.44 megabytes. Do this and click on the Next button.
342
Deployment Phase
This step asks us what we would like the title of our setup package to be. Click the Next button.
343
Chapter 11
The Start Menu Items dialog allows us to place files in the startup folder, or in the folder that will be
created specifically for your application, so that they will be accessible from the Start button. This is a
great place to put other executables or help files that are part of your application. Click on the Next button
to accept the default values. This takes us to the Install Locations dialog, where we can specify the folders
where our individual files will be saved:
For the most part, Visual Basic knows where the associated files need to be placed, but the Install
Locations dialog gives us the option of changing the defaults and placing files in a specific directory. If,
for example, we want to place a specific DLL in the application path rather than the Windows Directory, we
can change this here. Click on the Next button to accept the defaults.
344
Deployment Phase
We now have just one final decision to make before the package is created. Visual Basic will identify any
applications or DLLs that might be candidates to be shared by other applications. In this case, VB has
identified the CodeGenerator.dll and the MDAC_TYP.exe file. If you want to share the file, click in
the box next to the filename. In this case, just click on the Next button, since we don't want any other
applications using our program!
345
Chapter 11
The last dialog is the Finished dialog. Here we can save the script by name so that we can re-use it if we
want to make any modifications later. It is quite common to want to modify the setup utility later, so always
choose a name that is logical to the project. Finally, click on the Finish button.
It may take a few minutes to build and copy the files to your drive. When this process has been completed,
the dialog shown above will appear, giving us detailed information about the package. This information will
change from application to application. Be sure to read the comments closely then click on the Close
button. You will be brought back to the original dialog. Click on the Close button unless you want to build
another setup utility.
So, now that you have your packaged application, how do you make sure that your end users will be able to
install it onto their machines? There are a number of ways that you can do this, as I will now go on to
explain.
This method has today been superceded by the CD-ROM. CD-ROMs are easier for the user to utilize - it
carries more information than a huge number of floppy disks, and there is no frantic swapping of disks
before installation can continue. However, although this may ease the installation technique for some, you
must bear in mind that some users will not have a CD-ROM drive on their computer. So, although floppy
disks may appear to be a little outdated in this technological age, they are the only way that some of your
end users will be able to install your application.
346
Deployment Phase
Systems Management Server (SMS) is Microsoft's solution to mass deployment of regular files, such as
exes and DLLs, onto thousands of client machines. While it is beyond the level of this book to explain
SMS, it is important to make a few comments about this product. In general, if you are using SMS server to
deploy to thousands of clients, you need to first assemble a team of one or more people. These people will
need to begin by using SMS to determine every type of computer in the company. Once this is done, a lab
will need to be set up with client computers that are identical to the client computers that the software will
be installed upon. The software should first be installed onto the lab computers. Any problems with the
installation should be researched. This entire process can take up to six months. If this is done, SMS server
should work very efficiently and successfully install on the client machines.
If you try to push software out onto untested clients do not be surprised if the installation fails. This is not
only true with SMS server; this is also true with any method of deployment. I cannot stress enough that you
must test everything you do. Getting the software out onto the clients and servers is no trivial matter; it
requires a great deal of work to make a successful deployment plan.
The logistician should be working closely with the educators. It would be disastrous to change the client
machines if the users have not been trained or prepared for the new system. You must coordinate
deployment of the system with the training of the users.
It is important that the project is signed off after completion. The signing off of a project indicates that the
client accepts what has been delivered and is happy with the outcome of the project. If the project did not
deliver all agreed functionality, meaning that it did not fulfill its scope, it is up to the client whether they
accept what work has been done or not. If they are happy that the missing functionality can be delivered in
the next project, then they may well sign off the current project and accept the application. More often than
not, however, if the project has not fulfilled its scope it will not be accepted by the client, they will not sign
off the project, the application is not handed over, and they will definitely not pay up! It is important,
therefore, to strive to meet the scope so that the final sign off is merely a formality.
347
Chapter 11
With the final sign off a copy of all documents relevant to the project should be given to the client: these
documents will tell the client what their organization was like before the project, what the project aimed to
achieve, how it achieved its aims, and also provide any user guides that it is felt necessary to provide. The
client will use these documents for future upgrades and maintenance of the system. The development team
should also keep a copy of the documents for reference in future projects.
Summary
The deployment phase is the final stage of your project. It is a time of intensive final testing and debugging.
All project team members must continue to follow the guidelines of good project management during this
stage. Bugs should be documented and changes in code should be made properly and documented in the
code. Old versions of the project should be saved.
If the project has been properly designed and built, the final result will fulfill the business needs of the user.
Using the cyclic methodology means that we will end up with a user centered application that is built from
the best components within the limitations of the project.
Deployment of the application created by the project is not difficult, but there are a number of issues that
must be considered, such as including additional necessary files and deciding in which format the
application will be sent out. Once the application has been successfully deployed and accepted by the client,
all concerned can officially sign off the project.
348
Deployment Phase
349
Chapter 11
350
Versioning and Sharing Project
Files
Nothing can destroy a Visual Basic project faster than creating changes in the source code without properly
documenting these changes in the code and in the design documents. Combine these missing updates with a
failure to maintain old copies of the source code, and you will quickly find that you have lost all control of
your project. Because documentation and code become out of sync, it will be impossible to ensure that our
code continues to follow our carefully planned design. And, of course, the best design and plan are useless
if not followed.
The process of debugging code must be done scientifically, carefully and with purpose. I cannot tell you
how often I have seen developers being told there is a bug in the code, and then watched them start hopping
through code sections making random changes. When they have finished hacking, they say, “Try it now and
see if it works.” More often than not, several other bugs have been introduced. If the original source code is
not stored somewhere, there is no going back, as no one can figure out what changes have been made.
Changes need to be made in an orderly, organized manner. Using a tool such as Visual SourceSafe allows
one to track changes made to the code, and roll back to the previous code. Of course, one should make
changes in a careful, organized manner and have a standard for making changes to the code. But it’s
important to have access to the earlier versions if this doesn’t happen.
Chapter 12
When a tester identifies a bug, the team will look for a solution to the bug, and this should be found and
documented. At this point, a change will have to be made in the code. Prior to making any change, a copy
of the original files should be stored. In this chapter, we will look at a tool which can be used to implement
change control (the process of ensuring that any changes made to the product are authorized), and to
maintain a history of your Visual Basic project files (and other documents, too) so that you can retrieve
older versions.
Visual SourceSafe is a project-oriented version control system. Visual SourceSafe supports any type of
Visual Basic project, including web and non-web applications, and it can keep track of changes to both text
and binary files so we can use it with all of our project files. We can also use Visual SourceSafe to keep
track of the relationships between files. Visual SourceSafe works with groups of files.
In addition, Visual SourceSafe has a report generator, a history tool for showing history of projects or
individual files, tools to identify differences between versions of files, a tool for finding strings in text files
and a tool for viewing files.
Visual SourceSafe is a tool which allows a team to work cooperatively on code and documents. However,
since many readers will not have access to an entire network to explore Visual SourceSafe with, we will
create an example on a single machine.
In a real implementation of a change management system, there must be a great deal of planning. It is
unlikely the entire team will need access to all files. There must be a decision made on what files and
documents each component team will have access to, and what files and documents each member of the
team should have access to. The Visual SourceSafe database must be placed where all the team members
can have access to it and check out files for editing. There must be enough disk space for the Visual
SourceSafe database, and there must be enough room to allow for the expansion of the database as Visual
SourceSafe begins to maintain a history of the files. A clear set of rules must be established on when and
how files are checked, how they are updated and how they are changed and checked back in. All of these
factors take time, planning and research. A good change management system cannot be created without first
reviewing these issues.
352
Versioning and Sharing Project Files
You may be wondering where this file is physically saved. Usually, Microsoft Visual SourceSafe is
installed on a server in a development environment. Visual SourceSafe manages all of the documents it
stores (these documents can be code, forms, UML diagrams, etc.). Visual SourceSafe will place these files
in a special Visual SourceSafe database. The files will also be temporarily placed on one or more of the
developer’s hard drives as the developers check out the files for editing.
353
Chapter 12
While anyone using Visual SourceSafe can use the manager, most Visual Basic developers will actually
never use the Visual SourceSafe Manager or Administrator. These tools will usually be used only by the
project manager. In a large corporation with many projects, the change management system would become
a library that could be used by many developers. In this case, it is best if a librarian is placed in charge of
the database and the change management system. The librarian will establish user rights, locations of
databases and procedures and policies for the change management system. In this way the documents and
code will belong to the corporation and can be available for reuse, maintenance and future upgrades.
354
Versioning and Sharing Project Files
If a code module is checked out for editing, as we discussed, the last saved version can still be viewed by
another developer and even run. The second person cannot, though, change any of the code. This means that
while the development team is working on a module, the testing team can be testing completed portions of
the module. Thus, Visual SourceSafe allows development and testing to occur together.
355
Chapter 12
Configuring VSS
Many Visual SourceSafe options can be
changed. If you go to the Visual SourceSafe
menu and select Tools | Options you will
see the SourceSafe Option tabs:
This option tab allows us to adjust many of the SourceSafe configuration settings, such as what action will
be taken if an unchanged file is checked in, and what action to take when we double-click on a file in VSS
Explorer. It is worth taking some time to look through the tabs and see what options are available.
Merging Files
Using the cyclic methodology will allow us to complete the project in steps. Each step will complete a
portion of the project and will have milestones associated with it. Once the milestone is reached, we move
onto the next portion of our code. When it comes to writing Visual Basic code, it is best if each step creates
and completes a set of functionality of a Visual Basic component. Thus, in our first step we make the
Customer component and code the properties of the bottom class. Our milestone will be the writing of the
code and the debugging and testing of this code. Once this milestone is reached, we begin work in the next
stage, which may include writing the methods for this class. The next stage should not be adding additional
functionality to the properties written in the last stage, as this makes it difficult to update changes.
If we are adding methods or properties to a class from one stage to the next, we may run into the situation
where a bug is found in an earlier stage while working in a later stage. To fix this, we will have to go back
to the code from the earlier stage, fix the bug, and then merge the new version of the earlier phase into the
later phase. Visual SourceSafe can do this automatically, but it is recommended to use the Visual Merge
tool supplied with VSS. This works a little like Compare Documents in Microsoft Word, and allows us to
view each difference between two files:
356
Versioning and Sharing Project Files
Ideally, we would want to complete the bottom class in the first phase and then build other classes that used
the bottom class in the second phase. This is the best way to build a project and the easiest way to maintain
and debug the code.
Versioning Files
The standard project version numbers have used a Dewey decimal notation consisting of numbers separated
by periods. The format of a version number appears as major.minor.revision, where
You can extend this scheme if you need to. Visual SourceSafe’s archiving functionality allows you to
retrieve any prior version of existing code. This can happen if changes are made to the code that create a
serious problem in the functionality of the project. Using the archived versions, you can rollback to the
version that did not have the changes.
357
Chapter 12
One approach for tracking versions or builds of projects or applications in Visual SourceSafe is to use
labels. By placing a label on the parent project of a program, all of the child projects and files will inherit
that label. Labels are simply descriptive strings that we can apply to any version of a project. A label is a
free-form string which can contain up to 31 characters. The following are all examples of valid labels:
"1.0", "2.01b", "Beta 3" and "Approved by Tester1". Visual SourceSafe tracks the history of
the project, allowing us to label a project when we have reached a certain level of development (for
example, version 3.05.234). Later on, we can refer back to the files in the project, as they existed at the
time you labeled the project.
We can label a
project by going
into the SourceSafe
Explorer, right
mouse clicking on
the project and
selecting Label:
Label Promotion is the best method to use when your development is done in the same project tree and bug
fixes are routinely performed before other changes have been made in the project. A common example is
when working on a major release with several milestones, such as Beta 1 and Beta 2. In this instance, we
would label the project when we believe we have completed Beta 1, then continue working toward Beta 2.
If few fixes are needed for Beta 1, use the label-promotion feature.
Share/Pin/Branch is the best method to use for parallel development on a project over an extended period of
time. A common example is when we are working on two releases that share code, both of which have
milestones. For example, we have shipped Version 1.0 and now we are working on Version 2.0; however,
an interim patch for several bug fixes is needed. This patch will be released as Version 1.1. In this instance,
we would work on Version 2.0 and Version 1.1 in different project trees, then merge changes between them
as necessary.
358
Versioning and Sharing Project Files
The following are three scenarios using the label-promotion feature. For completeness, a fourth scenario
using share, pin, and branch is described. These scenarios are presented as a guide.
359
Chapter 12
Check out the original Release 1 copy of the files that need to changed, make the required changes, and
then check the files back in, creating a new version.
Label the file "Release 1" (the same label we gave to the project). This promotes the new version of
that file into the project with the label "Release 1".
Now, if we retrieve the Release 1 project, we will get the project the way it was at the date and time
when we labeled it "Release 1", except that we will retrieve the newer version of the file we just
labeled individually as "Release 1". This allows us to update specific files in an old version, even
after changes have been made to other files.
Scenario #4: Share, Pin and Branch to Create Service Pack Projects to Fix Major Bugs
If the need arises for a bug fix after a project has been labeled and further developed, we can use the
following share, pin and branch scenario.
Sharing allows one file or set of files to belong to multiple projects. Unless the file is branched after
sharing, each project will have a reference to the shared file: if the file is changed in one project, it will also
be changed in the other.
Branching is the process of sharing a file with another project and then separating it into two or more
branches. Once a branch has been created, two files (the file in the project and its counterpart in another
project) will have a shared history up to a certain point and divergent histories after that time. Branching a
file breaks the shared link, making the file in that project independent of all other projects.
Pinning is generally used with shared files, although it is not limited to shared files: we can pin any file.
When we pin a shared file, we cannot make any further changes to it. Pinning is like sticking a pin into the
file so that a particular version of the file becomes the version that is part of the project. If a pinned version
of a file is shared, the projects sharing the file cannot change it. If a file is shared first and then pinned in
one project, other projects can still change and update the file.
In the drive toward Version 1.0, develop and test your project (e.g. $/Application).
When Version 1.0 has been achieved, label the project "Version 1.0".
Begin changing files in the project in the drive toward Version 2.0 of the project, which will introduce
new features.
360
Versioning and Sharing Project Files
361
Chapter 12
Give the project a New Name (e.g., $/Application V 1.1). If the project has subprojects, select
Recursive; this will ensure that all subprojects are also shared. Add any comments in the Comment
box as needed, then click OK. Click Close to exit the History of Project dialog box.
Select the newly created project $/Application V 1.1. All files in this project will now be
pinned:
Select only those files that need to be changed to address bug fixes, then branch the file(s). Leave pinned
any files that do not need to be changed. You can later merge bug fix changes back into your Version 2.0
project.
362
Versioning and Sharing Project Files
File Histories
Visual SourceSafe has the ability to build file history reports. File histories list each version of a file, from
the most recent to the oldest, with information such as what happened to the file, who did it, when it was
done, and what comment was made.
To tackle this with Visual SourceSafe, we generate a report on the project itself. For instance, it might
report that a file named COMMON.BAS has just been modified; before that, OPENALL.FRM was changed;
before that, FILESUPP.BAS was added to the project, and so on. Visual SourceSafe collates the changes
that we would otherwise have to sort through manually, enabling us to view the order of changes over the
last week. This can save us a lot of time and help us avoid dead ends.
Visual SourceSafe can automate the process completely. Within its database, Visual SourceSafe stores each
file only once. Each project that contains a file has a pointer to the location of the file in the database. All
versions of the file are available to each project, and a project may “freeze” the version of a file to avoid
introducing errors while another development team works on the reused code.
Summary
Visual SourceSafe is a tool that allows a team of developers to share source code. It also provides an easy-
to-use versioning system. In this chapter, we outlined some of the more basic features of SourceSafe and
discussed how it can be used in managing your Visual Basic project.
We haven’t been able to look at all of the features provided by VSS, but this whirlwind tour of this tool has
given us the chance to look at some of the issues connected with version tracking and source control. We
saw how a tool such as VSS can help us keep track of who is editing which files, and how it can help us
maintain a library of previous versions of our code. This means that if we have to fix bugs in an old release,
we will still have the appropriate files. We also saw how VSS can help us manage and maintain code
modules which are shared by a number of different projects or releases.
363
Chapter 12
364
Creating a Project Schedule
We are now going to take all of the information we have learned throughout the book about our Visual Basic
project and goal oriented Visual Basic teams and create an example schedule for the whole project. Although
you can download this schedule from the Wrox Press site, I would recommend you taking the time out to
actually input the information into the schedule. This will help you understand the goals of each cycle, and
whose responsibility it is to fulfill that goal. We will discuss some ways of improving it at the end of the
chapter.
Project Resources
Create a new Project 98 schedule called DNA. You will need to add resources to your project. We will allow
for a large development team that incorporates three small teams. Team 1 will focus on server components,
Team 2 will work with client side components, and Team 3 will be the web experts. Go to the menu and select
View | Resource Sheet.
Resource Name is the label we are going to give to our resource; in this case, our resources are our team
members, so their titles will be entered as the resource label. In order for us to make a cost estimate for the
project, we must enter the rates of pay for each team member, or the Std. Rate: the total cost of employing
each team member will be seen after all the information has been entered into the schedule.
Chapter 13
Enter the information from the following table into the resource sheet.
366
Creating a Project Schedule
The table is full of zeros because the resources have not yet been assigned to any goals, and so have not yet
started costing you any money!
Throughout this chapter, you will see that as you add goals to your schedule, you assign resources to them. In
some cases, the resources will have a percentage mark next to them - this is to indicate how much of the
resource is being utilized for this particular goal. However, as our resources are all people, we will take the
percentage mark to mean the percentage of time each person is spending on the particular goal.
In an ideal world, we would have every member of the project team fully dedicated to only one project at a
time; however, this schedule tries to reflect a real life situation, so it must be understood that our team
members may sometimes have other, non-project related work to do. Although this may add some length of
time to our duration estimates, these responsibilities and prior engagements must be accepted and
accommodated.
367
Chapter 13
When you are entering the following information, please bear in mind that the durations I have given to the
goals here are only estimates, based on showing you what a realistic schedule may look like. In real life, the
durations will vary according to the size and complexity of the project, the number of people available, what
else team members may be working on at the same time, and lots of other factors. This schedule merely serves
as an example for the project we have been looking at throughout the book.
368
Creating a Project Schedule
In the first part of the envisionment phase, we must evaluate how the client’s current Enterprise system works
and what their current business processes are. This is essential to give us a good idea of the background of the
client. We must then determine how that system will be integrated, or migrated, into the current project.
It is important that every team member attends the initial consensus meeting: everybody should understand the
aims of the project and the impact it will have on the client.
It is quite obvious that the Enterprise Architecture Document cannot be created until you have evaluated the
current system. Similarly, the initial consensus meeting cannot take place until the current status of the
business is known and can be communicated to all.
This part of the envisionment phase allows you to make an initial estimate of the Total Cost of Ownership and
Return On Investment for the project. At this stage, estimates will be just that - it is only after completing the
other phases of the project that these estimates can be refined.
The ROI and TCO cannot be determined until after the initial consensus meeting. Similarly, the milestone
cannot be reached until the ROI and TCO have been determined.
369
Chapter 13
As you are undertaking the project to deliver some specific functionality to the user, it would be very useful to
find out what it is that they require! This cannot take place until after the initial consensus meeting. To define
client requirements, you must decide not only what information the users require, but also how they prefer to
access that information. From this, you should be able to determine exactly what information each user
requires.
Your clients may have strict rules about the configuration of their computers. This may put restrictions on the
way that the project can be designed and developed. It is imperative that information such as this is uncovered
before any design or development takes place - knowing the restrictions beforehand will save a lot of money
and effort in the long run.
To define the specific functionality, you must take the user requirements and translate them into goals for the
developers; this will give them more of an idea of what it is they are expected to do when design and
development actually take place.
370
Creating a Project Schedule
It is important to analyze your concept, the environment you are working in and the potential problems that
could arise. These areas of risk should be documented and a plan formulated to mitigate the risk where
possible, and manage the risk where necessary. Depending on the degree of risk inherent in the project, you
may want to add contingencies to the durations in the project plan. This step would form the basis of the Risk
Assessment Document.
This step cannot take place until all the preceding steps have been completed: the risks identified will be
specific to what the user wants the system to do. Until the specific functionality and requirements have been
defined, the risks cannot be identified.
371
Chapter 13
It should also take account of potential risks, so this step cannot take place until the risks and risk approach
have been defined.
A testing plan should also be developed to ensure that all code is tested systematically and thoroughly. The
master schedule should also be created; this gives an idea as to how long the project will last and can also
provide initial cost estimates for the project. These two steps will follow on from the project plan.
372
Creating a Project Schedule
The final consensus meeting, again attended by every team member, will give the green light for the project.
All items should have been agreed upon, and the Vision / Scope document created, becoming the milestone for
this phase. The completed Vision / Scope document will be used as a tool to communicate with the
development team, whether they are an internal development team or an external vendor. As a result of the
briefing you should have committed development resources for the project. Quite obviously, this step cannot
take place until all preceding steps are complete.
Vision statement
Scope statement
Assessment of resources
Team responsibilities
Risk Assessment
ROI / TCO
373
Chapter 13
The schedule for the Envisionment phase will look as follows in Project 98:
To make the schedule more readable, you can change the color of the goals that are divided into smaller goals.
Select an entire row and then go to Format | Font and select a color.
374
Creating a Project Schedule
375
Chapter 13
The conceptual design phase is all about adding structure to the ideas from the envisionment phase. Here, we
will find out from the users how they would like the system to work, and how the system can work in the most
efficient way to meet business needs. When the conceptual design milestone has been reached - a complete set
of finalized Use Cases - there will be a clearly defined description of the product, the functionality it will
include and the manner in which the users will interact with the system.
These steps occur in a logical order, each needing to be complete before the next step can begin.
376
Creating a Project Schedule
This stage of the design phase cannot begin until there is a complete set of finalized use cases - otherwise, there
would be nothing to build upon!
The logical stage of the design phase is where a prototype of the user interface will be developed; this will
allow the developers to ascertain how the users want to interact with the system. Form design will also take
place, so that the user’s interaction with the system is optimized and both easy and complex tasks are simple to
perform.
For the web component, you must figure out conceptually what you want the look and feel of the site /
application to be. If the site is large you will want to determine the design and layout of the site. Design should
be decided on first and agreed on by all team members. You should also determine conceptually what your ‘hot
spots’ will be and what they will link to.
377
Chapter 13
378
Creating a Project Schedule
This stage of the design phase is where the developers convert the use cases into sequence diagrams, which
indicate which components the project will need, and which properties and services each component will need.
After you have defined the specific functionality in the Conceptual phase, you must decide how to implement
it. The decision on how to implement functionality cannot be made until there is a complete user interface
prototype - before this, the detailed functionality will not be known. This decision entails whether you will
have in-house developers do the work, hire vendor development services, or you will buy a product off-the-
shelf to implement the functionality.
For example, functionality important to the users may be the ability to give feedback directly from the website
to the content owners. This can be done by implementing a link that sends email to the content owners, or by
creating a page that puts the feedback into a database. Creating a hotlink to email needs very little
development, but there must be a scheme set up to maintain whom that mail goes to. Creating the direct-
feedback page takes more development, but you have greater control over how the feedback is formulated and
can be reported on. These types of tradeoffs need to be considered when designing functionality. In this stage
you need to perform some cost benefit analysis as to whether it is more beneficial to develop the function in-
house, hire vendor development services or buy the product in the form of an off-the-shelf product.
379
Chapter 13
380
Creating a Project Schedule
The physical stage of the design phase is where the actual properties and services of each component are
defined: this means that there is a concrete design for each component, and also for the way in which the
component will interact. The physical design stage of the design phase cannot begin until all sequence
diagrams are completed. The logical stage was still very general; the physical stage translates the earlier
designs into the programming language of the project, in our case Visual Basic.
In this step of the physical stage, the activity and class diagrams are created - these relate directly to the Visual
Basic programming language and will show exactly how each component should work in Visual Basic. The
milestone for this step is the completed consolidated design document - it is essential that the design for Visual
Basic be agreed upon, as this is what will be developed in the next phase. However, this milestone is dependent
on the class and activity diagrams being completed.
381
Chapter 13
There are many things to consider when designing the setup of the server, not least the fact that all sequence
diagrams must be complete. First of all, you must determine how much data you will have so that you know
how much space it will take up on the server - this is quite important, as vast amounts of data may cause vast
increases in total project cost.
You will also want to ensure that, after developing the site, people will be able to view it. You need to
determine how much estimated traffic there will be: for example, how many people will visit your site and how
often will they visit it? For middle tier components, how many users will try to access the server
simultaneously? This will help you figure out what server (hardware and software) configuration you should
use.
Security is also an issue when developing a site: who has access to what information on the intranet? Access to
information will be based on the roles that were created in the Use Cases.
Since you do not want to make content changes to your application while users are working on it, you need to
define how changes will be made and how those changes will be propagated to the server components. You
must also communicate all server requirements to the personnel responsible for server operations so that they
can prepare and set up the production server. Only after this is complete can server site go live.
382
Creating a Project Schedule
Ideally, a lab should be set up to simulate the production network (bandwidth and traffic). Since this is not
always feasible, your best guess on impact to the network is important so that different potential solutions to
problems can be identified. If your system’s speed, reliability or response time will be compromised because of
network issues, you must determine what steps need to be taken to address those issues.
Keep your support personnel abreast of any issues you think relevant (network, server or content related) so
that they can prepare to staff accordingly. This is important because you want your support staff and intranet
site to go live simultaneously. The deliverable for the design phase is a completed design document - dependent
on there being a completed consolidated design document, a live server site and full documentation of support
requirements - detailing exactly what the system is to include and how this should be developed.
383
Chapter 13
384
Creating a Project Schedule
385
Chapter 13
386
Creating a Project Schedule
387
Chapter 13
Development cannot take place until the final design document is complete - only when the design is locked
down is it beneficial to move into development. This means that the project should not suffer from feature
creep.
The development phase is where the design from the previous phase is turned into an actual working product.
As I said before, three separate development teams will undertake the development of the system. Component 1
is split into two different classes, which was a decision made in the design phase. Here, you can see how the
design and testing of Component 1 Class 1 takes place.
388
Creating a Project Schedule
As the same group of people is working on the above two components, it makes sense to schedule the
development of Component 1 Class 2 to take place after the completion of Component 1 Class 1. However, it is
not enough to simply build the component: it must also be tested to make sure that it functions according to
specifications. After unit testing has taken place on the completed component, a bug report must be made,
showing any errors that were found, how they were rectified (if a solution was available!) and who was
responsible for making the changes. After this has been completed for each individual class of Component 1,
the component is complete.
389
Chapter 13
The development of this component is able to take place at the same time as the development of the server
component, because different team members are involved in the development of each component. Here, we see
that it is now Class 1 of the Client Component that is being developed.
390
Creating a Project Schedule
Again, the component must be unit tested and a bug report created before the milestone for this step of the
development phase has been reached.
The third development group is working on this particular step of the project, so this can be scheduled to take
place at the same time as the development of Component 1 and Component 2.
This is the stage in which you create the HTML source code. If you do not have developers assigned to this
goal, Microsoft FrontPage, Internet Assistant for Word, and other HTML editors can perform this function
quickly and easily.
If development is being done in-house, it is useful to have certain standards followed for HTML coding. This
makes the code easier to maintain in the long run. Creating a template for your developers will help this effort.
Building the Visual Basic Web Classes can only take place once the template has been created. The size of this
goal depends on the amount of content your web site will contain. The more detailed design work done up
front, the quicker this goal will be accomplished. Only then can appropriate testing and debugging take place.
391
Chapter 13
After you have designed the functionality, you must develop it or buy it, depending on the cost-benefit analysis
performed in the design phase. If custom development is the way you want to proceed with getting the
functionality you need, you must determine who will be responsible and plug them into this goal.
Once the functionality you need for your web site is complete, either by your own development or by
purchasing some third party software, integrate it into the other pages to complete the site. This can only be
done when the Visual Basic Web Classes have been tested and debugged and any custom functionality has been
developed.
Only after all the components have been developed and tested, and the web pages integrated, can you say that
the coding is finished and the code completed milestone has been reached. This is a very important milestone -
any delays in reaching this milestone will have a knock-on effect throughout the rest of the project.
392
Creating a Project Schedule
This step concerns defining what specific content will be converted to HTML to be viewed directly on the site
and which content will remain in its native file form and linked to from the intranet. You also need to
determine the source and location of each type of content. Each goal follows in a logical order.
It can be beneficial to create a content site map detailing where each content type resides today and where it
will reside on the new web server. Prioritize the content migration; that is, determine in what order content will
be moved to the web and, if appropriate, what content should be archived. You should also define how you
want the content to appear on each page.
Convert necessary content to HTML either manually or by utilizing a set of conversion utilities. The choice is
dependent upon the quantity of content requiring conversion.
Once the content has been converted, either manually or with the aid of conversion utilities, an editor should
double check the quality of conversion to make sure that standard formats are in place.
393
Chapter 13
Testing is very important; if you do not test your system you could run into insurmountable difficulties when
the system goes live, because you won’t know what to expect. There are a number of tests you need to perform:
first of all, you should test each individual web page. You then need to test the links / connections of all pages
of the site, to ensure that users can find the information they want. Quite obviously, testing cannot take place
until the code completed milestone has been reached.
Usability testing means that you have the users use the site and conduct testing to see if the site meets the
requirements defined in the conceptual phase. Stress testing means that you simulate the load on the system to
test the performance of the site according to the predetermined requirements.
394
Creating a Project Schedule
395
Chapter 13
396
Creating a Project Schedule
397
Chapter 13
398
Creating a Project Schedule
For the system to be prepared for handover, it is quite obvious that development must have been completed.
However, as much of this phase is concerned with planning for the handover, there is no reason why it cannot
start while development is still taking place: the design and functionality of the system are known, and the
duration of development can be estimated. This is why the deployment and development phases overlap.
It is quite plain to see why there are so many predecessors for goal 102 - obviously, the components cannot be
moved to the production server unless they are completed, tested and debugged.
399
Chapter 13
The users will obviously need to know when they are going to get their system, so you must let them know the
rollout schedule - this will also help them understand why they cannot have their system yesterday!
It is imperative that the users understand how to use the system before it goes live: not only will this save
money in the long run, but it also means that the time taken for the system to become operative and efficient
will be shortened.
It is also important to publicize the release of the system internally. Not only can this generate interest in the
system, but it might also generate interest in the project team, meaning that (if the project is successful!) their
skills are in demand.
The milestone for this step of the deployment phase is the actual handover of the system to the users, otherwise
known as rollout. It is clear that this is dependent on all other goals preceding it being completed and all
milestones reached.
400
Creating a Project Schedule
Although after rollout the project may have officially ended, it is by no means over. It is crucial that the users
receive support and guidance in how to use the system, especially if it radically alters business processes or
introduces totally new ways of doing things. This step ascertains what support the user will need and makes
sure that there are people available to provide it. The level of resources needed relates directly to the
documentation of Support Requirements that took place in the physical design stage of the design phase.
It is important to know how users will seek support: this could be by telephone, by email, over the Internet, or
even by post(!). If it is decided that there will be one main way in which users seek support, most of the focus
will be given to this; however, the other methods available should not be ignored.
401
Chapter 13
It should also be determined how the process of support takes place - this could include, for example, the
description of a hierarchy of support, where increasingly technical queries are passed up the hierarchy to
people who are able to deal with them. This process can only be determined after user training has been carried
out and the rollout plan communicated to them: before this point, it is unlikely that the users will realize that
they may need support with the system.
This phase ends with another milestone - support goes live on the same day as rollout.
The Project 98 schedule for the deployment phase will look as follows:
402
Creating a Project Schedule
The Gantt chart for deployment should look like the following:
403
Chapter 13
As I said at the beginning of the chapter, there are many ways in which this schedule could be improved. One
such area is the fact that some team members aren’t always fully dedicated to the project, through no fault of
their own. Although this isn’t fully under our control, it would be nice to have 100% of resources available to
allocate to each goal.
Room for improvement is also available regarding duration estimates. As has already been mentioned,
experience is needed when time estimates are being made. As you progress through your project management
career, you will become more proficient at estimating the time needed for each goal: therefore, with experience,
your schedules will become increasingly more accurate.
404
Creating a Project Schedule
Summary
We saw in Chapter 3 how to use Project 98 to make schedules for your projects. This chapter has built on this
knowledge to create an entire schedule for a sample project that you can adapt and modify to suit your needs.
This schedule has followed the cyclic methodology detailed in this book. Drawing up an approximate schedule
at the beginning of a project will allow us to estimate the resources needed for each phase of the project, and
thus the duration and cost of the project. Of course, the schedule will need constant refinement as the project
progresses through each phase; as you gain a full appreciation for the complexity of the project, and the effort
involved in bringing it to completion, you will be able to make a progressively more accurate assessment of the
resources required.
Remember, though, that in real life you will be constrained by a time limit or a set budget - making sure that
your project is successful within these constraints is a valuable skill. Hopefully, this skill has been strengthened
by the understanding you have gained of the different issues involved in the successful management of a
modern-day Visual Basic Enterprise project.
405
Chapter 13
406
A Brief Overview of UML
For those of you unfamiliar with Unified Modeling Language (UML), this appendix provides a quick tour
of some of the terms, concepts and diagrams that are used throughout the book.
A model is a description of the problem we are set to solve. It simplifies the reality by capturing a subset of
entities and relationships in the problem domain.
A problem domain describes not only a particular problem but also the conditions under
which the problem occurs. It's therefore a description of a problem and the relevant context
of that problem.
A model shows us what the problem is and how we are going to tackle it. We may use diagrams, text, or
any other agreed form of communication to present the model.
A modeling language, therefore, is a language for describing models. Modeling languages generally use
diagrams to represent various entities and their relationships within the model.
Appendix A
UML accomplishes these tasks by having a series of different models. Each model represents a different
view of the project. Some models are built from others, so there is a logical sequence in which the models
are built.
Things in the UML describe conceptual and physical elements in the application domain
Relationships connect things together
These two elements are brought together in UML diagrams to help us visualize things and their
relationships in a well-structured format.
UML Diagrams
There are quite a few UML diagrams that we can use when designing our applications, and we can pick and
choose those which will be of most use to us. However, there is a basic core set of diagrams that we will
almost certainly use. This core set of diagrams includes:
We’ll now run through these types of diagram at whirlwind pace. You’ll notice, as we run through them,
that some diagram types have sub-types themselves (such as collaboration and sequence diagrams). This
may be your first clue as to the richness and diversity of UML as an analytical design tool.
Notice that as we progress through this sequence of UML diagrams, we will also be
progressing towards an ever more focused and clearly defined idea of the project we
are designing and planning to develop. This is one of the fundamental points of the
UML approach.
408
A Brief Overview of UML
Use case models can be built from interviews with the user, and are the first step in converting the user’s
needs and requirements into a useful model.
Use cases are more like a model than a diagram because they describe the system, or parts
of the system, with words rather than with pictures.
Use cases are detailed enough to include all of the information on the project, but simple enough for even
the most technically challenged user to understand. Use cases can also be associated with business rules,
which explain special rules, related to the use case.
Let’s take an example. In an order entry application, the use cases could include descriptions of various
sub-parts of the system. These sub-parts, that together could make up the whole system, could be such
things such as Taking an Order, Creating a New Customer, etc. For the use case Create New
Customer, there could be a verbal description of the process of creating a new customer that looked as
follows:
Primary Actor
Sales Representative
Secondary Actor
None
Starting Point
The use case starts when the actor makes a request to create a new Customer
End Point
The actor's request to create a Customer is either completed or cancelled
Flow of Events
The actor is prompted to enter information that defines the Customer, such as Name,
Address, etc. The actor will then enter the information on the Customer.
The actor can choose to save the information or cancel the operation. If the actor decides
to save the information the new Customer is created in the system, and the list of
Customers is updated.
409
Appendix A
Measurable Result
A Customer is added to the system
Business Rules
Customer
Customer Fields
Restrict Customer Create
Without getting too heavily involved right in the details of this use case, what we’re seeing here is a verbal
description of what happens when a potential user of the program we want to design needs to create a new
customer. Possible flows of events are identified to explain how the system can get from the start point to a
definite end point. Measurable results are defined, and some business rules are created. One of these
business rules is called Restrict Customer Create and might be written as follows:
Overview
This rule is for when a Customer is added to the system
Business Rule
Each Customer must have a unique CustomerID
Depending on the size of the system we’re working one, we may actually need to create quite a few of these
use case statements and business rules before we have captured the key aspects of the system we’re
designing. It’s crucial, however, that we draw up these statements from the people who will be using the
system, and the people who want to see the system in place. It’s the first step in our design process.
410
A Brief Overview of UML
Interaction Diagrams
Interaction diagrams are the next step of the UML design process. Interaction diagrams concentrate on
showing how objects or things in the system interact with each other to give a dynamic view of the system.
There are two basic types of interaction diagram:
sequence diagrams
collaboration diagrams
Essentially these both model the same information, except that sequence diagrams emphasize time ordering
whereas collaboration diagrams spatial or structural organization.
For the most part, you choose to create either collaboration diagrams or sequence
diagrams. For the sake of completeness, this appendix discusses both but we only use
sequence diagrams in this book.
Sequence Diagrams
This type of diagram can be used to convert the written use case models that we saw in the previous section
into a clearer visual model. This visual model will show how the objects associated with a particular use
case communicate with each other and with users over time. Sequence diagrams are very general. For
example, they may show that some Object 1 passes a message to some other Object 2, and that Object 2
then performs some operation within itself and finally returns the message back:
The internal workings of Object 1 that led to the creation of the message, and the internal workings of
Object 2 that led to the return message, are not shown in sequence diagrams. (Details of the inner workings
of the objects are represented in another type of diagram called an activity diagram - which we’ll see in the
next phase of the UML design process.)
Sequence diagrams map out every possible sequence of events that can be performed within each use case,
including correct and incorrect paths. The correct paths in the sequence diagrams can be used to design the
GUI of the project as they show what the user will need to do to interact with the application. Incorrect
sequences will later be used to map out errors and how to handle these errors.
411
Appendix A
Sequence diagrams also show what public methods and properties our components must have. You can
compare the sequence diagrams for one or more components and attempt to find patterns that exist that can
be used to simplify the coding of the components.
Collaboration Diagrams
Collaboration diagrams are also built from the use cases - but this time the emphasis is on the spatial
distribution of the objects involved. This is not to say that there are no temporal elements in collaboration
diagrams, since the sequence of events is mapped using numbers:
Personally, I often find this type of diagram quite confusing in comparison with the equivalent sequence
diagrams. This particular collaboration diagram presents the same situation as the sequence diagram we just
looked at - Object 1 and Object 2 with exactly the same relationships as before. However, it should be said
that there are times when collaboration diagrams can make good sense - especially if we find that we want
to emphasize a set of objects themselves rather than any sequence of events between them.
Activity Diagrams
Activity diagrams take the information available from the collaboration and sequence diagrams that we’ve
just looked at, and present that information in a more detailed fashion. The purpose of activity diagrams is
now to show the inner workings for a particular object.
As you may have noticed, we are gradually moving towards more and more detail
about our project design as we proceed through the different UML diagrams.
412
A Brief Overview of UML
This activity diagram simply specifies what Activity is to be initiated at a certain Decision point,
depending on the outcome of that Decision. This is a step-by-step definition of certain situations that
pertain to the project we are designing and about to develop in VB, and is a considerable way forward in
our journey towards defining a project and preparing it for development and implementation. We’re still not
finished yet though - the final stage in the overall UML design process is to move on to our class diagrams.
Class Diagrams
Class diagrams ultimately represent the classes that we will build in Visual Basic. They are the most
detailed part of the whole UML design definition, inasmuch as they begin to map directly to code objects
that we will be writing in Visual Basic. This is where we’ve been heading all along, and demonstrates how
well UML maps our design considerations to the programming language we’re using.
A Class diagram is a simple static picture of a class; as such, it will include all of the public and private
methods and properties of that class. Class diagrams are, of course, built from use cases, sequence and
activity diagrams that we’ve been developing throughout the UML design process.
413
Appendix A
This sample class diagram is simply a schematic layout of the relevant information that we would need to
go away and create the objects we’ve developed in our UML design process straight into the VB
programming environment.
Naturally, for a larger project we would probably need to derive many such class diagrams
in order to complete the design of all the objects involved in our system.
Other Diagrams
The diagrams we’ve looked at so far (use cases-sequence-activity-class diagrams) form the essential parts
of UML that we need to build a Visual Basic project, and are the ones we use in this book. There are,
however, other models that I will mention now for sake of completeness for the interested reader. These
other diagrams include:
UML Notation
We have covered the fundamental terms and most important diagrams, but before we move on to
demonstrate how to map the UML constructs into VB code (Appendix B) we need to have a look at some
more advanced UML notation, including how to depict relationships between classes.
The rectangle representing the class is divided into three compartments, the top one showing the class
name, the second showing the attributes and the third showing the methods.
414
A Brief Overview of UML
If the class is abstract, then the class name in the first compartment is italicized.
Relationships
Relationships between classes are generally represented in class diagrams by a line or an arrow joining the
two classes. UML can represent the following, different sorts of object relationships.
Dependency
Association
Aggregation
Composition
415
Appendix A
Multiplicity
The multiplicity of a relationship is indicated by a number (or *) placed at the end of an association.
A multiplicity can also be a range of values. Some examples are shown in the table below:
0..1 Either 0 or 1
Naming an Association
Inheritance
An inheritance (generalization/specialization) relationship is indicated in the UML by an arrow with a
triangular arrowhead pointing towards the generalized class.
Multiple Inheritance
The next diagram represents the case where class C is derived
from classes A and B:
416
A Brief Overview of UML
States
States of objects are represented as rectangles with rounded
corners. The transition between different states is represented as
an arrow between states, and a condition of that transition
occurring may be added between square braces. This condition is
called a guard.
Object Interactions
Interactions between objects are represented by
interaction diagrams — both sequence and
collaboration diagrams. An example of a
collaboration diagram is shown here: Objects are
drawn as rectangles and the lines between them
indicate links — a link is an instance of an
association. The number at the head of the
message indicates the order of the messages
along the links between the objects.
417
Appendix A
Use Cases
A use case is a description of an interaction between an actor
(person or external system) and system under design. In UML it is
denoted like this:
Design Patterns
418
A Brief Overview of UML
419
Appendix A
420
UML to VB Mapping
Purpose of the VB Mapping
UML is a wonderful thing - it allows us to 'see' the design of a system. However the diagrams we take
trouble to create are only useful if they directly contribute to our final system. Developers who are new to
modeling can understandably wonder whether all the extra effort is worth it. Therefore the point of this
mapping is simple: to help the VB developer understand how to map the UML constructs into VB code.
As of writing, version 1.3 was in draft, although there are no major changes to this version that VB
developers need to be aware to.
It is recommended that VB Developers visit this site and review the official documents before trying to
understand the mapping in detail.
Therefore, the mapping that follows concentrates on the concrete elements from the UML that have notation
and appear on diagrams. These are also the artifacts that the VB Developer will have the most contact with.
These include class, attribute, operation, interface, etc. Each of these elements will be discussed in turn
and references will be made to the more abstract elements in the UML semantics document that they derive
from, so that the developer can choose to cross-reference with the official specification.
So to reiterate, the mapping focuses essentially on how the diagrams you draw and communicate with relate
to the code you write.
Please refer to the Mapping Guide at the beginning of the mapping itself for a breakdown of
the sections therein.
Statechart diagrams, on the other hand, are not so clear. This is because the standard VB language does not
come with a 'standard' statechart implementation (often called a 'finite state machine'). This is also partly
because of the many different ways we can write them. Nonetheless, some guidelines are provided to help
get you started.
Fortunately for us, we can come up with conventions that developers can follow to help us define
components. A further discussion of this can be found in the mapping.
Concrete Or By Convention?
Some mappings from the UML to VB are plain and concrete - there is no debate as to its correctness. Some
mappings, on the other hand, are purely by convention because VB simply doesn't support the construct.
When convention is used, developers should use their judgment as to whether they follow the convention or
invent their own. Remember, though, that the suggestions given are tried and tested.
422
UML to VB Mapping
While sections of VB code that are provided as context, but are not directly relevant to the topic under
discussion are presented like this:
As you become more familiar with the UML, you will soon only need to refer to this Appendix periodically,
as the core mappings are very intuitive and easy to remember.
There are many choices here from general symbol tools like Visio (UML templates are available for this on
the web) to a full-blown repository-based CASE tool that will also ensure your diagrams are in-sync' with
each other. Of course never underestimate the power of a whiteboard and marker!
So, without further ado, let's start to look at the VB to UML mapping.
423
VB6 UML
Mapping Guide
These are the sections that are included in this mapping.
424
UML to VB Mapping
4.6.2 Qualifiers
4.6.3 N-ary Associations
4.6.4 Aggregation and Composition
4.6.5 Implementing Associations
4.6.6 Basic 1-to-1 Unidirectional Associations
4.6.7 Basic 1-to-Many Unidirectional Associations
4.6.8 Implementing Qualifiers
4.6.9 Bi-directional Associations and Referential Integrity
4.6.10 Problems with Simple Associations
4.6.11 Link Management Routines
4.6.12 Association Classes and Link Management
4.6.13 Bi-directional 1-to-Many Association with Link Management and Qualifier
4.6.14 Miscellaneous Advice
5.0 Use Case Diagrams
5.1 A Word of Warning
5.2 Use Cases and Transactions
5.3 Use Cases and Controllers
6.0 Behavioral Diagrams
7.0 Sequence & Collaboration Diagrams
7.1 Object Instances and Context
7.2 Interactions
7.3 Pseudo-Code
7.4 Collaboration Diagrams
8.0 Statechart Diagrams
8.1 Mapping States and Transitions
8.2 Implementing State
8.3 An Example
8.4 Implicit Implementation
8.5 Explicit Implementation: A Finite State Machine (FSM)
9.0 Activity Diagrams
10.0 Implementation Diagrams: Component & Deployment Diagrams
10.1 UML Components and Visual Basic
10.2 Logical components
10.3 Physical Components
10.4 Stereotypes
425
VB6 UML
In VB, this would translate into validation code inside the procedures of the VB class, such as an Order
class:
With this example, an order can only be associated with one customer. It is a constraint that only one
customer can be associated at a time. (Assume a separate routine is available to disassociate the customer.)
One useful feature of VB is to make copious use of Debug.Assert. This build-in library feature allows
us to make assertions in our code that must always be satisfied. If you are running in design mode and an
assertion fails, then VB will take you straight to the place where the assertion failed. This is very effective
way of catching logic bugs in your code, early.
Sometimes it is not always possible to translate a constraint to code. In these situations, the best you can do
is place an appropriate comment into the code to remind yourself and your colleagues that the constraint
exists.
426
UML to VB Mapping
1.3 Stereotypes
Most UML elements come with a set of standard stereotypes. Some CASE Tools also extend the range of
stereotypes to match the languages targeted. Here are examples of two class stereotypes:
«type» «interface»
::Document ::IPersistent
Stereotypes have a big impact on how we map UML to VB. In some cases, they affect only the properties of
the target VB item and sometimes it will completely change the mapping.
When we discuss each UML construct, the standard stereotypes of that item will also be covered.
::Accountancy
None A file system mapping by convention only.
427
VB6 UML
2.1 Packages
Packages in the UML are a logical grouping of related items such as classes. A Package has no direct
mapping to VB so conventions are used instead.
A convention typically used is to include the package name in the name of contained elements. For
instance, an Accountancy Package may contain a class called Account. Therefore, the class will have a
name in VB of Accountancy_Account. This will ensure that classes with similar names in different
packages will not collide. This activity is usually called Name Mangling .
Account Account
Balance: Currency Access Permissions
Withdraw (in Funds)
::RDO
Recordset
Database
428
UML to VB Mapping
::Order Processing
Orders Customers
Invoicing
This technique will not only keep the source code files manageable, but also help partition the work up
between developers. For instance, one developer may be working on an Accountancy package, whilst
another is working on a User interface package.
A <<façade>> package indicates that the package is present to provide a façade on to other packages in
the system. In VB terms, this could represent a set of related classes that are providing a simple, more high-
level interface onto another set of more detailed classes. Again, because package is a logical grouping of
items, there is no explicit language feature in VB that you can use. It is all defined by convention.
A <<framework>> package indicates that the package contains a framework of items. In VB terms, we
might design a set of related classes that perform a certain framework service, e.g. generic database access.
The <<framework>> constraint simply implies that the package would be used as part of a complete
system, together with the extra classes that complement the framework and make it complete.
429
VB6 UML
::Order Processing
<<imports>>
::RDO
Association
Attribute
Variable
- Balance : Currency
430
UML to VB Mapping
Class
Classifier
Abstract class of Class,
Class
DataType and Interface
(no notation)
Constraint
Assert statement, comment
or validation code.
{ ordered }
Interface
IPersistent
A specialization of Classifier.
For an ActiveX component,
or – Class
Instancing =
PublicNotCreatable
«interface»
::IPersistent
Operation
Procedure without body Typically on a VB interface
Withdraw()
4.0 Classifiers
4.1 General
A UML Classifier is the abstract definition of a Class, DataType or Interface in the UML. All of these
elements map to a VB Class, Standard Module or Form.
( Classifiers are defined in the UML to simply capture the similarities between Classes, DataTypes and
Interfaces. They are abstract however and don ' t appear directly on diagrams. Consult the UML semantics
document for further details about them.)
431
VB6 UML
UML classes are the most used of all the Classifier types and these map straight to VB Classes or Forms as
shown:
Account
Balance: Currency
Withdraw (in Funds)
4.1.1 Name
The name of the UML classifier becomes the name of the VB item.
4.1.2 Features
All UML classifiers have features, which are further defined as attributes and operations and these map to
VB Member Variables and Procedures, respectively. These are discussed later.
If we consider these two forms of inheritance, it is important to realize that the first form is more important
for building components that exhibit good qualities of design like low coupling. (A component with low
coupling means that the component has few dependencies on other parts of a system. This means that the
component could be used easily in other systems without too much work). The details of this are beyond the
scope of this book and I suggest you read the ' VB Books On-line' for a background on interfaces and the
Implements construct.
In UML terminology, a class can realize many interfaces. This directly maps to the meaning of
Implements, in VB.
432
UML to VB Mapping
<<extends>>
::Customers
AddCustomer
GetCustomer
Code reuse via Inheritance Code reuse via composition (the VB way)
In this situation, any operations you want to reuse, involves writing delegation code to delegate to the
reused object. Here is an example ' customers' collection:
Of course this can be very tedious when there are many services involved. This is where CASE tools are
useful for doing the ' grunge work ' . VB Developers may wish to develop their own VB ' add-in ' that performs
this task.
So to recap, if you are turning an <<extends>> inheritance relationship into containment, do the following:
433
VB6 UML
If the stereotype is <<implements>> then this maps simply to the VB construct ' implements' :
«interface» «interface»
::CompanyAsset ::PersistentObject
GetValue Load
Save
Implements Implements
::Employee
GetValue
Load
Save
The VB code for the above model could look like this: -
'Employee Class
Implements CompanyAsset
Implements PersistentObject
One convention we can use is to create a standard ( .bas ) module for each class that has static members.
All static operations and attributes can then be added as members of this module. When naming the module,
try to pick a name that relates the module to the VB class. For instance, if we have a class called Account,
we may choose to name the module AccountClass.
434
UML to VB Mapping
Account
Balance: Currency
OverdraftRate: double {static}
Withdraw (in Funds)
If you include parameterized classes in your design then this is OK but remember that you will have to
manually write the specific versions yourself. It may be better to avoid modeling with them to start with.
It is good practice to choose a filename for the class that is similar to the class name.
4.2 Interfaces
An interface, which is a specialized Classifier in the UML maps directly to a class in VB.
This mapping is not explicitly stated and checked in VB - it is only apparent that a VB class is an interface
by the way it is used by other classes and the fact that the VB class contains empty procedures.
435
VB6 UML
Interfaces are crucial when building components in VB. To expose an interface from a VB ActiveX
Component, the Instancing property of the VB class should be set to PublicNotCreatable .
In all other respects, an interface has a similar mapping to a UML class in that is also has features that can
be operations, attributes, associations, etc.
Note: Developers should not confuse interface with user-interface or user-interface class. Refer to the UML
documentation for a precise definition of interface.
4.3 Attributes
An attribute of a UML classifier maps to a VB variable.
Account
'Account class
- Balance: Currency '
+ Withdraw (in Funds) Private Balance As Currency
4.3.1 Visibility
The visibility of the attribute has a partial mapping to the access of the VB attribute as captured in this
table:
4.3.2 Name
The name of the attribute simply maps to the name of the VB variable.
4.3.3 Type
The type specified for the attribute will be the name of either a built-in VB type such as an Integer or a
Long, a user-defined type or a VB object type such as a Class or Form.
436
UML to VB Mapping
If the attribute is tagged as {frozen} then this implies that the attribute is constant. Constant attributes are
easily represented in VB as Const variables. For example:
Note: VB does not allow classes to declare public constants. This is more of a nuisance rather that a logical
restriction. It is recommended that constants that relate to a class be placed in module that is closely related
to either the class or the package containing the class. For instance, if you have a package called
Accountancy that contains the related classes, Account and Ledger , then you might want to place your
constants in a bas module that is related to the package called, say, Accountancy
( Accountancy.bas ).
4.4 Operations
An operation on a UML class maps to a VB Procedure.
4.4.1 Visibility
The visibility of the operation has a partial mapping to the access of the VB procedure as captured in this
table:
The actual meaning of public, protected and private really comes down to the language you are using to
implement your models in. In C++ for instance, public, protected and private all have quite distinct
meanings that are different to VB.
437
VB6 UML
In VB, the visibility options provided in the UML will map to different things in VB. When we are building
VB components, we are interested in three levels of access:
So when using the UML we should choose the mapping as shown in the table.
4.4.2 Name
The name of the operation simply maps to the name of the procedure in VB.
4.4.3 Parameters
(see below)
If a return type is present then we map the item to a VB Function, otherwise we map it to a Subroutine:
If we really want to make a distinction in VB, then we can say that the empty procedures defined in a VB
interface are the operations and the methods are the actual implementations in each of the VB classes that
implement the interface.
4.4.6 Parameters
Each parameter in UML has the following form:
438
UML to VB Mapping
Kind
The kind of the operation is either in , out or inout , and indicates how the parameter is passed to the
operation ' s body. VB has an approximate mapping for these:
Type
The type specified for the parameter will be the name of either a built-in VB type such as an Integer or a
Long, a user-defined type or a VB object type such as a Class or Form.
Default Value
If a parameter is given a default value then this can be implemented in VB too. For a VB parameter to have
a default value, the Optional keyword must be present:
::Document
4.4.8 Stereotypes
A <<get>> or <<set>> operation stereotype is an operation whose role is to provide access to a value on
the object. In VB terms, Property procedures are good examples of these types of operations.
4.5 Utilities
A UML utility class represents just a cohesive group of global procedures or variables. These are usually
mapped to standard (. bas) modules in VB because they don ' t have multiple instances like a regular class
does. Examples of utility classes are the standard procedure libraries that come with VB. It is convenient to
show them in this way to make a model easier to understand. These are shown as a stereotype of class:
439
VB6 UML
«utility»
::WINAPI
SendMessage
PostMessage
GetDlgItem
CreateWindow
4.6 Associations
4.6.1 Multiplicity
The multiplicity of an association determines how we implement the association. If the multiplicity is 1 ,
then we may choose to implement the association using an object reference. If the multiplicity is a fixed
number then we might employ the use of VB arrays. If the multiplicity is unbounded, e.g. 1+ then a
collection may be used instead. See the implementation section for examples of this.
4.6.2 Qualifiers
A UML qualifier in is effectively a key for navigating to the object at the other end of an association. For
instance, we may initially model that a Person owns many Cars . However in later design revisions, we
may state that a Person owns a single Car when qualified by a particular registration plate. See the
following examples for more about this.
'Class Car
'My engine – this will be created when I get created
Dim m_theEngine As New Engine
440
UML to VB Mapping
Let ' s first look at how we might implement simple associations in VB.
Here is the code for a simple unidirectional association (note that the example actually holds a link from
Car to Person ).
441
VB6 UML
To test the association, we will place some code in the main routine of the application:
Sub Main()
'simple 1 to 1 unidirectional association
A basic implementation of this is to embed a collection of Cars into Persons and then allow client code
to add Car s to Person at will.
442
UML to VB Mapping
Note the embedded, hidden Cars collection in Person. This holds the references to the associated Car
objects. The code for Car follows. (This was generated by the class builder add-in.)
Option Explicit
End Function
443
VB6 UML
mCol.Remove vntIndexKey
End Sub
To test the collection, we can write some code for the main application routine
like this:
Sub Main()
'simple 1 to many unidirectional association
The example code assumes that the collection is not ordered in any way.
444
UML to VB Mapping
Building collection classes can be tedious so it is recommended that developers take a look at the Class
Builder add-in, which provides collection-building features.
1 Owns 1
::Person Registration ::Car
Owner Transport
As mentioned in the mapping, a qualifier becomes an index when traversing the association. If we are using
property procedures, then the qualifier will become a parameter of that procedure. So, to access a single
Car that the Person owns, we must provide a registration number. Clients wishing to access an individual
car would supply the registration number of the car of interest:
445
VB6 UML
Here is the code for Person also with a link back to Car:
Option Explicit
Sub Main()
'1 to 1 bidirectional association
'with *no* referential integrity
446
UML to VB Mapping
If we want to build more robust bi-directional associations, we must build referential integrity into our
models. We can do this in a number of ways.
So let' s revisit our original 1-to-1 bi-directional association between Person and Car but this time, we
will add some association link management.
The code for Person and Car is almost the same as before but we have a new module to add which
contains the link management:
447
VB6 UML
Option Explicit
Sub Main()
'1 to 1 bidirectional association
'with referential integrity
448
UML to VB Mapping
Let ' s assume that association between Person and Car is supplemented with a ' Log Book' that records the
Car' s history:
::Person 1 Owns 1
Registration ::Car
Owner Transport
::Log Book
Milage
We will now want to ensure that when a Person is associated to a Car , a LogBook is also associated. We
will assume that the LogBook already exists. If we do this, we can end up with the following
implementation.
(Note that some properties in the code have been omitted from the model to make it easier to read. In fact,
we can see that the LogBook in the code actually has a number of {derived} attributes that get their
information from the Car.)
Firstly, here is the LogBook association class, which also contains the link management code:
'attributes ------------------------------------
449
VB6 UML
'operations ---------------------------------
'Register the log book for use
Public Sub Register(ByVal aPerson As Person, ByVal aCar As Car)
'delegate to link
Link aPerson, aCar
End Sub
m_blnInitialized = True
End Sub
Here is the Car source code now (some extra attributes have been added to spice things up):
'Car Class
'our private implementation
Private m_Make As String 'make of car
Private m_myRoadMilage As Long 'My Milage
450
UML to VB Mapping
'attributes ---------------------------
'operations ---------------------------
'Bump up the car milage
Public Sub BumpMilageBy(ByVal someMiles As Long)
m_myRoadMilage = m_myRoadMilage + someMiles
End Sub
When we now want to associate Person and Car, we first create a LogBook and then get the LogBook
to associate all three objects together. In the example client code we first associate the objects and then
iterate over the assocation and list the information:
(Code in App.bas )
Option Explicit
Sub Main()
'1 to 1 bidirectional association with association class
451
VB6 UML
452
UML to VB Mapping
'attributes ------------------------------------
'operations ---------------------------------
'Register the log book for use
Public Sub Register(ByVal aPerson As Person, ByVal aCar As Car)
'delegate to link
Link aPerson, aCar
End Sub
m_blnInitialised = True
End Sub
453
VB6 UML
Here is the revised Person class. Note that the Transport property is now qualified with a registration
plate:
'attributes -------------------------------
454
UML to VB Mapping
'operations ---------------------------------
Private Sub Class_Initialize()
Set m_Transport = New Cars
End Sub
We also have a slightly revised implementation of the Car s collection. This is the same as the previous
version except that it has been changed to accept an existing object rather than creating it itself. Here is the
revised Add operation.
'add a car
Public Function Add(ByVal aCar As Car) As Car
mCol.Add aCar, aCar.Registration
Option Explicit
Sub Main()
'1 to many, bidirectional association with association class
'an owner
Dim aPerson As New Person
aPerson.Name = "Russell"
'the cars
Dim aFastCar As New Car
aFastCar.Make = "Ferrari"
aFastCar.Registration = "R999 ICH"
aFastCar.BumpMilageBy 50
455
VB6 UML
Points to note:
Car objects can now navigate to their associated LogBooks. This was because I wanted to report the issue
date of the log book via the car.
This is also a good example of how the UML can help you understand quite a complex code structure.
Consider redrawing the model with the extra operations and attributes added and then review the design
visually.
I have used the Registration Plate of the Car as the qualifier from Person to Car. This makes sense because
the Registration Plate will always identify a single Car.
I have chosen in this example to continue to give the LogBook class the link management responsibilities. In
practice this responsibility will vary depending on your model. The objective is usually to produce a simpler
model that other developers can pick up easier later.
It allows you to vary the way you store the reference to the associated object. This hidden reference may
change over the lifetime of the system.
It allows you to provide an association that is created “on-demand”, to improve performance. For instance,
you might have an association to a large collection of objects. By hiding the association behind a property
procedure, you could build the collection when the property is first called (which of course may never happen
for the object's lifetime).
It allows you to provide a "Derived" association. Because your implementation of the association is hidden, it
may never actually take up any fixed storage at all. In other words, you have an algorithm behind the property
procedure that calculates the associated object by traversing many other objects.
456
UML to VB Mapping
For example, given two classes, Person and Car , Person has a reference to Car, and Car has a
reference to Person . If you introduce such a cycle, the VB run-times are often unable to clean up the
objects, even after you released the objects:
How should you avoid this? There are a number of solutions to this. The first suggestion is to allow cyclic
references but make sure you explicitly break the cycles when releasing a model. The technique is to add
explicit Destroy() routines to classes which are called when the object is ready to be released.
m_Car
Russell: Ferrari:Car
Person m_Pers
'Car Class
Private m_Engine As Engine
Private m_Alarm As Alarm
'other operations.......
So, given the Person-Owns-Car example, we might choose to hold a reference from the Person to the
Car, but on the Car we place an ID that uniquely identifies the Person. To support this implementation,
we will need to introduce a ' registry object' that keeps a track of Person s and their associated ID. When
the Car wants to traverse to its owner, it now consults the registry.
Both techniques have their merits and different performance tradeoffs. It is a judgment call as to which
technique is better for a particular situation.
457
VB6 UML
'add a car
Public Function Add(ByVal aCar As Car) As Car
mCol.Add aCar, aCar.Registration
mCol.Remove vntIndexKey
End Sub
458
UML to VB Mapping
Actor
<name>
By Convention only.
Class
(See below.)
Use Case
Use case diagrams are basically an analysis tool - they are created to help all parties involved in a
development understand what is being delivered rather than how it is to be built. Therefore it is not usual to
map the artifacts from these diagrams to actual source code.
459
VB6 UML
This is wrong because the use cases are there to help the potential users of the system understand what the
system will do for them – not how the system should be written.
The useful thing about use cases is that they clearly define the boundaries of candidate transactions, (where
a transaction is defined as a distinct, logical unit of work that our system might perform). ' Create Order' is a
good example of a transaction. In other words, the use case ' Create Order' must run to completion or not at
all. If we ' half' created an Order, that simply wouldn ' t do and could leave our system is a nasty state.
Therefore it would be useful if we could help ensure that transactions are cleanly defined and applied in our
system.
(A <<controller>> class stereotype is a class that is mainly responsible for controlling and coordinating
the implementation of a use case but doesn' t actually perform any of the use case-specific detail, itself.)
Let ' s start by looking at a use case model of the example use case:
Transfer
Funds
Bank
Customer
The use case will be performed by the following classes. Note the presence of the use case controller:
«controller» 1 2
TransferFunds ::Account
460
UML to VB Mapping
This is a high-level model. The two accounts will be the source and target accounts.
As previously stated, the controller is just acting as a coordinator but also knows about the whole
transaction. Therefore the lifetime of the controller is synonymous to the lifetime of the transaction and use
case. When we discuss collaboration diagrams, we will show how the controller performs the use case.
The UML offers four different diagrams for capturing your design dynamics and these are detailed in two
parts: The first part looks at how we map sequence and collaboration diagrams. They are focused on object
instances and the messages and events that travel between them.
In the second part we look at statechart and activity diagrams. These are closely tied in with Collaboration
Diagrams but are focused more on states that an item such as an object can be in and how external and
internal events change that state .
461
VB6 UML
The first thing to note about sequence diagrams (and collaboration diagrams, for that matter) is that they are
usually drawn with a context in mind. The first time we use these diagrams is when we are designing how
our use cases will be handled. In this case the context is just the system as a whole. Later in the design we
will use sequence diagrams to understand how a particular object method behaves. In this case the context
is the method.
Here is an example of a sequence diagram scoped to a method together with the resultant code:
'Withdraw funds
theSource.WithdrawFunds theFunds
'Deposit Funds
theTarget.DepositFunds theFunds
'commit
theTransManager.Commit
Exit Sub
TransferError:
462
UML to VB Mapping
'Abort Transaction
theTransManager.Abort
End Sub
Notice that we have slightly changed the logic so that we can make use of VB ' s built in error system. This
is OK as long as we don ' t impact the core interaction design.
7.2 Interactions
The horizontal interactions connecting the object instances tell us what operations on the objects need to be
called (they also tell us what extra operations we need to add to our static model). The order of these
interactions is crucial– this is the main point behind ( message) sequence diagrams. Each horizontal line
represents a single message and this represents an actual operation call. So we need to map this call into an
actual VB operation call. The next question is ' which VB method makes the call?'
By studying the diagram it is usually easy to see which previous operation is making the call.
7.3 Pseudo-Code
The left-hand side of a sequence diagram usually contains pseudo-code that provides more clues about how
the operations used on the diagram are actually behaving. This code is usually stated in three basic control
constructs: sequence, selection and iteration. The Developer can use these constructs to write the skeleton
of the related method' s logic. So the mapping here is quite straightforward. Once the Diagram has matured
somewhat, the Developer will use the pseudo-code as the basis for the body of the related VB method.
Collaboration diagrams do however allow us to show which associations between two objects are being
used to perform the interaction. This will be reflected in the names of the objects being manipulated in the
procedure, i.e. if the objects have a ' m_ ' naming prefix, then it implies that the objects are defined at class
scope – not the procedure scope.
463
VB6 UML
Depends on
state Abstract – see notes
implementation
Transition Depends on
Abstract – see notes
implementation
State modeling is one of the more specialized areas of the UML. Although all objects in your system have
state, many applications such as client-server applications don't contain objects with very much state so the
need to model state is less important.
If you are using VB in a real-time systems environment, then understanding how to map statecharts to VB
will be very useful to you.
As was suggested in the introduction, statecharts have no straight mapping to VB. The main use behind
statecharts is to understand clearly how objects with complex state behave. Looking at the source code of a
complex object isn ' t very intuitive. So, once you' ve created your statechart and you are happy with it, what
comes next?
464
UML to VB Mapping
Alternatively, if the object in question is going to have a particularly complex state, then it is sometimes
worthwhile implementing an explicit ' Finite State Machine ' inside the object. What we do here is create a
machine that is driven from a table loaded with information about what to do for a particular combination
of state and event. It is also possible with this technique to change this data at run-time thus altering the
dynamic behavior of the object. (This technique is akin to data-driven programming, where the data is
partially controlling the program flow.)
8.3 An Example
As always, the best way to understand the difference in implementation is to see some examples.
Let ' s start by defining a simple statechart for a car' s security system. Here is the Car's static class model,
showing the objects involved in the state machine activities:
::RemoteKey
1
PressButton
TuneToCar( in aCar : Car )
1 CarLock
::Car
1 1 ::CentralLocking
- Locked : Boolean
- AlarmOn : Boolean myCentralLocking ToggleLock
+ StartEngine
+ StopEngine
::Alarm
- SoundAlarm 1 1
+ ResetAlarm TurnOn
myAlarm
+ <<get>> CentralLocking TurnOff
Now, the part we are interested in is the state of the Car object as shown:
Initial
Create
LockSignal / LockCar
Unlocked Locked
UnlockSignal / UnlockCar
StartEngineSignal / SoundAlarm
465
VB6 UML
'initialise self
Private Sub Class_Initialize()
'create my composite objects
Set m_myAlarm = New Alarm
Set m_myCentralLocking = New CentralLocking
466
UML to VB Mapping
Next, let' s look at the code for the Alarm (quite simple):
RaiseEvent Unlocked
Else
'unlocked - now lock
Debug.Print "Click"
m_Locked = True 'set unlocked state
RaiseEvent Locked
End If
End Sub
467
VB6 UML
Considering the complexity of the statechart (low!) the example is quite easy to follow. If the Car had
more states and events (which it could be if we considered the whole Car), then an explicit version might
be preferable.
468
UML to VB Mapping
'initialise self
Private Sub Class_Initialize()
'create my composite objects
Set m_myAlarm = New Alarm
Set m_myCentralLocking = New CentralLocking
Set m_MyFSM = New CarFSM
m_MyFSM.LinkCar Me
'actions -----------------------------------------------------------
469
VB6 UML
The CentralLocking, Alarm, and RemoteKey classes are the same but we have now introduced a
separate state machine that will drive the Car object:
470
UML to VB Mapping
471
VB6 UML
The state/event/action information has been stored in a two-dimensional table. To find out what actions
need to be performed on a given event, the state machine just indexes into this table using the current state
and event just received.
Each entry in the table contains a list of actions to perform in sequence, terminated by the special action
"NoAction". Each entry also contains "Next State", which is the state that the Car to enter after performing
the actions.
Note that the finite state machine (FSM) is part of the Car' s implementation. The client code has remained
the same in both the examples. Clients shouldn ' t be aware of how you have implemented the state of the
object. (This is the power of object encapsulation.)
In the example it was decided that the state machine should be a separate abstraction. By doing this we have
made the Car class simpler to understand. However this decision has introduced some compromises. For
instance, the actions that Car can perform can no longer be private as the state machine ( CarFSM class)
needs to call these procedures. These procedures now have ' Friend ' access to at least ensure that they are
not visible outside of the component - only inside.
In VB terms, a single activity diagram usually maps to a single VB method. You should use activity
diagrams only when dealing with complex operations that are easier to understand visually than in code.
The interesting items on activity diagrams are action and transitions . An action usually maps to either a
single VB statement or a cohesive group of statements. We can see how this relates to our previous
example. The procedure call to SoundAlarm can be treated as a single action in an activity diagram.
Transitions are simply the invisible transition from one VB statement to the next so they don' t have any
concrete mapping to deal with.
The text associated with an action , can also be conveniently mapped to a comment near to the statements,
particularly when the statements themselves aren ' t self-explanatory.
472
UML to VB Mapping
For completeness, here is an example activity diagram. This is the PerformUseCase operation on the
<<controller>> class TransferFunds we looked at earlier:
Begin
Begin Transaction
Withdraw Funds
Deposit Funds
End
Note that the code mapped from this is identical to that produced from the sequence diagram for the same
operation, so we won' t repeat it.
Interface
' PublicNotCreatable' Class
473
VB6 UML
Still, when developers talk about components, we are usually referring to either physical components, i.e.
Active X components, DLLs, etc. or logical components, i.e. Business Objects, such as Account, Sale,
etc., contained and exposed from these physical components .
Logical components expose services that applications can use, e.g. Account exposes the service Withdraw
Cash.
Physical components, on the other hand, are the packaging and deployment of these logical components and
their partitioning is influenced by the technical requirements of the target system.
IDocument
IPersistent
IPrintable Document
474
UML to VB Mapping
For mapping purposes, it is probably easier to look at an alternative but more familiar representation:
::Word Processing
«interface» Implements
IDocment
«interface» Implements
IPersistent
«interface» Implements
IPrintable
Document
Components also have a private implementation, which typically involves one or more private classes that
carry out the work for the component. The client code using the component via interfaces is completely
unaware of how the services requested are being handled internally. This is the key strength of component
development.
Any VB class in a Project that has an instancing property that is not private can be treated as a logical
component. The classes in the project that have an instancing property of ' Private' are usually there to
provide the implementation of the exposed components.
If we consider the Car example introduced in the Statechart mapping, the Car could be exposed as a
logical component and the CarFSM would be part of the private implementation.
::<<ActiveX EXE>>Word
IApplication
Application Indexer
IDocument
IParagraph
Paragraph
The UML can show a component offering many interfaces to its prospective users. Here is an example
475
VB6 UML
physical component together with exposed logical components and two hidden implementation classes:
However VB Developers should note that it isn ' t really the UML component that is offering interface -
rather the classes within the component (project) that are marked as public. This is something that the UML
is not clear about. It is likely that the distinction will be clarified in later drafts.
10.4 Stereotypes
The UML comes with a standard set of stereotypes for components:
An <<executable>> stereotype of component simply states that the item represents an executable file, such
as ' program.exe' , and can be individually deployed onto a node on a network.
A <<file>> component stereotype is nothing more than a physical file. However, this notation gives us the
opportunity to model files and more importantly, show where files live on a network of nodes in the system
we are building.
Most CASE tools extend the range of stereotypes available for components to cover those supported by
target programming languages. Visual Basic, for instance, is capable of creating the following component
stereotypes:
Stereotype Meaning
<<ActiveX DLL>> An ActiveX server packaged as a dynamic link library.
<<ActiveX EXE>> An ActiveX server packaged as an executable program.
<<EXE>> A regular Win32 executable (without COM).
<<DLL> A regular Win32 dynamic link library.
476
UML to VB Mapping
477
VB6 UML
478
Creating a VB Code Generator
Add-In
In this appendix I will show you how to create a Visual Basic application that will read from a database and
generate code for a three-tier DNA application which will connect to this database. This code generator can
be used to create the basis of any Visual Basic application, including the ones you are currently building.
As you have all of the code here, you can customize the code generator for your needs.
When building a Visual Basic code generator application, you will actually have two projects, the
application to generate the code and the application that will be generated. The application that is to be
generated must be built from patterns so that we can use these patterns to generate the code.
We will covered the basic functioning of the code and provided UML class diagrams for all of the modules
that are generated in Chapter 9, and the workings of this code are covered in detail in the VB6 UML book.
I have chosen to use an Access database for generating the code. I made this choice because most Visual
Basic programmers are familiar with working with Access databases. We will generate an object for each
table in the database. The field names in the tables will become the properties of the objects. The methods
will be the standard methods for a recordset.
Instead of using an Access database, we could use the Microsoft Repository as the source of information for
the code generator. The Microsoft Repository is a file that allows information, such as certain UML
diagrams, to be stored in a universal format. Thus, regardless of the UML tool I am using, I can export my
diagrams to the repository in one standard format. Using this standard format, I can read the data out.
Appendix C
If you wanted to use the repository for my code generator instead of the Access database, you would have
to write one extra code module that reads the repository and adds tables to an Access database. The table
names would be the names of the classes you want to generate and the table fields would be the names of
the attributes you want the class to have. Thus, the following project I am providing can easily be expanded
to generate code from any source; you just have to convert the information into Access tables.
Before we look at code generator itself, we must first look at the Visual Basic add-in object hierarchy. You
might imagine that there would be tons of information on how to this, but actually, there is very little
information out there. We will start by building a Visual Basic add-in and then move onto getting
information on an Access database.
The most critical piece of information that we put into the add-in .ini file is the identifier for the add-in.
We will be using the standard project name dot class name. Let us begin by creating a function to add the
information into the .ini file. Create a new Visual Basic ActiveX DLL project and call it
CodeGenerator. Call the default class CodeGeneratorClass. Add a .bas module to the project and
call it basMain. We are going to use an API function called WritePrivateProfileString to write
to the .ini file. If you are not familiar with API functions, they are functions that are provided by
Windows. We can use these functions in our Visual Basic application by declaring the function in our
Visual Basic application in a .bas module using the Declare keyword. Add the following code to
basMain to declare the windows function WritePrivateProfileString in your Visual Basic
project:
If you are wondering what all of this means, kernel32 is the DLL where the function resides. The alias,
WritePrivateProfileStringA, is the real name of the function (there are usually two versions, one
for Unicode strings and one for regular strings). WritePrivateProfileString is the name we give it
and which we will use in our code. ApplicationName is the name of the section that you want to add
this information to KeyName is the information you want to put into the ApplicationName section
KeyDefault is the default value of ApplicationName, and FileName is the name of the .ini file
you want to put the information in. In our case, ApplicationName is Add-Ins32, the KeyName is
CodeGenerator.CodeGeneratorClass, the KeyDefault is 0 and the name of the file is
VBADDIN.INI. You can probably find VBADDIN.INI in your Windows directory. My VBADDIN.INI
has the following entries:
480
Creating a VB Code Generator Add-In
[Add-Ins32]
MTxAddIn2.RegRefresh=3
DTCFrameWork.AddIn=0
RVBAddInMenus.Connector=0
RVBAddIn.Connector=0
vbscc=3
VBObjTest.Application.1=0
VisioUMLSolution.VisioUMLSolution=3
Of course, we could manually enter the name of our component into the .ini file, but it is safer to use the
Windows API function.
481
Appendix C
I have changed the names of the parameter in the function declaration. You can do this as long as you have
the right number of parameters and each parameter has the correct data type.
API functions can extend the Visual Basic language. For the most part these functions have been wrapped
by functions within Visual Basic. Sometimes, though, using an API function is the only way to get the
information you require or to do what you need to do.
Next we will add a function that uses our Windows API, called AddToIni, to basMain:
We will show an easy way to use this sub later. The next step is to get access to the Visual Basic IDE object
hierarchy so that we can manipulate objects in the Visual Basic IDE. To do this, we will need access to the
extensibility object.
We will make an ActiveX control project for each table in the database. We will therefore need to add a
new project to the group for each table.
As we will discuss in more detail below, each project will consist of two classes, the control and a .bas
module. Therefore, we will need the ability to add modules to our Visual Basic projects.
We will need to add references to our project.
We will need to change the names of the project and the parts of the project.
482
Creating a VB Code Generator Add-In
We have included the methods that we will be using with the objects.
You can see that the VBE object is the main managing object of the Visual Basic IDE. The VBProjects
object manages VBProject objects, the References object manages Reference objects and the
VBComponents object manages VBComponent objects. As you can see, this object hierarchy is built just
like the business services components we discussed in Chapter 8, except that this hierarchy is a little more
complex and it has more objects and levels. If you look at the managing classes in the Visual Basic object
browser, you will see that they consist primarily of methods. The managed classes are primarily properties.
The Add method of the VBProjects object, which will return a new VBProject object.
The AddFromGUID method of the References object, which will add a new reference object to the
project object based on the GUID of the reference.
The Item method of the VBComponents object which will return one of the project's components,
such as a class or a form.
The AddFromString method of the CodeModule object that allows you to use a string to add code
to a module.
Now let us take a look at the CodeGenerator project that we will use to create this project.
Finishing BasMain
We will need some information from the database so we can know how to write our functions properly.
Remember, we are using tables from an Access database as the basis for our components. Therefore, we
will need to know the table name so that we can set the name of our component to it. We will also have to
know the names of the fields for our properties and we will have to know the data types for each property.
We will also need to store information on the queries that will be used to get the information from the
database. To help keep track of all of this information, we will add the following enumerated types to the
declarations section of the basMain module:
It is possible that the field names may have spaces or other characters that will have to be removed if they
are going to be used as names of classes, .bas modules or variables in Visual Basic. To do this, we will
need a function that strips out these characters. Add this function to basMain:
483
Appendix C
This function takes the string array parameter r_sFieldNames() and places names into the array that do
not have spaces. The r_uFieldInfo parameter is filled with all of the field names from the table that a
business object is currently being built from. The For loop enumerates through all of the fields that are in
the r_uFieldInfo variable. Within the For loop we set the current r_sFieldNames() array member
equal to the current r_uFieldInfo array member. The Do loop enumerates through the name of the field
until all of the spaces have been removed. The Left and Right statements simple divide the string up into
two pieces, the section before the space and the section after the space, and then join the two pieces
together again.
In our generated code, the declarations in the .bas module for the customer component will look as
follows:
484
Creating a VB Code Generator Add-In
Option Explicit
For our code generator, we need to find a way to generate these declarations for any component we are
generating. Looking at the error-enumerated type, we can see the first three are general errors. We can
include these three errors in all of the classes to give the developer a place to add the rest of the errors.
The constants are based on the names of the fields. Thus, if we move through the fields, we can create a
template string that will give us all of the public constants. The template for these would look as follows:
The last two constants are used for the where clause to create groups. In the case of customer, we can
choose all customers or customers whose contact title equals some value. To simplify things, we will only
create a where clause from the primary key. If the developer needs additional where clause items, they can
add them.
Begin by creating a function called CreateDeclarations. The basis for this code module is the
following code:
485
Appendix C
The first parameter is a FieldInformation object which will have information on the fields in the table
that is currently being used to build a business object. The primary key will be used to make where clauses.
The table name is needed to make constants.
The strFieldNames variable will be passed into the CleanFields function so it will hold the names
of the fields without spaces. The strCode variable will be the variable we will use to hold the string with
all of the declarations.
Now, we can actually start building the code for the module. We want to create an enumerated type with
possible errors for this object. We want the enumerated type’s name to be based on the table name so we
will add that into the name of the enumerated type. First, though, we need to remove any spaces from the
name:
strCode = strCode & " errChangeFieldNoEdit = 1001" & Chr(13) & Chr(10)
strCode = strCode & " errEditPrimaryKey = 1002" & Chr(13) & Chr(10)
strCode = strCode & " errPrimaryKeyLength = 1003" & Chr(13) & Chr(10)
strCode = strCode & "End Enum" & Chr(13) & Chr(10)
We want the names of the fields to all be placed into one place. To do this, we will create constants for each
field name using the names stored in the strFieldNames array. Each constant will begin with
g_cstrField followed by the name of the field:
486
Creating a VB Code Generator Add-In
Finally, we will make a constant that will be used to make a where clause based on the primary key and set
the function to the string we have built.
The final result of this function for the Northwind database for the Customers class would look as
follows:
When making a code generator, you would start with the coded project. Using this and the UML diagrams
as a template, you can find the patterns that you will need to build your code. We will be doing this with the
rest of the code from the project in the VB6 UML book. You can compare the generalized code in the
generator with the code in the VB6 UML book. Where the code sample used generic terms, we will copy it
exactly. Where specific names are used, such as customer or address, we will need to create generic strings
and create loops.
487
Appendix C
Let us now add the function to read errors. Add the following code to BuildBas:
End Function
488
Creating a VB Code Generator Add-In
The code that we will generate will have a disconnected Recordset object that can be accessed by this
class and also by the managing class. This recordset will be passed to controls such as textboxes or
gridboxes. The recordset will also be used to retrieve the values of the properties, instead of keeping private
variables for all of the properties. The event RefreshDataMember will alert the managing class that it
needs to refresh the bound controls. EditInProgress will alert the managing class that an edit has been
started by changing a field value. Let us now add the class Initialize event.
Class Initialize
We will have to initialize our objects in the Class_Initialize event. Add the function
CreateInitialize to the BuildBottom .bas module to generate the Class_Intialize event:
strCode =
" Private Sub Class_Initialize()" & Chr(13) & Chr(10)
strCode =
strCode & " m_blnValidatingFieldChange = False" & Chr(13) & Chr(10)
strCode =
strCode & " m_blnIgnoreFieldChange = False" & Chr(13) & Chr(10)
strCode =
strCode & " m_blnInFieldChange = False" & Chr(13) & Chr(10) & _
Chr(13) & Chr(10)
strCode = strCode & " On Error GoTo InitializeError" & Chr(13) & Chr(10)
strCode = strCode & " m_eEditMode = adEditNone" & Chr(13) & Chr(10)
strCode = strCode & " Set m_recManagedObjects = New ADODB.Recordset" & _
Chr(13) & Chr(10)
strCode = strCode & " Exit Sub" & Chr(13) & Chr(10)
strCode = strCode & "InitializeError:" & Chr(13) & Chr(10)
strCode = strCode & " MsgBox " & Chr(34) & "Error In Class Initialize" & _
Chr(34) & Chr(13) & Chr(10)
strCode = strCode & "End Sub"
CreateInitialize = strCode
End Function
Class Terminate
We will also need to clean up when the class is done. Add the following code to make our
Class_Terminate event:
489
Appendix C
490
Creating a VB Code Generator Add-In
We will begin by coding the event exactly as an ADO recordset would create it:
Next we will set up error handling and check to see if the flag that tells us to not validate field changes has
been set:
strCode = strCode & " On Error GoTo FieldChangeError" & Chr(13) & Chr(10)
strCode = strCode & " If m_blnIgnoreFieldChange = True Then" & Chr(13) & _
Chr(10)
If the flag is set to true, this change occurred by a property changing the field. In this case, we want to reset
it to false, refresh all controls bound to this object and the managing object and exit the function without
validating the fields:
When using data provider classes, we must call the DataMemberChanged function to refresh the controls
bound to this object:
We must now pass a message up to the managing class that it must refresh all of the controls that it is
bound to:
strCode = strCode & " RaiseEvent RefreshDataMember" & Chr(13) & Chr(10)
strCode = strCode & " Exit Sub" & Chr(13) & Chr(10)
strCode = strCode & " End If" & Chr(13) & Chr(10)
If this field change is being called because this routine has made a change to the field value, we will end up
in an infinite loop. To check this we check the m_bInFieldChange flag. If it is true, this routine has
been called by a change in a previous call to this routine and we should exit the function:
strCode = strCode & " If m_blnInFieldChange = True Then" & Chr(13) & _
Chr(10)
strCode = strCode & " m_blnInFieldChange = False" & Chr(13) & Chr(10)
strCode = strCode & " Exit Sub" & Chr(13) & Chr(10)
strCode = strCode & " End If" & Chr(13) & Chr(10)
491
Appendix C
If there are no records to validate or the recordset is not open, there is nothing to check, so we should exit:
If we are in the middle of deleting a record, we do not need to validate a field change:
strCode = strCode & " If EditMode = adEditDelete Then" & Chr(13) & Chr(10)
strCode = strCode & " Exit Sub" & Chr(13) & Chr(10)
strCode = strCode & " End If" & Chr(13) & Chr(10)
If an edit has been started by changing a field in the recordset, we need to set the EditMode property:
strCode = strCode & " If EditMode = adEditNone Then" & Chr(13) & Chr(10)
strCode = strCode & " EditMode = adEditInProgress" & Chr(13) & Chr(10)
strCode = strCode & " RaiseEvent EditInProgress(adEditInProgress)" & _
Chr(13) & Chr(10)
strCode = strCode & " End If" & Chr(13) & Chr(10)
Finally, if we get to this point it means that we are doing an AddNew or Edit and we need to now validate
the field. To do this we will pass the fields and the recordset into the ValidateFields function. If this
function returns false, the record change is not valid:
If ValidateFields comes back false, this was an invalid change and we must set the value back to the
original field value:
strCode = strCode & " m_blnInFieldChange = True" & Chr(13) & Chr(10)
strCode = strCode & " m_recManagedObjects.Fields(Fields(0).Name).Value" & _
" = _ " & Chr(13) & Chr(10)
strCode = strCode & " pRecordset.Fields(Fields(0).Name).UnderlyingValue" & _
Chr(13) & Chr(10)
strCode = strCode & " m_blnInFieldChange = False" & Chr(13) & Chr(10)
strCode = strCode & " End If" & Chr(13) & Chr(10)
492
Creating a VB Code Generator Add-In
strCode = strCode & " Exit Sub" & Chr(13) & Chr(10)
strCode = strCode & "FieldChangeError:" & Chr(13) & Chr(10)
strCode = strCode & " Err.Raise Err.Number, " & Chr(34) & "FieldChange " & _
Chr(34) & " & Err.Source, Err.Description" & Chr(13) & Chr(10)
strCode = strCode & "End Sub" & Chr(13) & Chr(10)
CreateChangedField = strCode
End Function
As you can see, this is no different than coding the real module, except everything is wrapped in quotes and
has a Chr(13) & Chr(10) at the end to add a carriage return and line feed.
We will need to use the CleanFields function again as we want to use names without spaces for our
property names:
For each member in the fields array, we will need to add a property. To get the total number of items in a
one-based array (an array that starts with item 1) we can use Ubound. We will show you later how we built
our arrays to be one-based instead of zero-based.
We will now create the Property Get using the field name without spaces and the data type parameter
of the r_uFieldInfo user-defined type:
strCode = strCode & " On Error Resume Next" & Chr(13) & Chr(10)
strCode = strCode & " " & strFieldNames(lngFieldsCounter) & _
"= ItemsRecordset.Fields(g_cstrField" & _
strFieldNames(lngFieldsCounter) & ")" & Chr(13) & Chr(10)
strCode = strCode & " If Err.Number <> 0 Then" & Chr(13) & Chr(10)
493
Appendix C
strCode = strCode & " If Err.Number <> 3265 Then" & Chr(13) & _
Chr(10)
strCode = strCode & " Err.Raise Err.Number, " & Chr(34) & _
strFieldNames(lngFieldsCounter) & "Get" & Chr(34) & _
", Err.Description" & Chr(13) & Chr(10)
strCode = strCode & " End If" & Chr(13) & Chr(10)
strCode = strCode & " End If" & Chr(13) & Chr(10)
strCode = strCode & "End Property" & Chr(13) & Chr(10)
Next
CreateGetLet = strCode
End Function
494
Creating a VB Code Generator Add-In
Miscellaneous Properties
We still have several properties, such as EditMode, that need to be created. We will lump these together
into one function:
495
Appendix C
Enum TableName
e_Categories = 0
e_Customers = 1
e_Employees = 2
e_Order Details = 3
e_Orders = 4
e_Products = 5
e_Shippers = 6
e_Suppliers = 7
End Enum
The v_sTableName parameter is the name of the table without spaces of the component it is being built
from:
We will now build the BOFActionType and EOFActionType enumerated types to determine the
behaviour at the end of file and beginning of file:
strCode = strCode & "Public Enum BOFActionType" & Chr(13) & Chr(10)
strCode = strCode & " adMoveFirst = 0" & Chr(13) & Chr(10)
strCode = strCode & " adStayBOF = 1" & Chr(13) & Chr(10)
strCode = strCode & "End Enum" & Chr(13) & Chr(10)
strCode = strCode & "Public Enum EOFActionType" & Chr(13) & Chr(10)
strCode = strCode & " adMoveLast = 0" & Chr(13) & Chr(10)
strCode = strCode & " adStayEOF = 1" & Chr(13) & Chr(10)
strCode = strCode & " adAddNew = 2" & Chr(13) & Chr(10)
strCode = strCode & "End Enum" & Chr(13) & Chr(10)
496
Creating a VB Code Generator Add-In
Finally, we add the constants and variables needed by the managing class:
497
Appendix C
strCode = strCode & "Public Sub GetProxy()" & Chr(13) & Chr(10)
strCode = strCode & " Set m_objDataSpace = New RDS.DataSpace" & _
Chr(13) & Chr(10)
strCode = strCode & " m_objDataSpace.InternetTimeout = 30000" & _
Chr(13) & Chr(10)
strCode = strCode & " Set m_objProxy = m_objDataSpace.CreateObject _" & _
Chr(13) & Chr(10)
strCode = strCode & " (" & Chr(34) & "prjServer.clsServer" & _
Chr(34) & ", " & Chr(34) & Chr(34) & ")" & Chr(13) & Chr(10)
strCode = strCode & "End Sub" & Chr(13) & Chr(10) & Chr(13) & Chr(10)
498
Creating a VB Code Generator Add-In
The next property gets the bottom class. As the name of the bottom class will be based on the table name,
we will need to use the v_sTableName parameter to build the next line of code:
strCode = strCode & "Public Property Get Item() As cls" & v_sTableName & _
Chr(13) & Chr(10)
strCode = strCode & " Set Item = m_objManagedObject" & Chr(13) & Chr(10)
strCode = strCode & "End Property" & Chr(13) & Chr(10) & Chr(13) & Chr(10)
strCode = strCode & "Public Property Get ItemCount() As Long" & Chr(13) & _
Chr(10)
strCode = strCode & " ItemCount =" & _
" m_objManagedObject.ItemsRecordset.RecordCount" & Chr(13) & Chr(10)
strCode = strCode & "End Property" & Chr(13) & Chr(10) & Chr(13) & Chr(10)
strCode = strCode & "Private Sub UpdateManagedObjects()" & Chr(13) & Chr(10)
strCode = strCode & " On Error GoTo UpdateManagedObjectsError" & _
Chr(13) & Chr(10)
strCode = strCode & " Set m_objManagedObject.ItemsRecordset = _" & _
Chr(13) & Chr(10)
499
Appendix C
Again, we will need to use the table name in the retrieve methods used with the data services component:
strCode = strCode & "Public Sub Refresh()" & Chr(13) & Chr(10)
We are now starting the code that will require the v_bPrimKeyNum Boolean:
If v_bPrimKeyNum Then
strCode = strCode & " Dim strPrimaryKeyValue As Long" & Chr(13) & Chr(10)
Else
strCode = strCode & " Dim strPrimaryKeyValue As String" & Chr(13) & Chr(10)
End If
strCode = strCode & " If m_objManagedObject.ItemsRecordset.State = " & _
"adStateOpen Then" & Chr(13) & Chr(10)
strCode = strCode & " If Not m_objManagedObject.ItemsRecordset.BOF " & _
" And _" & Chr(13) & Chr(10)
strCode = strCode & " Not m_objManagedObject.ItemsRecordset.EOF " & _
" And _" & Chr(13) & Chr(10)
strCode = strCode & " Not IsNull(m_objManagedObject.ItemsRecordset." & _
"Fields(PrimaryKey)) Then" & Chr(13) & Chr(10)
strCode = strCode & " strPrimaryKeyValue = _" & Chr(13) & Chr(10)
strCode = strCode & " m_objManagedObject.ItemsRecordset.Fields " & _
" (PrimaryKey)" & Chr(13) & Chr(10)
strCode = strCode & " End If" & Chr(13) & Chr(10)
strCode = strCode & " End If" & Chr(13) & Chr(10)
strCode = strCode & " UpdateManagedObjects" & Chr(13) & Chr(10)
500
Creating a VB Code Generator Add-In
If v_bPrimKeyNum Then
strCode = strCode & " If strPrimaryKeyValue <> 0 Then" & Chr(13) & Chr(10)
strCode = strCode & " m_objManagedObject.ItemsRecordset.Find " & _
"PrimaryKey & " & Chr(34) & "=" & Chr(34) & " & _" & _
Chr(13) & Chr(10) & _
"strPrimaryKeyValue " & ", , , 1" & Chr(13) & Chr(10)
Else
strCode = strCode & " If strPrimaryKeyValue <> " & Chr(34) & _
Chr(34) & " Then" & Chr(13) & Chr(10)
strCode = strCode & " m_objManagedObject.ItemsRecordset.Find " & _
" PrimaryKey & " & Chr(34) & "='" & Chr(34) & " & _" & _
Chr(13) & Chr(10) & "strPrimaryKeyValue & " & Chr(34) & "'" & _
Chr(34) & ", , , 1" & Chr(13) & Chr(10)
End If
strCode = strCode & " End If" & Chr(13) & Chr(10)
strCode = strCode & "End Sub" & Chr(13) & Chr(10)
strCode = strCode & "Public Sub Update()" & Chr(13) & Chr(10)
If v_bPrimKeyNum Then
strCode = strCode & " Dim strPrimaryKeyValue As Long" & Chr(13) & Chr(10)
Else
strCode = strCode & " Dim strPrimaryKeyValue As String" & Chr(13) & Chr(10)
End If
strCode = strCode & " On Error GoTo UpdateError" & Chr(13) & Chr(10)
strCode = strCode & " If m_objManagedObject.ItemsRecordset.State = " & _
"adStateOpen And _" & Chr(13) & Chr(10)
strCode = strCode & " m_objManagedObject.ItemsRecordset.EditMode " & _
" <> adEditDelete And (Not IsNull(m_objManagedObject." & _
"ItemsRecordset.Fields(PrimaryKey))) Then" & Chr(13) & Chr(10)
strCode = strCode & " If " & " m_objManagedObject.ItemsRecordset." & _
"RecordCount <> 0 Then" & Chr(13) & Chr(10)
strCode = strCode & " strPrimaryKeyValue = _" & Chr(13) & Chr(10)
strCode = strCode & " m_objManagedObject.ItemsRecordset.Fields" & _
" (PrimaryKey)" & Chr(13) & Chr(10)
strCode = strCode & " End If" & Chr(13) & Chr(10)
strCode = strCode & " End If" & Chr(13) & Chr(10)
strCode = strCode & " If EditMode <> adEditNone Then" & Chr(13) & Chr(10)
strCode = strCode & " Set m_objManagedObject.ItemsRecordset = " & _
"m_objProxy.UpdateRecordset(UserName, _" & Chr(13) & Chr(10)
strCode = strCode & " Password, m_objManagedObject.ItemsRecordset," & _
"m_eRecordsetName, _" & Chr(13) & Chr(10)
strCode = strCode & " WhereClause)" & Chr(13) & Chr(10)
strCode = strCode & " EditMode = adEditNone" & Chr(13) & Chr(10)
strCode = strCode & " RaiseEvent ChangeManagedObjects" & Chr(13) & _
Chr(10)
strCode = strCode & " End If" & Chr(13) & Chr(10)
501
Appendix C
If v_bPrimKeyNum Then
strCode = strCode & " If strPrimaryKeyValue <> 0 Then" & Chr(13) & Chr(10)
strCode = strCode & " m_objManagedObject.ItemsRecordset.Find " & _
" PrimaryKey & " & Chr(34) & "=" & Chr(34) & " & _" & Chr(13) & _
Chr(10) & "strPrimaryKeyValue " & ", , , 1" & Chr(13) & Chr(10)
Else
strCode = strCode & " If strPrimaryKeyValue <> " & Chr(34) & _
Chr(34) & " Then" & Chr(13) & Chr(10)
strCode = strCode & " m_objManagedObject.ItemsRecordset.Find " & _
"PrimaryKey & " & Chr(34) & "='" & Chr(34) & " & _" & _
Chr(13) & Chr(10) & "strPrimaryKeyValue & " & Chr(34) & "'" & _
"Chr(34) & , , , 1" & Chr(13) & Chr(10)
End If
strCode = strCode & " End If" & Chr(13) & Chr(10)
strCode = strCode & " Exit Sub" & Chr(13) & Chr(10)
strCode = strCode & "UpdateError:" & Chr(13) & Chr(10)
strCode = strCode & " Err.Raise Err.Number, " & Chr(34) & "Update: " & _
Chr(34) & " & Err.Source, Err.Description" & Chr(13) & Chr(10)
strCode = strCode & "End Sub" & Chr(13) & Chr(10) & Chr(13) & Chr(10)
If v_bPrimKeyNum Then
strCode = strCode & " Dim strPrimaryKeyValue As Long" & Chr(13) & Chr(10)
strCode = strCode & " If v_strPrimaryKey = 0 Then" & Chr(13) & Chr(10)
Else
strCode = strCode & " Dim strPrimaryKeyValue As String" & Chr(13) & Chr(10)
strCode = strCode & " If v_strPrimaryKey = " & Chr(34) & Chr(34) & _
"Then" & Chr(13) & Chr(10)
End If
strCode = strCode & " Exit Function" & Chr(13) & Chr(10)
strCode = strCode & " End If" & Chr(13) & Chr(10)
If v_bPrimKeyNum Then
strCode = strCode & " If InStr(v_strPrimaryKey, " & Chr(34) & "'" & _
Chr(34) & ") > 0 Then" & Chr(13) & Chr(10)
strCode = strCode & " v_strPrimaryKey = " & _
"Mid(v_strPrimaryKey, 1, InStr(v_strPrimaryKey, " & Chr(34) & _
"'" & Chr(34) & ") - 1)" & Chr(13) & Chr(10)
strCode = strCode & " Else" & Chr(13) & Chr(10)
strCode = strCode & " v_strPrimaryKey = v_strPrimaryKey" & _
Chr(13) & Chr(10)
strCode = strCode & " End If" & Chr(13) & Chr(10)
End If
502
Creating a VB Code Generator Add-In
If v_bPrimKeyNum Then
strCode = strCode & " ItemsRecordset.Find PrimaryKey & " & _
Chr(34) & "=" & Chr(34) & " & _" & Chr(13) & Chr(10) & _
"v_strPrimaryKey " & ", , , 1" & Chr(13) & Chr(10)
Else
strCode = strCode & " ItemsRecordset.Find PrimaryKey & " & Chr(34) & _
"='" & Chr(34) & " & _" & Chr(13) & Chr(10) & _
"v_strPrimaryKey & " & Chr(34) & "'" & _
Chr(34) & ", , , 1" & Chr(13) & Chr(10)
End If
strCode = strCode & "Public Sub Delete()" & Chr(13) & Chr(10)
strCode = strCode & " On Error GoTo DeleteError" & Chr(13) & Chr(10)
strCode = strCode & " If EditMode = adEditNone Then" & Chr(13) & Chr(10)
strCode = strCode & " m_objProxy.UpdateRecordset UserName, " & _
" Password, _" & Chr(13) & Chr(10)
strCode = strCode & " m_objManagedObject.ItemsRecordset, " & _
" m_eRecordsetName, WhereClause, True" & Chr(13) & Chr(10)
strCode = strCode & " RaiseEvent ChangeManagedObjects" & Chr(13) & _
Chr(10)
strCode = strCode & " Else" & Chr(13) & Chr(10)
strCode = strCode & " GetErrorText " & Chr(34) & _
"CanNotDeleteDuringEdit/AddNew" & Chr(34) & Chr(13) & Chr(10)
strCode = strCode & " End If" & Chr(13) & Chr(10)
strCode = strCode & " Exit Sub" & Chr(13) & Chr(10)
strCode = strCode & "DeleteError:" & Chr(13) & Chr(10)
strCode = strCode & " Err.Raise Err.Number, " & Chr(34) & "Delete " & _
Chr(34) & "& Err.Source, Err.Description" & Chr(13) & Chr(10)
strCode = strCode & "End Sub" & Chr(13) & Chr(10) & Chr(13) & Chr(10)
strCode = strCode & "Public Sub AddNew()" & Chr(13) & Chr(10)
strCode = strCode & " On Error GoTo AddNewError" & Chr(13) & Chr(10)
strCode = strCode & " If EditMode = adEditNone Then" & Chr(13) & Chr(10)
strCode = strCode & " m_objManagedObject.ItemsRecordset.AddNew" & _
Chr(13) & Chr(10)
strCode = strCode & " EditMode = adEditAdd" & Chr(13) & Chr(10)
strCode = strCode & " Else" & Chr(13) & Chr(10)
strCode = strCode & " End If" & Chr(13) & Chr(10)
strCode = strCode & " Exit Sub" & Chr(13) & Chr(10)
strCode = strCode & "AddNewError:" & Chr(13) & Chr(10)
strCode = strCode & " Err.Raise Err.Number, " & Chr(34) & "AddNew " & _
Chr(34) & "& Err.Source, Err.Description" & Chr(13) & Chr(10)
503
Appendix C
strCode = strCode & "Public Sub Cancel()" & Chr(13) & Chr(10)
strCode = strCode & " If EditMode = adEditAdd Or EditMode = " & _
"adEditInProgress Then" & Chr(13) & Chr(10)
strCode = strCode & " ItemsRecordset.CancelUpdate" & Chr(13) & Chr(10)
strCode = strCode & " EditMode = adEditNone" & Chr(13) & Chr(10)
strCode = strCode & " End If" & Chr(13) & Chr(10)
strCode = strCode & "End Sub" & Chr(13) & Chr(10)
strCode = strCode & "Public Sub MoveFirst()" & Chr(13) & Chr(10)
strCode = strCode & " On Error GoTo MoveFirstError" & Chr(13) & Chr(10)
strCode = strCode & " If m_objManagedObject.ItemsRecordset Is Nothing " & _
"Then" & Chr(13) & Chr(10)
strCode = strCode & " Exit Sub" & Chr(13) & Chr(10)
strCode = strCode & " End If" & Chr(13) & Chr(10)
strCode =strCode & " If m_objManagedObject.ItemsRecordset.RecordCount " & _
"> 0 Then" & Chr(13) & Chr(10)
strCode = strCode & " m_objManagedObject.ItemsRecordset.MoveFirst" & _
Chr(13) & Chr(10)
strCode = strCode & " End If" & Chr(13) & Chr(10)
strCode = strCode & " Exit Sub" & Chr(13) & Chr(10)
strCode = strCode & "MoveFirstError:" & Chr(13) & Chr(10)
strCode = strCode & " Err.Raise Err.Number, " & Chr(34) & "Move First " & _
Chr(34) & "& Err.Source, Err.Description" & Chr(13) & Chr(10)
strCode = strCode & "End Sub" & Chr(13) & Chr(10) & Chr(13) & Chr(10)
strCode = strCode & "Public Sub MoveLast()" & Chr(13) & Chr(10)
strCode = strCode & " On Error GoTo MoveLastError" & Chr(13) & Chr(10)
strCode = strCode & " If m_objManagedObject.ItemsRecordset Is Nothing " & _
"Then" & Chr(13) & Chr(10)
strCode = strCode & " Exit Sub" & Chr(13) & Chr(10)
strCode = strCode & " End If" & Chr(13) & Chr(10)
strCode = strCode & " If m_objManagedObject.ItemsRecordset.RecordCount " & _
"> 0 Then" & Chr(13) & Chr(10)
strCode = strCode & " m_objManagedObject.ItemsRecordset.MoveLast" & _
Chr(13) & Chr(10)
strCode = strCode & " End If" & Chr(13) & Chr(10)
strCode = strCode & " Exit Sub" & Chr(13) & Chr(10)
strCode = strCode & "MoveLastError:" & Chr(13) & Chr(10)
strCode = strCode & " Err.Raise Err.Number, " & Chr(34) & "Move Last " & _
Chr(34) & "& Err.Source, Err.Description" & Chr(13) & Chr(10)
strCode = strCode & "End Sub" & Chr(13) & Chr(10) & Chr(13) & Chr(10)
strCode = strCode & "Public Sub MoveNext()" & Chr(13) & Chr(10)
strCode = strCode & " On Error GoTo MoveNextError" & Chr(13) & Chr(10)
strCode = strCode & " If m_objManagedObject.ItemsRecordset " & _
"Is Nothing Then" & Chr(13) & Chr(10)
strCode = strCode & " Exit Sub" & Chr(13) & Chr(10)
strCode = strCode & " End If" & Chr(13) & Chr(10)
strCode = strCode & " If m_objManagedObject.ItemsRecordset.EOF = False " & _
" Then" & Chr(13) & Chr(10)
strCode = strCode & " m_objManagedObject.ItemsRecordset.MoveNext" & _
Chr(13) & Chr(10)
strCode = strCode & " End If" & Chr(13) & Chr(10)
strCode = strCode & " If m_objManagedObject.ItemsRecordset.EOF = " & _
504
Creating a VB Code Generator Add-In
strCode = strCode & "Public Sub MovePrevious()" & Chr(13) & Chr(10)
strCode = strCode & " On Error GoTo MovePreviousError" & Chr(13) & Chr(10)
strCode = strCode & " If m_objManagedObject.ItemsRecordset Is Nothing " & _
"Then Exit Sub" & Chr(13) & Chr(10)
strCode = strCode & " If m_objManagedObject.ItemsRecordset.BOF Then" & _
Chr(13) & Chr(10)
strCode = strCode & " Select Case BOFAction" & Chr(13) & Chr(10)
strCode = strCode & " Case BOFActionType.adMoveFirst" & Chr(13) & Chr(10)
strCode = strCode & " m_objManagedObject.ItemsRecordset.MoveFirst" & _
Chr(13) & Chr(10)
strCode = strCode & " Case BOFActionType.adStayBOF" & Chr(13) & Chr(10)
strCode = strCode & " Exit Sub" & Chr(13) & Chr(10)
strCode = strCode & " Case Else" & Chr(13) & Chr(10)
strCode = strCode & " Exit Sub" & Chr(13) & Chr(10)
strCode = strCode & " End Select" & Chr(13) & Chr(10)
strCode = strCode & " Else" & Chr(13) & Chr(10)
strCode = strCode & " m_objManagedObject.ItemsRecordset.MovePrevious" & _
Chr(13) & Chr(10)
strCode = strCode & " End If" & Chr(13) & Chr(10)
strCode = strCode & " Exit Sub" & Chr(13) & Chr(10)
strCode = strCode & "MovePreviousError:" & Chr(13) & Chr(10)
strCode = strCode & " Err.Raise Err.Number, " & Chr(34) & _
"Move Previous Error" & Chr(34) & "& Err.Source, _" & _
Chr(13) & Chr(10)
strCode = strCode & " Err.Description" & Chr(13) & Chr(10)
strCode = strCode & "End Sub" & Chr(13) & Chr(10)
505
Appendix C
End Function
506
Creating a VB Code Generator Add-In
strCode = strCode & " m_str" & r_uTableInfo.PrimaryKey & "Equals=" & _
"m_def_" & r_uTableInfo.PrimaryKey & Chr(13) & Chr(10)
507
Appendix C
strCode = strCode & " e_" & v_sTableName & " , " & Chr(34) & _
Chr(34) & ", g_cstrField" & r_uTableInfo.PrimaryKey & ", g_cdm" & _
r_uTableInfo.PrimaryKey & Chr(13) & Chr(10)
strCode = strCode & "End Select" & Chr(13) & Chr(10)
strCode = strCode & " m_colDataMembersArray(v_eDataMember).Refresh" & _
Chr(13) & Chr(10)
strCode = strCode & " m_blnDataMembersInitialized" & _
"(v_eDataMember) = True" & Chr(13) & Chr(10)
strCode = strCode & " End If" & Chr(13) & Chr(10)
strCode = strCode & " Set Get" & v_sTableName & _
"Collection = m_colDataMembersArray(v_eDataMember)" & Chr(13) & _
Chr(10)
strCode = strCode & "End Function" & Chr(13) & Chr(10)
strCode = strCode & "Public Property Let " & r_uTableInfo.PrimaryKey & _
"Equals(ByVal v_strNew" & r_uTableInfo.PrimaryKey & "Equals" & _
" As _" & Chr(13) & Chr(10)
strCode = strCode & " String)" & Chr(13) & Chr(10)
strCode = strCode & " m_str" & r_uTableInfo.PrimaryKey & _
"Equals = v_strNew" & r_uTableInfo.PrimaryKey & "Equals" & _
Chr(13) & Chr(10)
strCode = strCode & "End Property" & Chr(13) & Chr(10)
BuildClass = strCode
End Function
508
Creating a VB Code Generator Add-In
Else
strFields = strFields & ",[" & r_Tables(lngTableCounter)." & _
"FieldInfo(lngFieldCounter).FieldName & "]"
End If
Next
strCode = strCode & " Private Const m_cstr" & _
r_TableInfo(lngTableCounter) & "Query =" & Chr(34) & _
"Select " & strFields & Chr(34) & " & _" & Chr(13) & Chr(10)
strCode = strCode & Chr(34) & " From " & _
r_Tables(lngTableCounter).TableName & Chr(34) & Chr(13) & Chr(10)
strTableName = r_Tables(lngTableCounter).TableName
strCode = strCode & " Private Const m_cstr" & _
r_TableInfo(lngTableCounter) & _
r_Tables(lngTableCounter).PrimaryKey & " As String = " _
& Chr(34) & r_Tables(lngTableCounter).PrimaryKey & _
Chr(34) & Chr(13) & Chr(10)
Next
strCode = strCode & " Private Const m_cstrDatabasePath As String = " & _
Chr(34) & "C:\Program Files\Microsoft Visual Studio" & _
"\VB98\NWIND.MDB" & Chr(34) & Chr(13) & Chr(10)
strCode = strCode & " Private m_objADOConnection As ADODB.Connection" & _
Chr(13) & Chr(10)
strCode = strCode & " Private m_strErrorDetails As String" & Chr(13) & Chr(10)
strCode = strCode & " Private m_strQueryString As String" & Chr(13) & Chr(10)
strCode = strCode & " Private m_objContext As ObjectContext" & Chr(13) & _
Chr(10)
strCode = strCode & " Implements ObjectControl" & Chr(13) & Chr(10)
strCode = strCode & "Private Sub ObjectControl_Activate()" & Chr(13) & Chr(10)
strCode = strCode & " Set m_objContext = GetObjectContext" & Chr(13) & Chr(10)
509
Appendix C
510
Creating a VB Code Generator Add-In
511
Appendix C
strCode = strCode & " " & Chr(34) & "Error Number:" & _
Chr(34) & " & " & "Err.Number & vbCrLf & " & Chr(34) & _
"Error Source: " & Chr(34) & " & _" & Chr(13) & Chr(10)
strCode = strCode & " " & Chr(34) & "ValidUserIDPassword " & _
Chr(34) & " & Err.Source" & Chr(13) & Chr(10)
strCode = strCode & " End If" & Chr(13) & Chr(10)
strCode = strCode & " SetAbort" & Chr(13) & Chr(10)
strCode = strCode & " ValidUserIDPassword = False" & Chr(13) & Chr(10)
strCode = strCode & "End Function" & Chr(13) & Chr(10)
strCode = strCode & "Private Sub GetRecordSet(ByRef r_recRecordset As " & _
"ADODB.Recordset, _" & Chr(13) & Chr(10)
strCode = strCode & " ByVal v_strSource)" & Chr(13) & Chr(10)
strCode = strCode & " On Error GoTo GetRecordSetError" & Chr(13) & Chr(10)
strCode = strCode & " Set r_recRecordset = New ADODB.Recordset" & _
Chr(13) & Chr(10)
strCode = strCode & " r_recRecordset.CursorLocation = adUseClient" & _
Chr(13) & Chr(10)
strCode = strCode & " r_recRecordset.Open _" & Chr(13) & Chr(10)
strCode = strCode & " v_strSource , GetADOConnection, adOpenStatic, " & _
" adLockOptimistic" & Chr(13) & Chr(10)
strCode = strCode & " Exit Sub" & Chr(13) & Chr(10)
strCode = strCode & "GetRecordSetError:" & Chr(13) & Chr(10)
strCode = strCode & " Err.Raise Err.Number, " & Chr(34) & "ValidUserID" & _
Chr(34) & " & Err.Source, Err.Description" & Chr(13) & Chr(10)
strCode = strCode & "End Sub" & Chr(13) & Chr(10)
For lngTableCounter = 1 To UBound(r_TableInfo)
strCode = strCode & "Public Function Return" & _
r_TableInfo(lngTableCounter) & _
"RecordSet(ByVal v_strUserID As String, ByVal _" & _
Chr(13) & Chr(10)
strCode = strCode & " v_strPassword As String, Optional ByVal " & _
"v_strParameter As String) As _" & Chr(13) & Chr(10)
strCode = strCode & " ADODB.Recordset" & Chr(13) & Chr(10)
strCode = strCode & " Dim rec" & r_TableInfo(lngTableCounter) & _
" As ADODB.Recordset" & Chr(13) & Chr(10)
strCode = strCode & " On Error GoTo Return" & _
r_TableInfo(lngTableCounter) & "RecordSetError" & _
Chr(13) & Chr(10)
strCode = strCode & " SetADOConnection v_strUserID, v_strPassword" & _
Chr(13) & Chr(10)
strCode = strCode & " GetRecordSet rec" & _
r_TableInfo(lngTableCounter) & ", m_cstr" & _
r_TableInfo(lngTableCounter) & "Query & v_strParameter" & _
Chr(13) & Chr(10)
strCode = strCode & " Set Return" & r_TableInfo(lngTableCounter) & _
"RecordSet = rec" & r_TableInfo(lngTableCounter) & _
Chr(13) & Chr(10)
strCode = strCode & " Set rec" & r_TableInfo(lngTableCounter) & _
".ActiveConnection = Nothing" & Chr(13) & Chr(10)
strCode = strCode & " SetComplete" & Chr(13) & Chr(10)
strCode = strCode & " CloseADOConnection" & Chr(13) & Chr(10)
strCode = strCode & " Set rec" & r_TableInfo(lngTableCounter) & _
" = Nothing" & Chr(13) & Chr(10)
strCode = strCode & " Exit Function" & Chr(13) & Chr(10)
strCode = strCode & "Return" & r_TableInfo(lngTableCounter) & _
"RecordSetError:" & Chr(13) & Chr(10)
strCode = strCode & " CloseADOConnection" & Chr(13) & Chr(10)
strCode = strCode & " SetAbort" & Chr(13) & Chr(10)
strCode = strCode & " Err.Raise Err.Number, " & Chr(34) & _
" Return" & r_TableInfo(lngTableCounter) & Chr(34) & " " & _
" , Err.Source " & " & _" & Chr(13) & Chr(10)
512
Creating a VB Code Generator Add-In
513
Appendix C
514
Creating a VB Code Generator Add-In
We will need to get the names of the tables and the fields from the Access database. To do this we will use
the OpenSchema method of the connection object. The OpenSchema method will give us access to the
structure of the database by returning ADO recordsets with information on the database’s schema
(structure). Some of the schema information is stored as integers and we will need to convert that to
something that is useful. For example, the data types of the fields are stored as numeric values. We will
need to convert these numeric values to Visual Basic types. After some digging around I discovered what
each of the numbers represented and wrote the following function to convert the numbers to Visual Basic
data types:
Private Function GetDataType(ByVal v_lngValue As Long) As String
515
Appendix C
End Function
516
Creating a VB Code Generator Add-In
The Criteria and SchemaID parameters are optional and we will not use them. QueryType is the type
of schema information we want on the database. The values of QueryType are in the MSDN Library. We
will only be using three values for QueryType. If we choose a QueryType adSchemaTables, we will
get back a recordset filled with information on all of the tables. If you look in MSDN at the values for
criteria for OpenSchema, you will see some of the field names for the recordset that will be returned. For
adSchemaTables, the values listed for criteria are:
TABLE_CATALOG
TABLE_SCHEMA
TABLE_NAME
TABLE_TYPE
We will want to use TABLE_NAME to get the names of all of the tables. There are additional fields that are
available. If you are curious about them, you can write a small application that loops through all of the
fields and writes to a text file the field names and values for the fields.
We will also use adSchemaColumns as a QueryType to retrieve the information on the columns (fields)
of the table. The final QueryType we will use is adSchemaConstraintColumnUsage to get the
names of the primary key fields.
We will use the m_oVBInstance variable to get access to the instance of Visual Basic. The IDE
m_uTables will be used to hold the information on the tables that will be collected when
cmdRetreiveTables is clicked.
517
Appendix C
Other modules will use VBInstance as we will show later, so it must be a Friend. We cannot include a
property for m_uTables as it is an array and we cannot use properties for arrays. We can create a function
to retrieve and set array members, but we will not do this to simplify the code. In a real project, you should
create such a function.
The objTableInfo variable will be used to hold the recordset with the table information returned by
OpenSchema. The objFieldInfo variable will hold the field information returned by OpenSchema,
and objPrimaryKey will have the detailed field information that will include the primary key
information.
If there is no connection string in txtConnection we will exit out, otherwise we will try to open a
connection to the database:
Screen.MousePointer = vbHourglass
If txtConnection.Text <> "" Then
On Error Resume Next
With objConnection
.Open "Provider=Microsoft.Jet.OLEDB.3.51; " & _
"Persist Security Info=False;Data Source=" & txtConnection.Text
If Err.Number <> 0 Then
MsgBox "The following Error Occurred when trying to connect:" & _
vbCrLf & "Error Description: " & Err.Description & vbCrLf & _
"Error Number: " & Err.Number & vbCrLf & _
"Error Source: " & Err.Source
Screen.MousePointer = vbDefault
Exit Sub
End If
If we have successfully opened the database, we will then get a recordset with the table information in it
using OpenSchema:
518
Creating a VB Code Generator Add-In
We will now move through the records. Each record contains information on a table in the database. This
recordset not only holds information on the regular tables, but also the views and the system tables. We are
only interested in the regular tables, so we must skip over the views and system tables. In an Access
database, MSYS will be in the name of system tables, so we can eliminate system tables by looking for
MSYS in the table name. The recordset returned by OpenSchema will have a field called TABLE_TYPE,
which identifies the type of table, i.e. TABLE or VIEW. We can use this to eliminate the views.
lngRecordCounter = 1
Do Until objTableInfo.EOF
If InStr(1, UCase(objTableInfo.Fields("TABLE_NAME")), "MSYS") = 0 _
And objTableInfo.Fields("TABLE_TYPE") = "TABLE" Then
We will want to add each table into the m_uTables array. Since we do not know how many tables there
are (the RecordCount of objTableInfo contains the count of regular tables, system tables and views)
we must increase the size of the m_uTables array before we add each table. To increase the size of an
array, use ReDim. Since we want to keep the information in the array from the previous times through this
loop, we use ReDim Preserve, which allows us to increase the size of the array without deleting the
current values in the array.
Now, we can add the table name into m_uTables and into the listbox:
m_uTables(lngRecordCounter).TableName = _
objTableInfo.Fields("Table_Name")
LstAvailableTables.AddItem objTableRecordset.Fields("Table_Name")
Set objPrimaryKey = _
.OpenSchema(adSchemaConstraintColumnUsage)
The recordset that is returned contains primary key information on all of the tables, not just the table we
want. Therefore, we will have to move through this recordset until we come to the record for the table we
are currently working with. Unfortunately, this table holds all of the constraint information on all of the
tables. We can have constraints other than the primary key constraint, so we must check to see if this is the
primary key constraint, also. If it is the correct table but the wrong constraint, we will ignore it.
519
Appendix C
Finally, we will loop through the fields and add them to m_uTables:
objFieldInfo.MoveFirst
lngFieldCounter = 1
Do Until objFieldInfo.EOF
If objTableInfo.Fields("Table_Name") = _
objFieldInfo.Fields("Table_Name") Then
To get the data type we will use the GetDataType function we created:
m_uTables(lngRecordCounter).FieldInfo(lngFieldCounter).DataType = _
GetDataType(objFieldInfo.Fields("DATA_TYPE"))
lngFieldCounter = lngFieldCounter + 1
End If
objFieldInfo.MoveNext
Loop
lngRecordCounter = lngRecordCounter + 1
End If
objTableInfo.MoveNext
Loop
End With
End If
cmdRetrieveTables.Enabled = False
Screen.MousePointer = vbDefault
End Sub
Once we have stored all of the schema information that we require into the m_uTables array, we can use
this to generate our Visual Basic application based on this schema.
520
Creating a VB Code Generator Add-In
We will use the objVBproj variable to hold a reference to a Visual Basic project, objVBClass will
hold a reference to a Visual Basic component, such as a class, control or module, and
strTempTableName will be used to parse spaces out of the table name. We will loop through all of the
tables contained in the m_uTables array:
We will now create a temporary variable with the name of the table. We will remove spaces from the table
name.
Next, we will use the Add method of VBProjects to create a new project in the Visual Basic IDE and
store a reference to this new project in the objVBProj variable:
We will use the GUIDs to set the proper references. To get these references, I created a Visual Basic EXE
project, added the references I needed, saved the project, opened the project in Notepad, and copied the
references. We will need references to the ADO 2.x library and remote data services.
objVBproj.References.AddFromGUID "{00000200-0000-0010-8000-00AA006D2EA4}", _
2, 0
objVBproj.References.AddFromGUID "{BD96C556-65A3-11D0-983A-00C04FC29E30}", _
1, 5
521
Appendix C
Next, we will use the Add method of VBComponents to add a class module:
objVBproj.VBComponents.Add (vbext_ct_ClassModule)
This will be the top class so we will name it after the table:
We will call the Activate method to make sure the class is the active code module in the Visual Basic
IDE:
At this point, we can insert the code into the class code module by using the AddFromString method of
the CodeModule object. We will call the BuildClass method of BuildTop to get the string containing
the code and insert it into the code module:
objVBproj.VBComponents.Item(objVBproj.VBComponents.Count).Name = _
"cls" & strTempTableName
objVBproj.VBComponents.Item("cls" & strTempTableName).Activate
Because we want the bottom and middle classes to be data providers, we must set the
DataSourceBehavior to 1. After that, we will use our functions to get the code:
objVBproj.VBComponents.Item("cls" & _
strTempTableName).Properties.Item("DataSourceBehavior").Value = 1
objVBproj.VBComponents.Item("cls" & _
strTempTableName).CodeModule.AddFromString _
BuildBottom.CreateDeclarations
objVBproj.VBComponents.Item("cls" & _
strTempTableName).CodeModule.AddFromString _
BuildBottom.CreateIntialize
objVBproj.VBComponents.Item("cls" & _
strTempTableName).CodeModule.AddFromString BuildBottom.CreateTerminate
objVBproj.VBComponents.Item("cls" & _
strTempTableName).CodeModule.AddFromString _
BuildBottom.CreateChangedField
objVBproj.VBComponents.Item("cls" & _
strTempTableName).CodeModule.AddFromString _
BuildBottom.CreateMiscProps(strTempTableName)
objVBproj.VBComponents.Item("cls" & _
strTempTableName).CodeModule.AddFromString _
BuildBottom.CreateValidateFields(m_uTables(lngTableCounter).FieldInfo)
objVBproj.VBComponents.Item("cls" & _
strTempTableName).CodeModule.AddFromString _
BuildBottom.CreateGetLet(m_uTables(lngTableCounter).FieldInfo)
522
Creating a VB Code Generator Add-In
objVBproj.VBComponents.Add (vbext_ct_ClassModule)
objVBproj.VBComponents.Item(objVBproj.VBComponents.Count).Name = _
"cls" & strTempTableName & "Manager"
objVBproj.VBComponents.Item("cls" & strTempTableName & _
"Manager").Properties.Item("DataSourceBehavior").Value = 1
objVBproj.VBComponents.Item("cls" & strTempTableName & _
"Manager").Activate
523
Appendix C
End If
Next
We will need references to the ADO 2.0 Library, MTS and remote data services:
objVBproj.References.AddFromGUID _
"{00000200-0000-0010-8000-00AA006D2EA4}", 2, 0
objVBproj.References.AddFromGUID _
"{BD96C556-65A3-11D0-983A-00C04FC29E30}", 1, 5
objVBproj.References.AddFromGUID _
"{74C08640-CEDB-11CF-8B49-00AA00B8A790}", 1, 0
objVBproj.VBComponents.Item(objVBproj.VBComponents.Count).Name = _
"clsServer"
objVBproj.VBComponents.Item("clsServer").Activate
objVBproj.VBComponents.Item("clsServer").CodeModule.AddFromString
BuildServer.CreateServer(strTempTable, m_uTables)
End Sub
While all of our code up to this point is perfectly correct, it will not work. While we have created a
reference to the Visual Basic IDE, we have not pointed the reference to the current instance of the Visual
Basic IDE that is using our add-in. We still need to get a reference to the Visual Basic IDE that called our
Code Generator add-in. Luckily, there are events that are raised that can be used to get this reference.
524
Creating a VB Code Generator Add-In
Option Explicit
Implements IDTExtensibility
IDTExtensibility will give us the events that we will need to get a reference to the Visual Basic IDE.
Remember, when you use an interface you will need to use all of the methods in the interface. If you look in
the object drop down of the Visual Basic IDE (the left drop down box) you will see that the
IDTExtensibility has been added.
We will use OnConnection event to get a copy of the Visual Basic IDE. Go to the object drop down of
the Visual Basic IDE and select IDTExtensibility. OnConnection will include a parameter called
VBInst, which is a copy of the Visual Basic IDE. We will pass this to the frmMain VBInstance
property:
We will now just fill in the rest of the events of the interface with comments:
End Sub
525
Appendix C
Open up another instance of Visual Basic 6 with a new standard exe project. If you want to step through the
code in the code generator, place break points in the code generator project and run it.
Double-click on
CodeGenerator.CodeGeneratorClass and select
OK. This will bring up the form from our add-in:
Click Retrieve Table Info and then click Generate. Set the path to the correct path for your computer.
The code generator should now generate the entire project for you.
The generated code for the business services components can form the framework for coding these
components. There will be many business rules, such as a customer must have a billing address or a state
must be two letters, that will have to be added to this code. We can see that our business components are
built from a basic pattern that has specific rules added to them. While we will have to do some refinement
to our business services components, the majority of the code can be created from a pattern. This can save a
great deal of time in the development phase. Let us now see how to test the generated code.
526
Creating a VB Code Generator Add-In
You can now try the project with other Access databases.
527
Appendix C
528
Creating a VB Code Generator Add-In
529
Index
2
Table of Contents
3
Table of Contents
8
Table of Contents
10
Table of Contents
MTS OLE-DB
See Microsoft Transaction Server (MTS), 203 Active Data Objects (ADO), 242
multiplicities one-based arrays, 307
UML representation, 416 OOP
multi-threading, 205 abstraction, 12, 190
not supported by Visual Basic, 205 business rules, 177
network classes, 12
traffic, 383 cohesion, 193, 195
Northwind example composition, 196
ADO disconnected recordsets, 257 coupling, 193
bug tracking, 308 cyclic methodology, 14
class diagrams emergence, 196
bottom class, 272 encapsulation, 12, 191
middle class, 275 extensibility, 14
class hierarchies, 238 instances, 12
functional testing, 306 methods, 12
goal prioritization, 127 object design, 192
goals, first level, 130 versions, 192
goals, second level, 130 object interfaces, 192
goals, third level, 133 use cases, 209
interviewing users, 170 objects, 12
patterns, 283 patterns, 279
recordsets, returning, 313 properties, 12
schedules, Project 98, 85 Option Explicit
goal linking, 92 variable declarations, 308
testing, 259 order object, 198
transaction processing, 204 parameters
vision/scope documents passing by reference, 315
project cycles, 140, 141 passing by value, 314
object diagrams passion for work, 57
defined, 414 increasing, 58
object hierachies nurturing, 57
managed class, 284 patterns
managing class, 284 application efficiency, 300
object hierarchies, 284 code generation, 285
Object Oriented Programming code reuse, 279, 285
see OOP, 12 frameworks, 280
ObjectControl interface general, 279
MTS, 291 sequence diagrams, 282
objects, 12 specific, 279
As Soon As Possible (ASAP) deactivation, 247 usefulness, 280
attributes, 190 performance tests
accessing by recordset, 272 functional testing, 307
classes, 12 personnel
HTML, 299 risk management, 149
in DHTML, 297 Pert charts
interaction goal dependencies, 73
UML representation, 417 schedules, 73
Just In Time (JIT) activation, 247 sub-goals, 73
methods, 12 physical design stage
MTS, 247 Active Data Objects (ADO), 242
ObjectContext object, 278 activity diagrams, 250, 381
properties, 12 ADO connection, 251
UML representation, 415 benefits, 258
11
Table of Contents
12
Table of Contents
team, 32 proxies
project manager, 25, 26 DataSpace object, 276
conflict resolution, 56 marshalling, 244
coordination, 36 RDS.DataSpace object, 244, 276
decision making, 34, 48 Remote Data Services (RDS), 275
deployment phase, 37 pseudo-code
design phase, 37 logical design stage, 189
development phase, 37, 268 public properties, 237
envisionment phase, 37 PVCS Tracker
goals, accomplishing, 63 bug tracking, 308
leadership, 61 Rational
passion for work, 57, 58 sequence diagrams, 215
problem solving, 53 RDS.DataSpace object
responsibilities, 29 proxies, 244, 276
risk management, 150, 270 Reconcile step
role, 36 Microsoft Transaction Server (MTS), 258
team spirit, 61 recordsets, 240
project schedule Active Data Objects (ADO), 242
risk management, 149 ADOR, 244
projects field validation, 274
communication, 22 HTML pages, building, 287
components, 13 object attributes, accessing, 272
cost Remote Data Services (RDS), 243
TCO/ROI, 136 recordsets, disconnected, 183
defined, 8 relationships
desgining as a team, 229 UML, 408
coding standards, 229 UML representation, 415
design documents, 229 Remote Data Services (RDS), 243
design work, importance of, 11 component reuse, 276
failing, 158 DCOM, 246
failure rates, 10 HTTP, 246
functionality, 124 marshalling, 244
iterative design, 184 proxy servers, 275
maintenance, 16 recordsets, 243
research, 230 reporting manager, 25
schedules, 71, 115, 404 evaluation, 29
scope, 14 role, 30
success, reasons for, 10 reproducibility, bugs
team roles, 24 categories, 336
total cost estimates, 136 requests for services
properties, 12 conceptual design stage, 168
bottom class, 272 Requirement Business Rule, 176
friend, 237 research
middle class, 275 documentation, 231
private, 237 MSDN, 230
Property Get, 272 Visual Basic, 230
Property Let, 272 resource files
Property Set, 272 error messages, 261
data conflicts, 273 resources
public, 237 estimates, 234
prototypes management, 96
code, discarding, 304 risk management, 149
testing, 231 schedules, 93, 96
VB with ASP pages, 287 time
13
Table of Contents
15
Table of Contents
17
Table of Contents
18
Table of Contents
19
Table of Contents
20