Glossary of Terms:
-
Visual Studio Solution
A named collection of Visual Studio Projects with properties. A solution normally builds a
single application, composed of one or more executables (client-server perhaps). Each solution is persisted to a
structured text file that contains references to each of its Visual Studio Projects and
solution properties.
-
Visual Studio Project
A named collection of files that build into a single executable or library. Projects are
persisted to XML files containing references to source code files and properties.
-
CSE687-OnLine Project
A Project Statement and the Code you develop
to satisfy requirements of the statement.
-
Package
For C++, two files: header file PackageName.h and implementation file PackageName.cpp.
Both files have prologue comments.
The header file has comments for Package Operations and Maintenance History, followed
by class declarations.
The implementation file has class member definitions and a test stub main.
Here's an example.
Getting Started with Projects:
So how
do you start? Here are some practical steps to get going:
- Read project statement carefully.
- Make a list of tasks the software must execute.
-
With each task, associate a package. Some tasks may combine to form a package, some may need to be
partitioned into two or more packages, but one package per task is typical when you are starting
(see bottom-up construction, below).
-
Open Visual Studio and create an empty solution.
-
Building Top-Down
-
The instructions in this section are fairly detailed.
Building this example, I followed the Top-Down steps below. Now, it is ready for some Bottom-Up
development to give the Task classes useful functionality.
-
Add an empty C++ Win32 Console Application project, named Executive.
-
Add header file1 Executive.h with a brief prologue comment including the file name.
Make sure the file uses preprocessor statements to avoid multiple inclusions2.
-
Add implementation file Executive.cpp with a brief prologue comment including the file name.
Then add a #include "Executive.h" statment.
-
Include any C++ libraries needed, i.e., #include <iostreams>3.
-
Include any header files for task packages the executive uses, i.e., #include "Task1.h"4.
When you first begin there won't be any. Later, you will come back and add headers as needed.
-
To Executive.cpp add a main function, i.e.:
int main(int argc, char* argv[])
{
// code to invoke your executive goes here
Executive ex;
ex.someMemberFunction();
// yada yada
}
-
Build the solution and make sure that the Executive runs correctly.
-
Add an empty C++ Win32 Console Application project, named Task15.
-
Add package files, Task1.h and Task1.cpp. Configure these files like the
Executive package you created in the steps above.
-
Add a Task1.cpp test stub main like this:
#ifdef TEST_TASK1
int main(int argc, char* argv[])
{
// code to invoke your Task1 goes here
Task1 t1;
t1.doWork();
// yada yada
}
#endif
The compiler directive allows you to run Task1, stand-alone, by setting
Project Properties > C/C++ > Preprocessor > Preprocessor Definitions to include "TEST_TASK1;".
In any project that uses Task1, but does not define TEST_TASK1, this test stub will not be compiled,
so Task1 can be combined with other Tasks and the Executive.
-
Build the Task1 project and run stand-alone to be confident that it works correctly.
-
Now, go back to the Executive package, add #include <Task1.h> to Executive.h.
-
Add Task1 t1 as a composed member of the Executive class.
-
Add code in Executive to invoke Task1 processing.
-
Add code in Executive::main to test this new behavior of Executive.
-
Now, for all the remaining application tasks, you repeate the steps above.
-
Congratulations! You're done and can submit your project.
-
Building Bottom-Up
-
Instead of starting with the Executive package, you decide to start with some low-level task that you know
will be needed. The advantage of this is that you can think carefully about the language that package will
provide, through its class interface, for higher-level packages to call. However, you need to be confident
that you know what to build.
-
You build code structure for this lower-level task package using the same techniques you did for the top-down
package design, discussed above.
-
Test the package and modify until you are satisfied that it works correctly and provides the functionality
needed by higher-level packages.
-
Build more low-level packages that you know how to build, that don't depend on other code you need to write.
-
Now pick a task that needs just the services of packages you've completed, as above.
-
Implement, #including headers of needed packages you've completed, and add code to use their services.
Test until you are satisfied with its functionality and behavior.
-
Keep going up until you reach the Executive. Test the Executive until you are confident that its behavior
is correct and that you've met your obligations, as per the Project Statement.
-
Building Top-Down and Bottom-Up
-
Frequently, I expect, you will find yourself using both styles of implementation - I often do.
You may start Top-Down, but realize you need some low-level processing that will be called from several
different places in your code. You want to implement that only once, so you stop Top-Down, and focus
on the packages you want to use in multiple places, building Bottom-Up.
-
Advantages of each implementation style
-
Top-Down development usually results in application packages that have well structured dependency
relationships. It's natural to think critically about project structure while developing Top-Down.
-
Building Bottom-Up is likely to result in significant code reuse and minimize duplication across the
application's code. Also, its natural to focus on the language that each package will provide in
ways that make it more reusable.
-
So, it's often effective to use Top-Down development for the upper layers of an application, and
bottom-up for the lower layers.