COMMERCIAL AND PROFESSIONAL APPLICATION DEVELOPMENT
Part Three - The Conceptualization Process
And here we are, the 3rd part of this series. What exactly can you expect in this section? Well let's start by stating what you would typically have before arriving to this section. In theory, you would have your analysis documents (the 3 of them) completed, you would have gotten the solution discussed and approved by management and everything is ready to go to the next step of the development cycle. What is that next step? It's called Conceptualization phase, and entails the beginning of the creation of the proposed solution as it is defined in the detailed analysis and the solution proposal document. Since any flow of information between process steps and between departments in the company (if need be) have been defined in the detailed analysis, you should be ready to go on and start to create the solution. In this 3rd part of the series, we'll cover all you need to know about the conceptualization phase, what it is, what tools are available to you during this phase, and some good practice to use throughout the process.
By the end of this 3rd part, you will be well equipped with the knowledge you need to conceptualize an idea into a workable solution ready for the development phase (which we'll cover in the next part of this series). So indeed, there's alot of ground to cover here. Grab your favorite drink and let's get started shall we?
WHAT IS THE CONCEPTUALIZATION PHASE:
In the software engineering field, conceptualization is taking everything in the analysis and building a solution from all the information gathered in the analysis phase. Of course, as I mentionned in the previous section, there are many ways to arrive at that, and each of those ways involve a different point of view on the creation of the solution. I'm not going to detail each method again here, you can review them here. if you recall, I mentionned that we would be using UML (Unified Modelling Language) for our project, and that is exactly what we will be doing here.
Is there a preferred order of things that can work better than others? Many software engineers might argue on this. Me, I tend to use somewhat of a top to bottom approach in that I'll start with the bigger, more complex objects (which are usually objects that are made of other objects) and work my way down to each object that the bigger objects are made of. The reason I work in this order is it gives me a bigger picture so to speak and i can work on the relationships between the objects as I break them down. Since we'll be using UML as our tool, actually, we'll be using a text version of UML which means that I'll be describing the objects as text as well as the relationships between the objects. This is a quicker method than going into some application and creating UML diagrams. And it can be done in notepad or your favorite text editor. Let's start by covering what UML is and what it allows to do to familiarize ourselves with it.
UNIFIED MODELING LANGUAGE BASICS:
U.M.L. is a language that used to describe a problem based on the entities involved, howw to describe these entities (properties) and what those entities can do (methods). UML also alows to describe the relationship between each entity. It doesn't stop there however, UML is also used to describe Organization Diagrams, Use Case Scenario diagrams, Activity and State diagrams, and Static and Dynamic Model (class) diagrams, Sequence Diagrams (to explain certain ordered steps), Collaboration diagrams (where more than one process need to work together to get a given job done) as well as a whole bunch of other types of diagrams that are useful when modeling a solution from start to finish.
For some reference you can take a look at Allen Holub's UML Quick Reference which details all the types of diagrams that are available in UML as well as examples on what those diagrams can look like. Also you can take a look at the UML 2.0 Superstructure Final Adopted specification. With these documents at hand, you'll be equipped to tackle any conceptualization model you would be likely to encounter.
I need to add a distinction here. In many cases, people tend to confuse the concept of composition versus the concept of aggregation. So I will explain these two right here to a bit of clarity. Here they are:
- Aggregation: An Aggregation represents a whole entity that comprises other parts. For example: a committee is an aggregate of it's members. However, in the case of an aggregation a commitee does not contain it's members per se.
- Composition: A composition, unlike the aggregation, has everything to do with containement. For example, a horse is a mammal, and will never have a reason to be nothing else but a mammal, therefore, a mammal contains a horse.
With all this in mind, you can see that UML can be a very powerful tool to add to your arsenal of software engineering tools for more than one reason. For the sake of this example, we'll be using what I called a text version of UML as in there will be no diagrams. The description of objects will be nade in a textual, almost pseudo code like even, because when you look at an object class model diagram, that's exactly what you're seeing for an object is all it's properties and methods listed and described. If the need for a sequence or a collaboration diagram is needed in our description I will use lists or paragraph describing the sequence and/or collaboration. This way you should be able to see clearly what should be going on in an object. Also as mentionned, I will start with the bigger objects and clearly state what the object is composed of. the components of the objects will be detailed later in the scripted UML model.
FINANCECAD SCRIPT BASED OBJECT MODEL:
To start this model, I will begin at the highest possible level of FinanceCAD, the Application itself. Indeed the FinanceCAD Application can definitaly be thought of as an object, a very complex object that comprises everything else in the project.
ENTITY FinanceCAD PROPERTIES: ApplicatioNPath Text VersionMajor Numeric VersionMinor Numeric VersionRevision Numeric VersionRelease Character VersionStamp Text METHODS: CreateNewDesign <- DesignName Text OpenDesign <- FileName Text SaveDesign <- FileName Text PrintDesign <- PrinterNumber Numeric COMPONENTS: OBJECT Canvas <- The main Drawing Canvas OBJECT DatabaseEngine <- File and database functionality OBJECT PrintingEngine <- Printing functionality for the design OBJECT ReportEngine <- Printing Functionality for the reports OBJECT NetworkEngine <- Detection and access to the network folders OBJECT ImportExportEngine <- Import and Export for the design and the reports RELATIONSHIPS: No relationship at this level of refinement. END ENTITY
So far it's not too long is it? There's a median to reach when you are describing a problem using this approach. For the sake of our example here, there's no need to go into any more details, at the application level, than to list what the general components of the application would typically be. As you can see from this first description, things can become obvious quite quickly using this description method. You described the Application just as you would any other type of object. All Objects have qualities and properties that describe them, they also have actions that they can perform. Just by saying what the object looks like, and what it can do, you end up with a pretty complete description of the object itself. Take a look at the Canvas object defined below, you'll see what I mean when I say a complete picture.
OBJECT Canvas PROPERTIES: FileName Text UnitOfMeasure Numeric Scale Numeric NumberOfShapes Numeric Layers List METHODS: Create <- The constructor, called when object is initialized Destroy <- The destructor, called when object is destroyed SetUnitOfMeasure <- NewUnitOfMeasure Numeric SetScale <- NewScale Numeric ClearCanvas RefreshCanvas AddCircle <- Layer Numeric, Radius Numeric AddEllipse <- Layer Numeric, Ratio Numeric AddArc <- Layer Numeric, Ratio Numeric, Length Numeric AddSquare <- Layer Numeric, Length Numeric AddRectangle <- Layer Numeric, Height Numeric, Width Numeric AddTriangle <- Layer Numeric, TriangleType Numeric, Lengths() Numeric AddHexagon <- Layer Numeric, SideLength Numeric AddOctogon <- Layer Numeric, SideLength Numeric AddLine <- Layer Numeric, X1, Y1 Numeric, X2, Y2 Numeric RELATIONSHIPS: One To Many -> Circle Object One To Many -> Ellipse Object One To Many -> Arc Object One To Many -> Square Object One To Many -> Rectangle Object One To Many -> Triangle Object One To Many -> Hexagon Object One To Many -> Octogon Object One To Many -> Line Object DESCRIPTION: The Canvas object is where the drawing of the design actually occurs. It is composed of a drawing area and a command processor (to get and process all the different commands that would typically be entered. The One To Many relationships to the different Shape Objects are because Shapes are added to the canvas rather than just drawn. This way, each shape can be treated as an independant entity and moved independant of the other shapes on the given design. END OBJECT
The first thing to notice here is how I categorized each descriptive element. this method is the one I prefer to describe a physical object in an application hierarchy. I'm not going to define the Circle, Ellipse and the other basic objects for this example. Just remember that when describing a different scenario (typically when you are modelling a manual process) it will be a good idea to define each little element that make up a given object. In this case the Circle object and the other shapes would be defined in the same fashion as the canvas objects with the properties section, the methods, relationships and so on.
We'll just go down the list of objects in the order they have been defined in our application entity. As such, here's the definition of the DatabaseEngine object:
OBJECT DatabaseEngine PROPERTIES: DatabasePath Text ConnectionString Text ConnectionMade Boolean TableCount Numeric TableList List Table Objects METHODS: Create <- The constructor, called when object is initialized Destroy <- The destructor, called when object is destroyed ConnectToDB <- ConnectionString Text, DBPath Text ValidatePath <- PathToValidate Text OpenTable <- TableName Text ExecuteQuery <- QueryToExecute Text InsertRecord <- RecordData Text UpdateRecord <- RecordData Text DeleteRecord <- RecordNumber Numeric FindRecord <- Criteria Text RELATIONSHIPS: One To One -> NetworkEngine Object DESCRIPTION: The DatabaseEngine as defined here is not a Database Management System but rather a wrapper that connects to the existing database engines via the ODBC database connectivity library. Each method will therefore portray a function calling to the inner ODBC functions in the actual coding phase. The relationship to the Network Engine is for validating the actual path to the global database and assure proper connection between the the Database Engine and the physical location of the database itself as well as validating the existence of the network printers and plotters to print the designs and the reports. END OBJECT
And that was the DatabaseEngine object definitions. As you go along refining the object model when issues get solved and questions get answered, you may want to add to this model. For example, maybe you'll find you need more properties in the list of properties depending on what the users know that they need to get access to the database. Perhaps the ability to specify a username and a password to the ConnectDB method rather than the way it's designed right now. You need to remember that typically you are at the start of the conceptualization phase and that you may as the modelling moves along, move properties and methods around to other objects perhaps for whichever reason. Just remember that you need to have an open mind at this stage of conceptualization. Things can and will change in your model and knowing that in advance can influence the initial design to be as open and flexible as it needs to be to allow for these changes. As a quick note, you can see I named the constructor and the destructor the same name as the canvas object. It's good practice to name functions that perform the same things by the same name not just in the conceptualization phase but throughout the whole development cycle all the way to the source code as well. This way you know that Create will always create and initialize the object no matter what that object is.
Likewise, the PrintingEngine Object is defined as any other objects it has properties and methods that will be used by the main application object at will to get things in output format. A typical definition for a printer object could be as follows:
OBJECT PrintingEngine PROPERTIES: PlottingJobs List PlotterList List JobCount Numeric HasJobsToDo Boolean METHODS: Create <- The constructor, called when object is initialized Destroy <- The destructor, called when object is destroyed DetectPlotter <- PlotterToDetect Text InitializePlotter <- PlotterToInitialize Text AddToJobs <- JobNumber Numeric, FileName text PrintFirstInList <- No Parameters, will print the first job in list RELATIONSHIPS: One To One -> NetworkEngine Object One To Many -> ReportEngine Object DESCRIPTION: The PrintingEngine as defined here is a central object where all printing jobs are passed. This object will determine the type of document that is being requested for printing, determine where it should be printed (Physical location of the plotter) and send the job to there to be printed. It does nothing to the actual design file itself other than send it to be printed. The One to One relationship to the NetworkEngine object is to detect the presence of the plotter that has been configured by the design. The One to Many relationship to the ReportingEngine Object is because when the user prints a design he or she could want to print more than one report for the cost of the design itself. END OBJECT
There you have it, the PrintingEngine Ojbect as you can see is the object that manages and prints The Design file itself. In the description part is where you defined the exact relationship between the object as I've done here. it will help the coding phase alot to know why a relationship is defined. Notice how every object is defined using the same structure no matter what it's role is. That's the beauty of this method. Consistency in structure will help you, and everyone that needs to see the model, quickly learn how to read the model and where to locate vital information they will need in their part of the project.
To continue with our modeling, as per our list of components in the Application definition the next object on our list is the ReportEngine Object. So then, let's define that one right now:
OBJECT ReportEngine PROPERTIES: PrinterJobs List PrinterList List JobCount Numeric HasJobsToDo Boolean METHODS: Create <- The constructor, called when object is initialized Destroy <- The destructor, called when object is destroyed DetectPrinter <- PrinterToDetect Text InitializePrinter <- PrinterToInitialize Text CreateSummaryCost <- DesignFile Text CreateDetailCost <- DesignFile Text AddSummaryJob <- JobNumber Numeric, FileName text AddDetailJob <- JobNumber Numeric, FileName text PrintFirstInList <- No Parameters, will print the first job in list RELATIONSHIPS: One To One -> NetworkEngine Object Many To One -> PrintingEngine Object DESCRIPTION: The ReportObject takes care of all the paperwork related to a given design file. the user will have 2 choices when requesting a report to be printed with a design. He or she can have a sumarry report (usually used inhouse for quick evaluation of costs) and a detail report (usually used both inhouse and sent to the client for aproval purposes. The two reports are added to the same list of print jobs as they will typically be sent to the same printer. The One to One relationship to the NetworkEngine Object is to validate the existence of the physical printer on the network. The Many to One relationship to the PrintingEngine is because the reports that are offered here are only available when printing a design (an optional checkbox may be added to select to print just the design, the design and the report, or just the report, but they will all originate from the same print dialog). END OBJECT
The good part of this type of definition is let's say the users, even at this stage of the conceptualization process, decide they want another type of report, all you have to do is add an Add____Job method (these will be defined at the coding phase). The model can stay as abstract as needed to isolate itself from the actual coding of the application this way. By tracing this line between the conceptualizaton and the coding phase, it's easier to set a limit to when the conceptualization phase will end and when the coding phase will begin. Note that so far there are no screens or any visual aspects defined at this stage either. You'll see why in the next section, the coding phase of the development cycle. But let's just say here that the coding phase is and should be split into two sub-phases, The design phase and the programming phase.
Moving right along in our model, the next object to attack is the NetworkEngine Object. Before we begin the model, just keep in mind one thing. Unlike the rest of the objects here, the NetworkEngine object is an independant object in that it doesn't need the other object to execute itself, however, there are relationships because the other objects of the application will give the NetworkEngine object it's purpose of existence. So let's define this object and we'll see what I am talking about:
OBJECT NetworkEngine PROPERTIES: DriveCount Numeric ListOfDrives List PrinterCount Numeric ListOfPrinters List PlotterCount Numeric ListofPlotters List IsNetworkPresent Boolean METHODS: Create <- The constructor, called when object is initialized Destroy <- The destructor, called when object is destroyed GetListOfDrives <- No Parameters, gets list of network drives SetDriveCount <- Count Numeric ValidateDrive <- DriveIndex Numeric GetListOfPrinters <- No Parameters, gets list of available printers SetPrinterCount <- Count Numeric ValidatePrinter <- PrinterIndex Numeric GetListOfPlotters <- No Parameters, gets list of available plotters SetPlotterCount <- Count Numeric ValidatePlotter <- PrinterIndex Numeric RELATIONSHIPS: Many To One -> Canvas Object Many To One -> DatabaseEngine Object Many To One -> PrintingEngine Object Many To One -> ReportEngine Object DESCRIPTION: The NetworkEngine Object is an object that performs all necessary validation against the network in order to get all the valid drives, printers and the plotters that are available on the network. The list of drives will contain the physical Drive Letter, the logical Drive number, and the network path to the physical hard disk. The list of printers will contain printer relevant information such as printer path, shared name, and the likes. The same goes for the list of plotters. The printers and plotters will be initially determined by the printer drivers installed on the user's machine then validated against the printer and plotter list on the network. All of the many to one relationships are established because the Canvas, DatabaseEngine, PrintingEngine and ReportEngine will use the NetworkEngine to determine the existence and validity of the drives, databases, printers and plotters that were configured at the application level (hence on the user's installation of the FinanceCAD Application). END OBJECT
In most cases, a One to Many relationship determines that the modeled object has one or more of the related object. This is know as a "has a" relation. When you encounter a Many to One relationship usually indicates that the modeled object uses the related object. This is called a Uses relationship. This can mean that it uses the related object or is used by the related object. To know which of the two is entailed, you'll need to look at the related object's relationships section and the description.
One more object to worry about, it is the ImportExportEngine object. If you remember in the previous section, there was mention that the design, and the attached reports have the ability to be exported into more well known file formats for compatibity purposes. In this object I'll introduce sequences (or order in which steps are to be performed) and how to define them in the definition of the given object. So then, Here is the definition of the ImportExportEngine object:
OBJECT ImportExportEngine PROPERTIES: ImportFormats List ExportFormats List FileName Text FileType Numeric ImportFormat Numeric [Index to the Import File Format] ImportCompleted Boolean ExportFormat Numeric [Index to the Export File Format] ExportCompleted Boolean METHODS: Create <- The constructor, called when object is initialized Destroy <- The destructor, called when object is destroyed ImportFromDXF <- DXFFileName Text [Autocad Data eXchange Format] ImportFromWMF <- WMFFileName Text [Windows Meta File Format] ImportFromTHREEDS <- THREEDSFileName Text [3D Studio file format] ExportToDXF <- DXFFileName Text [Autocad Data eXchange Format] ExportToWMF <- WMFFileName Text [Windows Meta File Format] ExportToTHREEDS <- THREEDSFileName Text [3D Studio File format] ExportToDOC <- DOCFileName Text [Microsoft Word Format] ExportToWPD <- WPDFileName Text [Word Perfect File Format] ExportToPDF <- PDFFileName Text [Adobe Portable Document File] ExportToRTF <- RTFFileName Text [Microsoft Rich text Format] ExportToHTML <- HTMLFileName Text [HTML 4.01 Compliant format] ExportToTXT <- TXTFileName Text [Standard ANSI Text File] ExportToCSD <- CSDFileName Text [Comma Seperated File Format] ExportToXLS <- XLSFileName Text [Microsoft Excel Spreadsheet] ExportToWKS <- WKSFileName Text [Lotus File Format] ExportToDBF <- DBFCFileName Text [X-Base compatible format] SEQUENCES: Importing from a format 1. Select the file to be imported 2. Determine format based on file extension 3. Perform the import Exporting to a format 1. Select a file from the list of files 2. Select the desired output format 3. Perform The export RELATIONSHIPS: Many To One -> Canvas Object One To One -> NetworkEngine Object DESCRIPTION: The ImportExportEngine object is created at the start of the application and available live from the main application object. when a Design is created, or opened, the ability to export the design itself or the reports are also made available for direct access to it's functionality. This way the user can export the design and/or the reports anytime he or she wishes to do so. The many to One relationship with the Canvas object is defined because Any of the open Canvas Objects (hence any Opened design files) can be exported. The One to One relationship with the NetworkEngine Object is present for drive and folder validation purposes only. END OBJECT
You can see that I used file extension as a mean to differentiate the different file formats I plan on being compatible to for the design file and for the reports as well. You can also see that I don't import anything for the report files as only exporting of our reports are necessary. Here to the constructor and destructor of the object are named the same as all other objects for familiarity and the beginning of a certain naming convention that can be followed all the way through the coding phase. As you can see, sequences are nothing more than an ordered enumeration of what needs to happen in what order, simple as that really. And that goes for any model that may need any type of ordered list of objects or list of actions to take.
And there we have it, the modeling is completed. we've defined our application object and it's 6 components. In the coming section we'll see what we can extract, as far as notions are concerned, from the model as well as some special considerations and notes that need to be mentionned for all your modeling projects.
As I mentioned before, this model is rudimentary and at the surface level of the objects it models. The goal here is to teach you what modeling is and I believe this top level of refinement is more than adequate to show you how it's done. In a typical scenario however, you would be modeling everything from the top level down to the bottom levels of an object hierarchy. To know how low a level you need to go to, you just need to know where your entities end and when you can only talk of properties and methods of your entities. When you can no longer define an entity as having sub entities (objects) then the hierarchy is complete and so is the levels of refinement of your model. It's the best trick I can give you.
The order where I defined the methods is important in this model. the only Object I have defined sequences for is ImportExportEngine object. In the case of the other objects, if a certain order of things is needed, they can be define simply by the order in which the methods are defined in each object. The specific order of things are usually defined either in the user requirements document (when the order are ordered set of steps or commands to get towards the accomplishment of the desired function). or the detailed analysis document (when the order of things are steps to execute a given process).
This is why it's important to be prepared before entering the conceptualization phase. As you can see here, when you have all the documents you need, before you enter the conceptualization phase of the development cycle, you have all the information and tools you need to get through the conceptualization phase as straightforwardly and as smoothly as it can possibly be. And since this phase is a big part of the development cycle, I would urge you to take the time to be as prepared as you can be before you start the conceptualization phase. You'll thank yourself later.
A WORD OF CONCLUSION:
That was a big load to digest wasn't it? Well, when you have the right notions, it is a big job to conceptualize, but it can be quite rewarding as well, when you are well prepared, you'll find out that this phase will be invalluable for the rest of the development cycle. I can't stress enough that the key to this phase, and absolutely all phases of the development cycle (as defined in the 1st part of this series) is to be prepared. If you take the extra time to ask the right questions, you'll get the right answers to work with. This is true for all phases. There are types of projects that for some reason are harder to gather a complete range of information than others. This is usually a sign that the application will need to consider adaptability in the process. For example, many reporting systems may not know, in advance the whole list of reports it will need to create. In this case, being prepared means you have a list of report as are currently known. Adapability means the reporting engine is designed to accept new reports as if they were always part of the list of reports and therefore can be as integrated to the system as the known reports would be. There are other situation where it's difficult at best to acquire a complete list of specifications or list of reports, or list of things that will need to be implemented as well. But again asking the right questions in this case will tell you, atleast, that what you have is incomplete and should be made to grow. This is also called programming for the future.
And that's it for this part of the series. I hope you enjoyed it, and especially, I hope you learned what I tried to teach in this document. Remember, as always that I am there to answer questions as well as for comments and suggestions so email me with any concerns or discrepencies in what you've learned so that we can clear things up together. AS such, a note must be made that the contents might change if I get enough requests to make certain parts of this document clearer than they already are. In the next section we'll attack the coding phase in all it's glory. We'll see why being prepared is important at that phase too, just like all other phase of the development cycle, and we'll see all the special consideration we'll need in that phase. Happy reading and see you then.
Stephane Richard (MystikShadows)