Jojo's 2008 Design Study
Contents |
Design Study
I will be using the design case study from my COSC460 Research Project on multiple-paged page turning animations on my attempt to improve Digital Music Stand.
Rough Progress Log
Background
The title for my honours project is ‘Improvements for a digital music stand’. One substantial part of my honours project is to extend its freature: Adding and implementing a multi-paged view page turning algorithm for Espresso Latte digital music stand. It was originally written in C++ and it then was ported to C# with .Net 2.0, and Windows Form as it’s GUI implementation.
Initial design
The image below shows the final designed by Alexey Blinov, a Cosc Honours 2007 student, which also did this course. He came up with this final design at the end of the course. It is a very well balanced design, though to say the least it is only good relative to the software requirements at that time. His design was bound to the software requirement which have now changed. The first main requirement that has changed is that now we have to be able to have show multiple pages at the same time. The second is the fact that we would have two multiple-paged page turning algorithms.
And thus, my task is to improve his design based on the new requirements. At the start of the design study, the “motto” (so to speak) here is to work with his design as much as possible.
Design critique on the initial design:
- Document.open PDF? – Keep behaviour and data together
- Model the real world
- There are components that are conceptually coupled. Painter has made itself responsible over two things: the actual page display AND deciding which transition strategy to use. It would be very nice if we could separate this two distinct apart. (One stable abstraction, Separation of concerns, Single responsibility principle). Frankly speaking, this has caused me grief and headache and some difficulties of sleeping peacefully because now Painter has to deal with more stuff: painting the page transition, painting the pages itself, and painting multiple views! This is certainly not obeying Single responsibility principle. And as a result of this, Painter gets really complex and does multiple things at once. The responsibility has to be shared to be balance across all classes.
- There are absolutely frustrating bottlenecks in the initial designs, on how OldImage and NewImage. This limits me to expand to have multiple pages.
- Some minor stuff such as naming of method is not so good or descriptive to the context
Second design
I added more classes into the first design, to try and see what I can do to extend the original design:
- In the Model layer, I added DocumentFragment. To view the document as a multiple view, I decided to have a concept of a fragment of a document. This represents the framents of document. This may have violated the Model the real world design maxim. But I have encapsulate more granularity of control.
Now, we can have a statement “Document is made up of DocumentFragments which in turn made up of Pages”
- In the Controller layer, I added DocumentFragmentController, DocumentController. The reason is the same, and that is to get the granularity of control that I want.
- Also, in the controller layer, I added ViewStrategy: SingleViewStrategy & MultipleViewStrategy but this leads me to Parallel hierarchies problem because now SingleViewStrategy and MultipleViewStrategy has some "subclass hierarchical matching" to do with the PainterStrategy.
Furthermore, there are many cases where interfaces (IViewer, IPainter, etc) are limiting my freedom. All of my changes have to obey the contracts imposed by those interfaces. Now, the dilemma is, if I do change those interfaces, I have to change many things within the code even to the point of changing tiny that are not related Shotgun surgery smell. Everything convoluted with each other and because of the contracts imposed by the interface. This has forced me to break out from his design entirely.
Final Design: Mini, a simpler Espresso
After some playing around with Espresso source code, I found that there are many unnecessary modules that are not used at all to accomplish my honours project. I dont regard this as my software requirements. Thus, I have decided to start from stratch to focus on what I wanted to accomplish, instead of trying to try make changes and have to care about what this might affect other components of Espresso (yes, I am lucky in a way that the system is not huge) and look for what Alexey has done for inspiration and guide, especially where I agree with what he did with his choice of decisions.
The software’s functional requirements
- [DONE] Can Open PDF file, and
- [DONE] Convert it into Image file (PNG to retain image integrity)
- Able to have MultiView, but
- Still have to be able to have SingleView
- If we have MultiView, we have two methods of page turning: OneStep and MultiStep
- If users are in SingleView, that means OneStep and MultiStep are basically the same thing.
- (optional) Can adjust speed of transition
- (optional) Dynamically change preferences/options
I will be trying to use the Model-view-controller architectural design as general guide to separate the three layers. This is important because I have to aim for less coupling between presentations (view), the business logic (controller) and the domain knowledge (model). But most likely what will happen that my software architecture would be a variant of Model-view-controller architecture, like Model-view-presenter architectural pattern by Martin Fowler, since in Windows Form the boundary of View and Controller is quite blur and thin. There are grey, crossover regions.
In the next section, I will explain what classes I have carried over to my third design and how they have changed.
Model
- Page: Obvious choice. This class . I strip out all codes regarding OMR (Optical Music Recognition) stuff because as it does not concern us any longer
- Document: Another obvious choice.
- DocumentFragment (?)
Controller/ViewModel
- MiniUtilityClasses: I also carry over this utility lass which deals with
- PDF2BitmapConverterUtility: I also carry over this utility class which deals with opening PDF file. There is an implementation of ImageMagick system calls inside it that converts these pdf pages into png files. and thus this is a static class, which make sense. But the naming is quite long Long method name smell.
View/Presenter
- MiniMainForm: Handles event handling of the top level stuff.
- PagePlaceholder
The sole design heuristic and principle that will drive my design is the Tell, don’t ask principle. I will not follow it blindly, however. It will be the main design heuristic that hopefully could dominate and permeate through the entire design.
Instead of having Painter who does all the work (both painting the transition and the pages; instead of having one canvas and one painter to draw multiple pages, and draw transition of each pages, I choose to have one canvas with multiple placeholders.
By having placeholder, the responsibility of is shared and encapsulated. Though the downside of it is that it maybe a bit more expensive because we have more objects to create for each placeholder. However, I think if the responsibility is shared then it is just what I want to achieve, a little bit of cost is ok.
Also, The responsibility of displaying the page is for the page to care about. The Painter will ask, “Ok Page 1, show 70% of yourself, and Page 2, start showing 20% of yourself, while I will paint the 10% visual transition cue.” Painter will not ask for the page (as it currently does) but it will tell them to show themselves Tell, don’t ask principle.
The final design would look something like this:
Design Maxims
Followed design principles
Violated design principles
The Use of Design Patterns
I believe design pattern is just a software design aesthetic which reconciles differences between two conflicting design principles/forces. As even one of the GOF guys (I think it’s Erich Gamma) has mentioned that Design Pattern is used wisely only “as necessarily when it is needed to as to not over-complex the software modules”. This even implies that even if you CAN use design pattern but if the simple design can already encapsulate the functional/nonfunctional requirements needs of the customer, then there is no use to apply design pattern except for bragging rights.
- Singleton
- Strategy
- Iterator
Other Honourable Mentions
Source Code
Here is the source code for the second design: Media:MyExpresso.zip
Here is the final design's source code: Media:Mini0.5.zip (A lot of the classes have not been implemented yet since a lot of time spending coding to extend, rather forcefully, the second design AND bug fixings). It was very late of me to decide to break free to "rewrite" and start again from a clean sheet). But the class diagram pretty much tells what I am about to do with this one.