Saturday, January 16, 2010

Day 9

I spent Friday finishing up the text box which is now nearly in its final state. Just before lunched I paired with Mike, a visitor to 8th Light, and gave him a general intro to Test Driven Development and Pair Programming. At lunch I presented my two new testing patterns to the 8th Light guys, and got some general feedback. For the rest of the day, I wrote the Mouse Processor, completed some linkage between the TextModel and both Key and Mouse processor. All that remains to be done is optimize the repainting of the TextPanel at appropriate times.

Design Patterns:

*Command Pattern: The Command Pattern can be used to capture and store a request as an object, and then calling some abstract command, thus allowing you to populate clients with different and log-able operations.
To do this, a Command interface is created with an abstract execute() method and several concrete subclasses which are designed to define their own execute(). Whenever a request is made, it will call execute() on its instance of the Command interface. The instances of the subclasses will know who their respective receivers are, and what steps must be taken to complete their action.
This could be used to create a flexible barrier between some UI and application. A user could initialize some request by pressing a button or clicking some start key, thereby calling the application to action. Since the UI doesn't know who the request belongs to, or who the receiver of action will be, it would use its instance of a Command (given to it upon initialization) and call execute() which will generate the appropriate response.
So when, for example, a start button is created, it is given a Command object from the application. This command object will be some concrete class named StartCommand, which is a subclass of a Command interface. When the start button is clicked, it calls execute() on its Command object (of which the type is unknown to the button) which gets routed to the StartCommand. The StartCommand is then able to follow through with the necessary actions to 'start', calling the appropriate methods on its receiver.
Using this strategy, all UI interactions can be separated from the application, and all dependancies will flow at the Command Interface. It also means that all commands can be logged, and thus many of them could even be reversed.

This is actually quite similar to the structure I set up for my KeyProcessor. The TextInputPanel gets some keyPressed event which then uses some algorithm to select the appropriate processor. The TextInputPanel then calls processKey() on the selected processor, which proceeds to make the needed changes on its receiver the TextModel. The main difference is that for the Command Pattern I might have a KeyProcessor for each key which calls processKey() on its own KeyProcessor rather than having a Dispatcher in the keyPressed() method that decides who gets the command. The basic idea is quite similar though.

*Adapter Pattern: The Adapter Pattern allows two unrelated or unconnected interfaces to be connected so that they may be used in conjunction. This is done in one of two ways; either using a Class adapter or an Object adapter. The class adapter will inherit from one of the interfaces, and implement the other, linking the methods of the inherited interface to the methods of the implemented class. The object adapter will inherit from one interface and through some means get an instance of the other, and then connect the method calls from the parent by making calls on the instance. The exact manner in which this occurs is a tid-bit illusive to me and I think depends largely on circumstance.
Though a stretch, one example of this could be that my TextInputPanel, through the TextModel, is an adapter for the TextLayout class. A limelight app would be the Target, the TextInputPanel would be the Adapter, and the TextLayout would be the Adaptee. This would be the object adapter case. Limelight wants a Panel that can have some text and is clickable, and there is this TextLayout class out there that already has many methods to assist with these features, but isn't a Panel. Thus the TextInputPanel is used to adapt the TextLayout's functionality by inheriting from the Limelight Panel, and holding an instance of the TextLayout.
Limelight gets some MouseClick event, which is handed off to the TextInputPanel. The TextInputPanel then takes the request and (through some indirection) gets some TextHitInfo from the TextLayout, and therefore adapts the Layout to the Panel.
Let me know if there are any clarifications you can give as to the exact nature or best way to use the object adapter. I am not entirely certain as to how you get an instance of the Adaptee if it is meant to be an interface.

Now to optimize the painting of my panel.

No comments:

Post a Comment