![]() |
||||
|
As explained in my project proposal document, I had several overall goals for this independent study project:
Learning the Unified Modeling Language In the past, most of my designing was in the form of inheritance diagrams and simple lists of methods and interfaces between components. For this project, I decided that I would use learn and apply the industry-standard Unified Modeling Language (UML) during the design process. Because UML is a very large, encompassing specification, I decided to read a book that, instead of trying to cover every aspect of it, focused more on how to use it in practical situations. I chose to read UML Distilled by Martin Fowler (Addison-Wesley, 2000). Overall, the book was very helpful, although there were sections that it didn't explain in the best way. In CS3141, we were given a few lectures and some sparse notes on using UML; having learned UML already and having already started to use it was very beneficial to my group in that class. Between that project and this one, I feel that I have a good grip on using UML for the basics of software design. I am confident that these skills will be useful when I get out in the real world and do development at a real company. One specific goal regarding UML that I mentioned in my proposal document was to "be able to easily and effectively communicate the project's architecture." I used Rational Rose, a very un-user-friendly but nevertheless powerful tool, to create class, sequence, and state chart diagrams. The advantage of UML is that anyone can then look at these diagrams and be able to more easily understand the overall design of the program. Even though I made the diagrams and understand them, I am somewhat doubtful of the extent to which my design can be understood just from the diagrams. Obviously, they are better than nothing at all, but I think my diagrams are best thought of as design references and must be accompanied with additional documents explaining the design as a whole. Designing Before Coding To a certain extent, I had always done some designing before sitting down and writing code. For instance, I remember sitting down with my notebook in the summer of 2000 and defining interfaces, methods, and properties for the old Solitaire Pack version. When I wouldn't be able to physically be in front of a computer, I would spend time thinking and writing down ideas for how to implement a program. Often, however, my preplanning would simply be of classes and would not include much interaction between objects or program logic. I would start writing code, and trying to design things as I go: a strategy which often led to headaches, the need to redesign fundamental portions of code, or the loss of motivation to work on the project at all. Because this project's design was based primarily on the architecture of the prior version, there was not the need to brainstorm different ideas of how to do certain things. Instead, I could jump right into Rose and start putting the design into diagram form. One aspect of the program, however, that I did need to spend some time thinking over was the mouse state diagram. In another document, I explain how I use a state machine to greatly simplify mouse event handling. Because the old version's mouse event code was such a mess, I knew I would have to redesign this part from scratch. I simply sat down and started drawing out a state diagram, showing which mouse events would lead to which states, and what resulted from the user's actions. Although the diagram seemed somewhat intimidating to me at first, it does do an excellent job of breaking down the logic into an easy-to-understand form. When it came time to write the mouse event handling code, I based it entirely off of the state diagram and was amazed at how easy it was to implement. This was a direct result of taking the time to think out a design before sitting down and writing the code. There are some ways, however, in which I fell short of realizing this goal. Obviously, I knew that my design diagrams did not cover every little part of the program. My diagrams of the Undo architecture described the general idea of how undo/redo would work, but while I was coding I found that I hadn't thought it through very well at all. Also, other aspects of the program, such as the logic of the individual games, was largely based upon the old version's code and wasn't thought through very well this time around. Despite not realizing this goal completely, I feel that I have definitely reaped benefits from spending weeks doing pure designing before writing code. The fact that I was able to complete a project of this magnitude within the remaining time, without too many headaches and without deviating too much from the original design, shows how beneficial proper design is. Hopefully I will remember the importance of design as I return to working on other projects. Improving Object-Oriented Design As described in my project proposal, I hoped that this project would help to improve my object-oriented programming skills. I feel that this is definitely the case. Many programs that I have written have had everything lumped into the MainWindow class, leading to code that is hard to work with. In the old version of Solitaire Pack, the majority of functionality is in the "CAppImpl" class, that is, the class equivalent to this version's CEngine in that it was what implemented the ISolpackApp interface. The old CAppImpl class handled everything: it managed the Web Browser control and HTML document; enumerated all registered games; created the Game Menu and handled clicking on menu items; managed the undo/redo stack directly; displayed the 3D Shatter animation directly... In all, CAppImpl did everything. This version's CEngine class just implements the things specific to playing a game. The game menu is a separate class; there is an Undo Manager class to manage the undo/redo stack; there is a separate Library Manager to handle registering and enumerating game library objects. By taking the time to design the program first, I was able to better break down functionality into independent components that encapsulate specific aspects of the program. As a result, my code is easier to read, understand, and maintain. Overall, I feel my object-oriented design skills have improved greatly as a result of this project. |
May 9, 2002 | jmhoersc@mtu.edu |