Monday, January 10, 2011

My contract to people testing my code.

I promise future QA/Testing staff that I will work with the following: I will have a suggested end to end automation tool that I will verify works against the applications I write. I will not put off till the end of the development cycle time to verify this claim. I will not treat this as a promise, but as a requirement from day one. Just as I will always consider how a user will interact with the application, so too will I consider it a priority that an automated tool must be able to do the same in a verifiable way.

My apologies to all of the QA staff I have ever worked with or near where this has not been the case.

Wednesday, August 25, 2010

Who are you writing code for?

Currently, I have come to realize that I have a flawed methodology for how I write code. My main solace is that it appears to be a flaw shared by many of my peers. This flaw, simply put, is that I try and design all of my code with the belief that somebody else will try and use it in something they do.

The intent here is usually altruistic. I want to share somebody else the burden of having to implement a few ideas that I had in my head. Just as I will do a quick search for how others have accomplished something, so too do I hope that somebody might find what I have done in one of their quick searches.

I will confess this is not always the case. Sometimes, I just want to force others to do something the exact way that I am doing it. In the cases where somebody is trying to add to something I have done, I have little qualm with this thought. (Almost amusingly to my point, the person most likely restricted in how they can add functionality to my code will be myself.)

Of course, despite which of the reasons I am holding as to why I am trying to make something reusable, the reality is that I will be forcing whoever tries to implement my idea to do so in the exact same way that I did. Some of this will be through my own lack of understanding when it comes to API creation. Most will come to down to my simply not seeing how somebody else would want to reuse something.

This inability to see possible uses should be no surprise. The people that actually interact with my code more than anyone else will be the users of the system I am helping to write. While they will never see a line of code I have written, they will be quite familiar with what it accomplished. Worse, for me, is that they will likely have envisioned something subtly different than I did when they want to use the application.

It is a common enough event to have to take some customer feedback into consideration when building something for them. How could I possibly think I could design some code for other developers, with limited feedback from them?

Who then should I write for? It makes little sense to write the code simply for the end user. After all, they simply see what it does, not how it does it. They are far from concerned over whether or not I used enough patterns when I implemented their system. They probably don't even know the different languages and styles I have to choose from. Why should they?

I am tempted to say that code should be written strictly for myself. I am reading it more than anybody else. I am the one writing tests for it. I am likely the one that will have to track down bugs in it. So, if I wish to try and write everything using a declarative style because that is easier for me to understand the intent when I look at it later, then I think it makes sense to continue to use a declarative style.

I realize that many work in a team, however, so for you I have no real answers. I still believe that you yourself are the most likely person to revisit code that you wrote. Do it in a way that you feel is understandable, but get it done. Don't fret over how someone else will use it later. When the time comes, they will find a way to do so.

Monday, August 9, 2010

How I Understand Generics.

I have come to realize that my understanding of generics is likely more limiting than I'd care to admit. No better way to address this concern than to try and lay it out.

To start, I must fall back to what I understand of types in Java. Before generics, to define a new type was to define a new class. So, if you had a class:



public class List {
public Object get(int index) {...}
public void add(Object o) {...}
}


Then you have declared a type that is very understandable (helped by virtue of being familiar). Now, generics often start by showing casting happening at the use site of this class. However, I feel it is more revealing to think of another type that is similar to the above definition. Consider:



public class StringList {
public String get(int index) {...}
public void add(String o) {...}
}


Now, this is a new type. Further, it is completely unrelated to the previous type, except for the fact that it looks an awful lot like it.

Now, most people will start with the other types that happen to be named in these and try to build a relationship from that. Such that because people see that String extends Object, so StringList must extend ObjectList. But remember, we aren't talking about the types String and Object, we are looking at StringList and plain List. As defined here, this can not happen. Were one to try this, you would find that, were you to drop the set method, suddenly you could make these types related. As such:


public class List {
public Object get(int index) {...}
}

public class StringList extends List {
public String get(int index) {...}
}


