"COMPUTER POWER TO THE PEOPLE! DOWN WITH CYBERCRUD!" - Theodor Nelson
Thursday, December 29, 2005
Testing Abstract Code
I've been working on some java code lately and I came across something interesting. I have a set of domain objects that I wanted to make persistable via Hibernate. Now, these domain objects are meant to be used by other folks and they might want to map their Hibernate objects differently. So, I wanted to provide the support and maybe an example of how to map the objects. The problem was that I didn't want to bundle Hibernate just so that I could test the mappings.
What's a programmer to do? Well, to be Hibernate persistable, a class must have a default constructor and accessors for each field. Why not test for that? So, I quickly whipped up some code to iterate through the class path and find each of my domain objects. It then checks each class for the constructor and that each field has accessors. Wonderful. But, how do I know they work?
In the process of verifying everything, I had all of the reflection objects that I needed to verify that they worked as well. So, I invoke the default constructor and make sure no errors ensue. I then set/get each field with sample values and verify the results. If at anytime, an error happens, I output a reason and the test fails.
Now, I have a test that will keep me honest and tell me if I ever do something stupid to break my mappings. I can also enforce standards by testing if I wanted to. This is just another example of the power of meta-testing.
The design was simple. I had an object called ClassGenerator that was responsible for traversing the class path and providing class objects to an abstract method. It walked directories and jars respectively. The next object was a ClassFilter that would be given to the ClassGenerator to work much like FileFilter does. I did this so I could create a filter for my domain objects and outright reject classes that were out of my control. The last object was a Verification object that was responsible for making sure a class was correct (default constructor, all accessors worked, etc). The test is where everything was put together. He creates an inner class that subclasses ClassGenerator and hands it a DomainClassFilter. The inner class simply creates a new Verification object for each class passed into it and asks if the class is valid. If not, the tests fails and reasons are given why.
It was great to use this test to make sure I had done all of the mappings correctly and had not forgotten anything. The power of reflection compels me!
Friday, December 23, 2005
One of the great ideas to come out out of XP is that of the metaphor (along with Test-Driven Development of course). I'm shocked that is a constant source of controversy in the XP community and largely ignored because of that. I think the problem might be forcing a metaphor when one is not needed.
My viewpoint is that if a metaphor helps communication with developers and business users then by all means DO IT. But, don't force a round peg in a square hole. I generally strive to understand the business of the application being developed and how to satisfy the goals of my users. Use cases and early domain model sketches are great for this. Generally, if there is some difficult area and a metaphor comes to mind that simplifies the problem for both developers and the users, then I use it. I never try to think up of a metaphor if the problem domain is well understood or waste time trying to force one.
The point of a metaphor is to make what's happening in the business crystal clear to developers. Use a metaphor for the murky waters (only if you can come up with one that makes things simple, otherwise you're making things worse and difficult). Remember the point of being agile is delivering value to your customer. Above all else, you are there to make the life of your user easier and help them achieve their goals quickly and profitably. Be pragmatic! If something is not working for you, try another technique else! Everyone has their own ways of learning the business and goals of the user. My favorite is a sketch of the domain on the left (using the language of the user, it's a high level view and only the objects that match the user's mental model) and a mock-up of the screen on the right. The use cases are written in front and we go through each scenario the customer needs. Be creative. I think metaphor is one of those tricks and it's always good to have a big bag and not just one.
Saturday, December 17, 2005
Well, yeah! Especialy since I got a Batman buckle now too! =)
Sunday, December 11, 2005
No matter your craft. Words to live by from Randy Thom:
1. Learn your craft thoroughly, reading everything you can about the traditions and conventions of the craft, as well as experiments on the modern cutting edge.
Mark Derricutt sends a dose of reality to Smalltalkers via his excellent post on IDEs. In it, he writes:
Sure, alot of the time Smalltalk gives you this "everything is live" scenario, the problem I have is when Blaine (and others) say "there's no shutdown, compile, restart, and retry" which goes all the window when you start asking them about deploying an application.
Deployment in Smalltalk is different from everything else. It's more of building down than building up. It just takes some getting used to. Dolphin makes it nice, you just add a category "Must Not Strip" to anything you don't want the automatic stripper to take away. What does the stripper take away? Any class or method not explicitly referenced. The things that get thrown away are methods that are only accessed via "perform" or other forms of reflection. Most Smalltalks allow you to add rules to stop methods from being stripped. It's a gotcha that stings most beginners. But, generally, less than 5% of your code is accessed only through reflection. It's not to say I haven't been bitten by it before. But, I've also been bitten by leaving out a jar in my lib directory at run-time in one of my java applications. It's something you don't forget and make once.
Later on, he talk about intellisense:
DOH! When your autocompletion gives you the wrong information it makes it more than worthless, I hope I don't get people saying 'oh but its because the IDE doesn't know what object you're wanting to complete...' cause that'll be playing right into the arms of pro-static-typing....
Ouch. You got us there. Since, Smalltalk is dynamically typed, it's hard to know what the type is so it just matches on symbols in the system. But, some intellisenses in Smalltalks are smarter. The ECompletion package in Squeak actually uses clues to find ou the type by taking advantage of the fact that a lot of people use the convention of "[a|an]Class" for their arguments. It only gives you the methods for that class if it can figure it out. But, intellisense in statically typed languages is better because they can know the type. It's more precise.
And then, he makes the final wake-up call:
Smalltalk IDEs may have provided all these wonderfull features for the last 20 years or so, but they also seem to have sat stagnant with the thought that they don't need to improve.
This hurts. I believe that Smalltalk IDEs have a lot of room for improvement. Several folks have made efforts to improvement(Whisker, Omnibrowser in Squeak, TrailBlazer in VisualAge for example). There's even efforts to improve the language (Traits). I wouldn't call Smalltalk stagnant and it hurts to see someone have that opinion. I still think with all of the improvements, we could go further. There's several things that I love about Eclipse (like hover over a method and its comment pops up).
I think for many years, Smalltalk was becoming stagnant, but recently, this has been changing. Squeak is undergoing a huge change. VisualWorks doesn't even look like the product from 5 years ago. And Dolphin makes huge leaps and bounds with each release. We need to keep our heads up and see what's going on and incorporate good ideas in Smalltalk and never be satisfied with the current state.
I would like to thank Mark for helping me stay honest....=) I know I tend to talk highly of Smalltalk, but it's because I love it so much. I never want to over-sale it. I'm just trying to be like the "soldiers in the village" and get people excited about what I think is one of the best languages around.
Saturday, December 10, 2005
Civility in blogging is contraversial? I'm a little shocked that someone was scared about giving a talk about this. I know there's things about there like the Bile Blog, but I don't like venomous talk and generally avoid things like it. I know he has a lot of readers and good luck to them. But, if you're going to spew hate into the world, I will not be reading it. You are the problem.
I want to debate topics constructively and not tear people down. I'm not afraid to put my name behind my comments and what I think. I want constructive, healthy debate. I like to think of the arguments of both sides and add my two cents. Mental vomiting and bad language adds nothing to the debate and discourages people to be speak up.
I would think in general people would accept civility and it shouldn't be something contraversial. I wonder if putting your name behind what you say is equally problematic. I hate anonymous posts especially of the putrid kind just because they seem so cowardly. I guess it's no different than the people who ruined newsgroups with their petulant rants and name calling. They have to go somewhere. You would hope that they would grow up and leave their veil of disguise. It's probably asking for too much.
Thursday, December 08, 2005
The tuesday meeting (December 13, 2005) of the Omaha Smalltalk User's Group will include a LIVE demo of Dabble. How cool is that? Come see what everyone is talking about and why Dabble might be the killer application for Smalltalk. Or if you're just curious to see a cool Seaside application (who couldn't do without that?). See you all Tuesday!
Live vs. Dead
Torsten speaks about IDEs and he's right on the money. I generally look at Smalltalk's IDE as playing with a live patient. You are in the middle of a living and breathing system that reacts immediately to you. There's no shutdown, compile, restart, and retry. It's all happening right here and now. It's an incredibly cool experience especially when you realize that you can execute any code and inspect the state of the system. Eclipse on the other hand is like looking at your objects through a window. You can do some manipulation, but you can't mess around with the guts of the patient like you can in Smalltalk. The thing that truly shocks me is why Ruby and Python developers still try to mimic Eclipse (ie. run the code in a different process) in the IDEs available. There's no IDE for them that allows you to be in the middle of a live system. Why wouldn't you want that? I can't wait till Ruby does have a great IDE like Smalltalks. It turns the amp to 12 instead of a mere 11.
Wednesday, December 07, 2005
Humane Interface Debate
I've been following the humane interface debate on James Robertson's blog. I can see both points of view. One side wants the minimal interface because it's easier to maintain the class implementing it. The other side wants a richer interface because it's easier to maintain the class using it. Notice both sides are interested in making it easier to maintain and both have valid points. Is there a compromise to be had?
I like having a minimal set of methods to implement because I make sure duplication and cognitive friction is reduced. But, the users of the class wind up with terse code that's harder to read than with a richer interface. It seems both sides of the argument will always be at odds. This is where I think concepts of object composition from prototype languages can help. "Organizing Programs Without Classes" is worth a study for it shows the way that we can have our cake and eat it too. We have all of the tools at our disposal right now in Ruby's mix-ins, Traits in VW and Squeak, and even in Java with some creative use of proxies and interfaces (yes, it might be slow, but premature opimization is evil right?).
Ruby's Enumerable mix-in is a perfect example of having our humane interface and minimal interface too. All we have to do is implement the minimal methods "each" and "<=>" on a new collection class. It keeps the cognitive friction to a minimum of what the class does and then, we simply mix-in Enumerable and we get "select", "detect", "collect", and just a whole slew of convience methods that makes our client code easier to read.
Traits implements a similiar idea for Smalltalk complete with browser support and it's a joy to use. It's available for both Squeak and VisualWorks. If you're a Smalltalker, you have no excuse not to look at it. I can't say enough good things about it.
I'm still thinking at what a Java option would look like. I'm thinking creative use of aspect-oriented programming or byte code manipulation should make the same thing possible. A poor man's solution could use interfaces, proxies, and the delegation pattern right off the bat.
Java is the real challenge in making code that reads well. In Smalltalk, it's easy because of the message syntax. It's not impossible, but it might be why Smalltalkers favor code that reads like a book rather than minimal interfaces. Anyway, I'm getting off-topic, but I believe there is a compromise in this debate that can satisfy both sides and I think that the resulting code is better for both the implementers and users of the class. We just needed to dig a little into our past of our prototype brothers and adapting some of their concepts for our class-based elders.
And if you haven't tried out mix-ins in Ruby or Traits in Smalltalk, do it now! You'll start thinking of your objects as compromised of behaviors and it allows you to break up your code into more manageable chunks. It also increases the reuse and readability. How much better could it be? Of course, you could play with Self or Io to see what class-less programming looks like. Who couldn't use a new tool or trick in their bag?
Testing To Stop Pain
Unit testing has taken the entire developer world by storm. The xUnit frameworks are simple and easy to use. I always have a test to verify any of my code. I love it. Recently, I've been using the unit testing framework for more than just unit testing. My view on testing has been to simply stop pain.
What does that mean?! It sounds like another meaningless mantra to beat developers with! Heaven forbid! But, I don't mean it that way. Pain to me is anything that detracts me away from my task. Bad design, crufty frameworks, and buggy code are painful. Unit testing is meant to fix the latter, but what about the first two? Could we do something about them? I think so.
The xUnit frameworks are so simple. They're really verification frameworks. If we change our thinking on what we verify, we can create a richer set of tests that go beyond mere broken code insurance. At work, if anything starts feeling problematic, I start thinking how can I fix it and write a test so that it never comes back. It's automating verification of problems. I take this beyond buggy code. I've so far used it to ensure deprecated frameworks are not used on new code and to support code coding habits (like ensuring file handles are closed). I plan on using it to ensure code is deployed correctly, raising flags on poor designs via metrics, and so much more. I'm basically thinking about using testing for prevention as much as verification. The xUnit frameworks are perfect because most of the hardwork has been done to integrate them into every IDE known to developers. A red bar means I need to go look at something. If a developer is sloppy enough to clean up their system resources, I want to know. Besides, a test can also have comments to give possible explanations why it failed. What a perfect training opportunity and no one has to lose any skin off their teeth for it. Think of it as a teacher and a kind enforcer of your teams coding rules. The point should be automating pain away so that once we fix it, it doesn't sneak up on us again.
Thinking beyond unit testing and code correctness is the next step. We have a lot of tools that determine the health of our project. Why not hook those into the unit testing framework as well? I'd rather know up-front if something is going to be a problem before it is. I want to stop the pain as early as possible.
It's time for the Smalltalk User's Group. This week we will be discussing Dabble and showing the video demo. It should be a lot of fun! As always bring your cool pieces of code!
Here's all of the details:
Office is at 103rd & Pacific. Guests can park in the Northern visitors parking area back of building, or across the street at the mall. Enter in front door, we'll greet you at the door at 7:00pm. If you arrive a bit later, just tell the guard at the reception desk you're here for the Smalltalk user meeting in the 1st floor training room.
Monday, December 05, 2005
Circuit Bending Blog
There's now a blog called "Get LoFi" that talks about that is cool is in the DIY synth/circuit bending circles. Very cool. I had a lot of fun reading through the site. I got to get me one of those "Make synths not war" shirts. How cool is that?!
Friday, December 02, 2005
It's time for the Omaha Ruby User's Group. We'll be discussing everything about Ruby. So bring your favorite pieces of Ruby code and your curiousity. Hope to see a lot of people there! Make sure you sign up on the mailing list. Here's the information of the when and where: