View this PageEdit this PageUploads to this PageVersions of this PageHomeRecent ChangesSearchHelp Guide

MP9

HW 9: Refactoring

Homework 9: Refactoring


In this homework you will apply patterns to refactor the method retrieveContents: in the FtpUrl class. This method retrieves the contents of FTP sites. It is long and not easy to read. Before making any changes to it, make a reference copy of this method - it may save you frustrations later on.

As usual, a test file is provided at the bottom of this page. File it in. Run it after every step to make sure that you don't introduce any bugs. Read the setUp method before you start to understand what the tests do.

In your refactoring, follow these steps in order:

1) Apply the Method Object pattern. Create a class for the retrieveContents: method. Move the method to the new class. Change method's local variables into instance variables of the new class. Change the original method in FtpUrl class so that it creates the Method Object and calls it. Test to make sure that the code works. (Remember to change the references to 'self' when you move the method).

2) Using the Extract Method refactoring in the Refactoring Browser, break the original method into smaller methods. Give each new method a meaningful name. Leave the code starting with "filename == nil ifFalse" as a single method for now. If an instance variable is used in only one method, make it temporary to that method. Test to make sure that the code still works.

3) Note that a large portion of the original method depends on the URL format. Requests for files are handled differently then requests for directories. The code at the beginning of the original method determineswhether the URL is a file or a directory and the code at the end of the method performs different processing based on this distinction.
Use the Choosing Message pattern to refactor this part of the code. Create subclasses of your Method Object, one for files, and another one for directories. Have the retrieveContents method in the FtpUrl class invoke a new class method on your superclass. In that method, instantiate the appropriate subclass (i.e. move the code from the beginning of the original method to the new class method). In the subclasses, implement a method with the file- or directory-specific processing. Define it as an abstract method in the superclass. Test again. And again :) Note that making the test cases green does not mean that your code works, you need to make sure that the Scamper shows meaningful data.

4) Finally, clean up the code to ensure that each variable is defined only in the classes/methods that use it.

Look back the results. Isn't this code easier to understand than the original?




Advice


Refactoring Browser

For this assignment, it might be easier to use the Refactoring Browser (though it is not required). If you want to try it you will need to use the SqueakMap Package loader to install it. In Squeak 3.9, the Refactoring Browser depends on the AST package. You can find a rough guide to installing packages in Squeak here.

The Refactoring Browser in Squeak has at least one very annoying bug: you cannot use rename method on it. This has been reported here. Currently it also suffers from notoriously bad user messages for errors.

I have gotten Extract Method to work on my image. However, it is very picky about the selected text and if it does not like the selected text, it does not offer a good explanation why. If it accepts the selected text, a dialog will pop up. In the top-most text field, you should enter the name of the new method. Make sure to include the necessary colons (:) because if you forget it will not work. After entering the new method name, hit alt-s (or Accept from the contextual menu). If it passes the checks then the OK button will turn white and you can perform the refactoring.

Installing Scamper

Follow the normal procedure for installing SqueakMap packages. To get scamper to work, you need to install the Scamper package and also the Network-HTML package (this is mentioned here but not in the description on SqueakMap). Those are the only two packages that you need to get Scamper to work.

Doing this assignment without Scamper (submitted by Brett Daniel 3/7/07)

For those without Scamper (or those who do not want to install it), the following unit tests will run the method under test without relying on a browser window:


FtpUrlRefactoringTest>>testFTPFileNoScamper
| url content |
url := FtpUrl new schemeName: 'ftp' authority: 'ftp.freebsd.org' path: #('pub' 'FreeBSD' 'README.TXT') query: ''.
content := url retrieveContents content.
Transcript clear; show: content.
self assert: (content size > 0).



FtpUrlRefactoringTest>>testFTPDirectoryNoScamper
| url content |
url := FtpUrl new schemeName: 'ftp' authority: 'ftp.freebsd.org' path: #('pub' 'FreeBSD/') query: ''. "note the trailing slash"
content := url retrieveContents content.
Transcript clear; show: content.
self assert: (content size > 0).



Files


CS598rej Grading HW9.st



Deliverables


By now, you should have developed aversion to:

  • methods that do not fit in the browsers' window

  • non-descriptive method names

  • method names that start with get/set

  • conditional statements (use polymorphism instead)



Note that all but the 3rd observation apply to other OO languages as well. So make sure that your code does not suffer from those code smells.

For this assignment, send me an e-mail with the methods that have changed using the standard notation.

Link to this Page

  • Machine Problems last edited on 14 May 2008 at 4:25:53 pm by c-98-212-224-168.hsd1.il.comcast.net