The Source for Java Technology Collaboration
User: Password:



William C. Wake's Blog

Programming Archives


In Memory - Dr. Sallie Henry

Posted by wwake on April 11, 2006 at 10:40 AM | Permalink | Comments (0)

Dr. Sallie Henry died March 7, 2006.

She came to the Computer Science department at the University of Wisconsin - LaCrosse, in 1979. Her energy and enthusiasm were a real boost. She encouraged many students - most of the CS people I know from those days are still actively in the software business. At LaCrosse, she brought in undergraduate research opportunities, and she helped push the programming team to prominence.

In the mid-80s, Sallie moved to Virginia Tech. There she continued a focus on teaching, the programming team, and research in the area of software metrics.

Sallie retired a few years ago, and I've hardly had contact with her since then. But I can't let her passing go by without an acknowledgment of how much she meant to me and my peers.

Structure and Interpretation of Computer Programs

Posted by wwake on February 15, 2006 at 11:19 AM | Permalink | Comments (2)

Somebody at MIT was nice enough to make available the videos for lectures on Structure and Interpretation of Computer Programs, by Abelson and Sussman.

It's a refresher in just how powerful Lisp is. For a language approaching 50 years old, it's pretty amazing.

I always crack up a little when I think about the reasons Lisp and Smalltalk couldn't go "mainstream" - why, they use too many resources! (My web browser looks like it's running in 41 meg so I can type into a non-styled text box. I doubt Lisp or Smalltalk would do worse than that:)

Anyway, if you've never studied Lisp, these lectuers are a good excuse for trying it out.

Martin Fowler's article on Language Workbench

Posted by wwake on June 24, 2005 at 04:42 AM | Permalink | Comments (0)

Martin Fowler posted a good article on the idea of Language Workbenches, followed up by some nice links and more reading: http://www.martinfowler.com/articles/languageWorkbench.html and http://martinfowler.com/bliki/LanguageWorkbenchReadings.html

Anonymous subclass with instance initializer

Posted by wwake on February 21, 2005 at 07:26 AM | Permalink | Comments (10)

In JUnit Recipes, JB Rainsberger points out this idiom:

static final Set s = new HashSet() {{
  add("this");
  add("that");
  add("another");
}};

