|
Comp201: Principles of Object-Oriented Programming
|
Pledge of Honor |
1. 25 pts | 2. 20 pts + 5 pts extra credit | 3. 25 pts | 4. 15 pts | 5. 15 pts | Total 100 pts + 5 pts extra credit |
Take the frog example in the State Design Pattern lecture and convert the code to use (an) anonymous inner class(es). Your code must meet the following criteria:
The IFrog is in the supplied code which includes the test code your BetterFrog must pass.
Suggestion: Write and test your best initial attempt at the problem. Then carefully
review your code and ask if you can modify it to better meet the above criteria,
especially #5 and #6. Modify your code and review it again. Repeat this process
until your code is perfect!
Consider an IList whose first (if it has one) is an IList. That is, consider a list that contains lists. Below is an example of such a list.
((a , b, c), (), (d, e))
Write an IListAlgo visitor, called CountAll, that will count all the elements in all the contained lists of a list of lists. An Integer object should be returned. For example, for the above list, Integer(5) should be returned.
Your code must conform to the following specifications:
The listFW package has been supplied, including the test code that your code is required to pass.
Extra-Credit: 5 points extra-credit will be given to a tail recursive visitor.
In general, the user interface of a system is a variant with respect to the actual computing process that goes on behind it. Examples of this are the "skins" on various software audio/video players and the configurable "look-and-feels" found in Linux and other systems. Likewise, the actual processing code can vary independently from the user interface, such as the different implementations of Mozilla on different operating system platform which all have the same user interface.
To decouple the "model" (where the actual processing takes place) and the "view" (the user interface), we employ what is called the "Model-View-Controller" or "MVC" design pattern. This design pattern uses "adapter" objects to connect the model and the view together, creating an indirection layer between them which enables them to vary separately. These adapters are part of the Adapter design pattern (for additional, optional reading, see the Java Resources web page). The adapters "translate" calls to their methods to method calls on their target objects, which may be quite different.
The job of the "controller" is to instantiate all the pieces of the application and tie them all together into a fully operational system. Since the view only talks to its adapters and the model only talks to its adapters, neither the model nor the view know anything about each other. The controller is the only object that knows about all the objects in the system. The controller does not do any processing of its own however. All it does is to set up the communications between the model and the view (after instantiating them and their adapters).
Consider the follow simplified MVC system (full documentation here, click here to see the demo):
The view above (MyView) does not ever talk directly to the model (MyModel). They are not even in the same package. Instead, the view has specified that when it talks to the model, it wants to see a very particular interface, namely, IModelAdapter. IModelAdapter has the one method, getResponseTo, that the view needs to communicate with the rest of the system. Since IModelAdapter is part of the view's specification, it is located in the view package. Likewise, the model has an interface which it has specified to communicate with the view, IViewAdapter which contains the method the model needs, display.
Notice that the method on IModelAdapter does not correspond, at least in name, to any method actually on MyModel. This is because the specifications of the view are determined independently from the specifications of the model, based solely on the needs of the view, not what is supplied by the model. Likewise the same is true looking the other way, we see that the method of IViewAdapter is not the same as any of the methods on MyView.
This is where the controller, AppController, comes in. Since the view and the model are decoupled and thus know nothing about each other's methods, the controller is the one piece of the system charged with actually knowing all this information. The controller thus represents the particular configuration of the system that pairs this particular view with this particular model. If we switch models or views, we would need to write a new controller. But that's all that would change. Any particular model or view is independent of the corresponding view or model that it attached to in the end.
The controller's job is to create the proper instances of adapters needed to connect that specific model and view together. Anonymous inner classes are beautiful tools for this job because they enable the controller to create a "custom" one-time-use class (instance actually) that is perfect for attaching a particular model to a particular view. For instance, above, the view wants to call the IModelAdapte.getResponseTo method. MyView has no idea that the model wants to take the given string and construct a silly quote from it. The view only knows that it is supposed to give the model the text from a text field and put whatever comes back up on a text area. The controller, on the other hand, knows what the model is trying to do and what the view is trying to do. Thus the controller can create an anonymous inner class instance of IModelAdapter whose getResponseTo method calls the MyModel.getQuoteFrom method and returns its result. Similarly, it can construct an IViewAdapter instance that calls the appropriate method on the MyView object. Once the two adapters are instantiated, the controller can install them into their respective model or view objects. Since both MyView and MyModel take their respective adapters in their constructors, the instantiation of the model's (or view's) adapter and the model (or view) can be written in a single line of code.
In the code that is provided, you must write 3 missing sections of code to complete its functionality (all clearly marked in the code itself).
You may not modify any sections of code other than what is clearly specified.
Consider a LRStruct filled with Integers. How can we sort the values in the LRStruct without creating a new list? That is, can we write an algorithm on a LRStruct that will mutate the list so that all the Integers will end up in order?
Let's examine the following "selection sort" algorithm:
Convince yourself that this will indeed sort the list.
We already have an visitor that removes the minimum value in a LRStruct of Integers: .RemMinLRS
Write an IAlgo visitor called lrs.visitor.SelectionSortLRS that uses the above algorithm.
The lrs package, including RemMinLRS and the test code that your code is required to pass has been provided.
Let's consider another technique for sorting a list, called "insertion sort":
Convince yourself that this will indeed sort the list.
We already have an visitor that does an ordered insertion into a LRStruct of Integers: .InsertInOrdeLRS
Write an IAlgo visitor called lrs.visitor.InsertionSortLRS that uses the above algorithm.
The lrs package, including InsertInOrderLRS and the test code that your code is required to pass has been provided.
Last Revised Thursday, 03-Jun-2010 09:50:18 CDT
©2004 Stephen Wong and Dung Nguyen