Similarly, were one to drop the get methods, the relationship could actually be written the other way, such that List would actually extend StringList:



public class StringList {
public void add(String o) {...}
}

public class List extends StringList {
public void add(Object o) {...}
}


(It occurred to me this morning that I should say that Java doesn't support contravariant method parameters. So... The above compiles, but only because List is defining a new add method. :) )

Using this code, you would see that nothing that is invalid to the type system would have happened, as you simply added a String to a List. Which, since List has an add method that takes an Object, and a String is an Object, we are all clear.


StringList foo = new List()
foo.add("hello");




But, what all does this have to do with generics in Java? Well, as I said at the beginning, until generics, one had to write a new class file to define a new type. With generics, one can simply describe types. Specifically, you can now define all types that share a common description. For us, this description is simply:



public class List<O> {
public void add(O o) {...}
public O get(int index) {...}
}



So, why did I go through the trouble of exploring relationships of these possible types. Well, remember in Java when you describe all possible types that share a common description, you are describing completely unrelated types (in the typically inheritance based view of relationships). This is what is referred to when it is said that generics are invariant. List<String> describes a type akin to StringList, and List<Object> describes plain old List. And, just as StringList is not a related type to List, nor is List<String> related to List<Object>.

But what if we wanted that relationship ability? That is where wildcard captures come into play. Specifically, the first relationship type can be described with the following snippet. Notice the lines that don't compile are the ones that we could not have been able to code were we writing the class file ourselves:


List<? extends Object> foo = new List<String>();
foo = new List<Integer>();
foo = new List<Double>();
Object o = foo.get(0);
foo.add(new Object()); //Fails.


Similarly, the second relationship could be encoded with the wildcard below:



List<? super String> foo = new List<String>();
foo = new List<CharSequence>();
foo = new List<Object>();
foo.add("hello");
String o = foo.get(0); //Fails



That is all well and good, but what if we wanted to describe not just all similarly described types, but also all of their subtypes as well? Since we can identify in the code what restrictions are required to say that StringList extends String (and, conversely List extends StringList), could we not write a class such that we declared the generic to account for this and have the compiler let us know if we write a method that would be incompatible with what we declared as our intention?

Unfortunately, this is not possible in Java. And it is a direct consequence of the final point on generics that one will hear about in java, that it has use site variance declarations. You can not write a class that describes all possible subtypes of the types it describes, but one can write a variable that defines an inheritance chain. And, in so doing, the compiler will remove methods that would not be possible in the inheritance chain that you declared.

Friday, June 18, 2010

The Power of Declarative Code

The best policy is to declare victory and leave.
—George D. Aiken




While learning to write some basic UI using GWT, it is hard not to be aware of the work they are doing with UiBinder. At a very high level, they have introduced XML templates for a declarative syntax to build an interface. The basic example from the main page is:


<!-- HelloWorld.ui.xml -->

<ui:UiBinder xmlns:ui='urn:ui:com.google.gwt.uibinder'>
<div>
Hello, <span ui:field='nameSpan'/>.
</div>
</ui:UiBinder>


From their example, they hook this up to a sample piece of Java code as:


public class HelloWorld extends UIObject { // Could extend Widget instead
interface MyUiBinder extends UiBinder<DivElement, HelloWorld> {}
private static MyUiBinder uiBinder = GWT.create(MyUiBinder.class);

@UiField SpanElement nameSpan;

public HelloWorld() {
// createAndBindUi initializes this.nameSpan
setElement(uiBinder.createAndBindUi(this));
}

public void setName(String name) { nameSpan.setInnerText(name); }
}



It is not hard to see the advantage of this. Especially in a shop where you have designers who provide prototypes or templates in an XML format.

However, for those of us that are on the hook for everything individually, I contend that the annotation and XML approach are actually less appealing than an approach that can encode everything in one file. To that end, I have started using some helper methods to try and capture the essence of what UiBinder can accomplish for you.

My first target is what I consider to be the most appealing part of UiBinder, the declarative nature of the code. I am of the opinion that it would be incredibly dreadful if one had to drop to XML in order to get declarative code. Luckily, this is not the case. It is relatively easy to generate the above hello world example in a single file that shows the structure just as well:


public class HelloWorld extends UIObject {

SpanElement nameSpan = span();

public HelloWorld() {
getElement().appendChild(
div(
text("Hello, "), nameSpan, text(".")
)
);
}

public void setName(String name) { nameSpan.setInnerText(name); }
}


The above code can be added to a document in the same manner that the original example could. While not an extreme example, this still shows that two files, one at about 13 lines of code and one with 7, can be combined to a single 14 line snippet. And this ignores all of the setup one has to do to have UiBinder actually compile and run the code.

Of course, this wouldn't be that appealing if it did not work with Widgets. To that end, another set of helper classes and methods can give us:


public class PanelExample extends Composite {

WidgetConfig<Label> topLabel = label("").addStyle("title");

public PanelExample() {
this.initWidget(
dockPanel(
north(topLabel),
center(label("Body")),
west(
html(
orderedList(
item(text("Sidebar")),
item(text("Sidebar")),
item(text("Sidebar"))
)
)
)
)
);
}

public void setTopLabel(String text) {
topLabel.get().setText(text);
}
}


Essentially, just by taking advantage of some chained method calls (with a judicious use of varargs) and a simple wrapper object, we can create a section of Java code that has the same declarative qualities of XML, without having to resort to XML. (We also save ourselves the joy of seeing new sprinkled throughout our code.)

Further, we can take advantage of other private methods to help make other sections more readable. Consider, the above example could be recoded to look like:


public class PanelExample extends Composite {

WidgetConfig<Label> topLabel = label("").addStyle("title");

public PanelExample() {
this.initWidget(
dockPanel(
north(topLabel),
center(mainBody()),
west(sideBar())
)
);
}

private WidgetConfig<?> mainBody() {
return label("Body");
}

private WidgetConfig<?> sideBar() {
return html(
orderedList(
item(text("Sidebar")),
item(text("Sidebar")),
item(text("Sidebar"))
)
);
}

public void setTopLabel(String text) {
topLabel.get().setText(text);
}
}



This is definitely doable with tools such as UiBinder, but extracting out inner templates simply by using familiar IDE tools for refactoring is hard to scoff at.

There are, of course, several other good reasons to use UiBinder. The first is the way it treats styles. The second is the way in which it eliminates a lot of the code to attach listener objects to the view. I am currently working on some code to address each of these issues. I welcome any feedback. In particular, if I am incredibly misguided in these efforts, it is usually best to find out sooner, rather than later. :)