(JB points to an article by Paul Holser, which cites Dave Astels' Test-Driven Development as the source.)

What's it do? The new HashSet(){}; part creates an anonymous subclass (a new type of HashSet without any name). The inner braces are an instance initializer, run before the constructor (implicit and empty) of our new class. So this code creates a new Set, and fills its contents.

OOPSLA '04

Posted by wwake on December 05, 2004 at 01:38 PM | Permalink | Comments (0)

I'm always struck by how everybody goes to a different conference. This was mine...

10-24-04 - Sunday, and 10-25-04 - Monday

"Usage-Centered Design in Agile Development", by Jeff Patton. This tutorial used a series of exercises to simulate how UCD works.

"Dungeons and Patterns", "Test-Driven Development Workout" - Steve Metsker and I offered our tutorials on patterns and TDD. We also did a session on Framegames for the Educator's Symposium.


10-26-04 - Tuesday

"The Future of Programming", by Richard Rashid. He described several interesting bits of research. One system created a "black box for humans", capturing video every few seconds. SPOT is Small Personal Object Technology, e.g., very smart watches. There will be a kit available 1Q05. He also described research in development tools, for better testing and better modeling.

"Mock Roles, not Objects" by Steve Freeman and Tim MacKinnon. This left me once again aware of how different the mock object approach is from how I do TDD. The design seems more conscious. I don't know how much that's good or bad. It does make dependency injection more natural.

"Systems of Names and other tools of the not-quite-tangible", by Ward Cunningham. He reviewed the idea of mining experiences for patterns. He used System of Names as an example of this, with a very simple Problem => Solution form. He also likes the idea of leaving room for new things: the wiki has a prompting statement for new pages. Finally, Ward reminded us of the importance of being receptive to discovery and integration of new ideas.

"Methodology Work is Ontology Work", by Brian Marick. Ontology refers to the kind of things that exist (philosophically). Brian highlighted Lakatos' philosophy, and suggested that the result is that it's rational to produce a program that seems exciting and spins off results (regardless of its "truth"). (To be fair, Brian pointed out that Lakatos would hate this attitude.)

So:

  • Have a hard core 3-6 postulates.
  • Work out the consequences, and merrily ignore counterexamples.
  • Prefer novel confirmations.
  • Keep throwing off new results.

Brian described a second "trick": use perception to provoke action and reinforce ontology. For example, have Big Visible Charts that show a team where it is; have monitors that go red when tests break.

"Agile Customer Panel" (various).

  • "Customer is not an administrative role" (?)
  • "Customer interaction patterns are simple but difficult" (Linda Rising)
  • "How do we know what has value?" Put it in ridiculous order, and let the customer rearrange it. Tie groups of features to business value, favoring early deployment as proof.
  • Customer prioritization is hard but has the best opportunity for creating high value.

"First courses in Computing Should be Child's Play", Alan Kay. Changing the bulk of people requires a contagion model. Flow as a balance of challenge and ability.


10-27-04 - Wednesday

"Code Complete", Steve McConnell. There are plenty of bad ideas, but there have been advances: higher-level design, daily build and smoke test, standard libraries, Visual Basic, Open Source Software, the web for research, incremental development, test-first development, refactoring as a discipline, faster computers. But - software's essential tensions remain: rigid plans vs. improvisation, discipline vs. flexibility, etc.

"JMock Demo".

"Wiki BOF". Seeding can be important: seeded pages with incomplete ideas, invited guests, no passwords, compelling questions, etc.


10-28-04 - Thursday

"Amazon Web Services", by Allan Vermeulen. There will be computer-to-computer "grid computing" superseding the person-to-computer web computing era. He demonstrated a variety of tools that you can use with Amazon to make this work.

"Outsourcing - How will your job change?" (panel). It's clear there's fear of outsourcing, but it can work. Approaches built around the idea that "they" aren't just as smart as "we" are are misguided and doomed.

"Exocumputing", Jaron Lanier. He tried to suggest different approaches to computing. Computers as built today are very brittle. Perhaps we can try new ways inspired by biology.


Overall, I enjoyed the conference. But it was a lot heavier on philosophy than technique. The thing I'm most inspired to do is investigate what's happening in the Amazon "grid service" space.

Refactoring Thumbnails

Posted by wwake on August 09, 2004 at 10:45 PM | Permalink | Comments (0)

Sven Gorts has introduced what he calls Refactoring Thumbnails. These are UML-like diagrams augmented with some flows, and used to summarize refactorings. (For example, the UML might have no words, but rather squiggles to represent identical text in two different classes.)

In addition to summarizing the transformation involved in simple refactorings, he uses these to show how large refactorings can be created out of smaller ones. A nice example is Break Module Dependencies With Adapter. He shows that you can break package dependencies by doing Separate Interface from Implementation, and then Introduce Indirect Class, or by doing these in the opposite order. For Evolving to the Proxy / Decorator Pattern, he shows several approaches that end up in the same place.

I really like these summaries, and I'll use this approach to help manage my focus on large refactorings.



Refactorings require new tests

Posted by wwake on May 31, 2004 at 05:19 AM | Permalink | Comments (0)

Someone asked on the XP egroup about getting access to private methods for testing purposes. Others suggested a number of ways to get this effect, but it got me thinking about refactoring.

Refactoring is often thought of as a pure, safe transformation: convert a program into another program with the same semantics but a better design. From the standpoint of a refactoring tool, the "same semantics" part is crucial.

But refactoring also has a psychological side: a better design, but also a different design. A different design may induce people to act differently (indeed, that's why we do it!). In particular, a different design may give people different expectations about code.

Following are some examples. In each case, I'll assume the code was created by test-driven development, and adequately tested before the refactoring.

  • Extract Method - the code worked as part of another method (and still does). But now, the reader's going to assume they can call this method from other parts of the class. Is the extracted method tested sufficiently on its own terms?
  • Expose Method (private becomes protected) - now, subclasses expect to be able to call this method (either directly or via a call to super()). We'll need to create testing subclasses to verify that it works in that context.
  • Expose Method (to ) - Other objects are free to call it. The original object no longer has control over the order in which this method is called. (We may have had a method that was only to be called if another method was called first; when it was private, we were ok; if we expose that method, it's hard to enforce this obligation.)
  • Extract Class - The object now stands alone. Is there a test class testing this object by itself? You may need to extract a new test class, but you also may find you need new tests to cover everything.


Scratch Refactoring

Posted by wwake on May 12, 2004 at 03:54 AM | Permalink | Comments (5)

I recently had a chance to do some refactoring of some Visual Basic code. I hadn't worked with it in several years. In particular, I hadn't worked with the object support that's in VB.Net. It's very striking how much it's like C# with different keywords.

My task was to convert some code from using web services (which were too slow) to just straight object code. Several factors came together:

  • My unfamiliarity with VB.Net and web services.
  • The fact that I was heading out of town for a week and didn't want to risk leaving problems.
  • The team's use of source control which locks checked-out files. (I'm lobbying to change this.)
  • A desire for extra care as the product has almost no automated tests.

This led me to do a scratch refactoring: refactoring with the intent of throwing it away and re-doing it. I refactored away two sets of web services, writing down each of the changes I intended to make (along with the name of the affected file.)

I found several benefits:

  • I learned some little tricks for how to get the compiler to tell me what needed doing.
  • Knowing I would throw the result away let the scratch refactoring go more quickly.
  • I learned a couple tricks for the IDE.
  • When I came back after my trip (to do the real thing), I felt like I was just flying through the changes.

I think it was Brooks who said something like, "It's faster to make a 6-inch mirror and a 10-inch mirror than it is to make a 10-inch mirror." I found that true in this case.



Tools - especially JUnit and Fit

Posted by wwake on December 25, 2003 at 03:22 AM | Permalink | Comments (2)

I'm reflecting on the most important tools I've been using this past year for my Java projects.

  • IntelliJ Idea - A fine IDE. My current default.
  • Eclipse - I've used it some, and found it a little clunkier than IntelliJ's. But I plan to move toward it more this coming year.
  • P4 - Perforce source control system. It's free for a single user, and does a nice job.

I've used two primary testing tools:

  • JUnit - for unit testing.
  • Fit - for system/acceptance testing.

JUnit is a simple unit testing framework. Suppose we're testing the Stack object. Here's an example test. The framework will locate the method via reflection (it treats methods starting "test" as tests):

import junit.framework.*;

public void TestClass extends TestCase
{
   public void testSomething() {
     Stack stack = new Stack();
     stack.push("Test string");

     String result = stack.pop().toString();

     assertEquals("Expected last value pushed", "Test string", result);
   }
}

(This test case fits a pattern I call "Arrange, Act, Assert": it sets up data, calls a method under test, and then verifies that it worked as expected.)

JUnit lets you create setUp() and tearDown() methods that will be called before and after each test method in a file. It has a number of other assertion methods (assertTrue, assertNull, etc.)


Fit is a tool for higher-level testing, available from fit.c2.com. It allows a Customer or tester to write tests in a spreadsheet (a very familiar interface). The tests are exported to HTML, and fit reads and runs them.

I typically use fit with a program known as FitNesse. FitNesse is a standalone wiki that knows how to run fit tests, either individually or in suites.

I can't create tables in this blog, so you'll have to use some imagination. But a fit test might look like this:

myprog.fit.NameFixture
in           formatted()
Joe Fish        Fish, Joe
John H. Doe      Doe, John H.
Queenie         Queenie
Dodge, B. R.      Dodge, B. R.

Fit has a number of builtin test classes that you can extend.


Both these testing tools can help change how you look at tests. They're both good additions to your set of tools

Happy new year to all! --Bill





Powered by
Movable Type 3.01D
 Feed java.net RSS Feeds