Tuesday, November 3, 2009

Wave and Email, Collaboration versus Correspondence.

While I have been looking over many of the Waves that I can find in public searches, I have been wondering what is the main point of Wave. According to Google, the idea was simply to answer the question: "What would email look like if we set out to invent it today?"

Like I assume many have, I started using it just as the basic interface allows you. Essentially, you get many "blips", one after the other responding to the "blip" immediately above it. It winds up resembling a chat room, where you just happen to be able to edit any existing message.

If you use it as some of the examples indicate, the idea is not that you respond directly to a full blip, but you instead inline responses to individual parts of a blip. The main use case being collaborating on a series of questions or ideas. This would mean that if you had several points in your original email, a respondent could place the responses directly where those points were.

This seems to imply that email is strictly a collaboration tool, when many people use it more for correspondence than they do for collaboration. In fact, I would go so far as to say that it is a major complication to approach Wave like you would an email or a chat. Both of those are just correspondence tools. While it is true that correspondence can be used to collaborate, the best Waves will be like the best collaborations in the real world, where people are actively doing something as well as just communicating. It is only once we learn how to start editing each others contributions that the real value of Wave will be seen.

Wave does not make an ideal correspondence solution right now, maybe it never will. It does look like it will one day make a wonderful collaboration tool, though.