Archive for the ‘Software Development’ Category

Interfaces and Implementations

Consider a Java interface and class: Dog and DefaultDog. Which of these two conventions is best?

Option 1 : Dog

Name the interface Dog and call the implementation something like DefaultDog or DogImpl.

Option 2 : IDog

Name the interface IDog and call the implementation Dog, DefaultDog, or whatever else you can come up with.

The Answer

I prefer option 1 for these reasons:

  • A vast majority of your code will utilize the interface, rather than the implementation. Thus, it’s best to keep the interface name clean, and reserve the weird names for the implementation classes, which you hardly ever see.
  • Prefixing names with “I” feels like Hungarian notation. The name redundantly specifies what the interface keyword already specifies. Should we also adopt notations for things that are static, final, abstract, etc? I think not.
  • Many interfaces will have multiple implementations. Thus, each implementation will need a different name. I see no need to also put some name discriminator on the interface.

Regarding names like “Impl” and “Default”, I prefer to avoid those when possible. For example, ArrayList and LinkedList are far better names than DefaultList or ListImpl.

Cedric on Testing

I like how Cedric articulates his approach to testing:

Typically, I code a feature, iterate over it a few times and I reach a point when I’m pretty happy with its shape: it’s looking decent, it gets the job done and while there is obviously more work to be done on it, it’s mature enough that writing tests for it at this point will not be a waste.

Unit Tests are Tests

James Carr writes:

Unit Tests are NOT “tests” in the classical sense… they instead should be used to drive your design, to help you think about how the system you are writing should work, to illustrate functionality.

I disagree with the all caps “NOT”. I think unit tests are primarily for testing, and are particularly valuable for regression testing. I do find that writing tests as I write code influences and usually improves design, but they certainly are “tests”. The fact that tests can drive your design and illustrate functionality are often nice side effects, but they are not the primary reason I write tests.

He goes on to write:

If you ever find yourself running a code coverage tool after writing fresh code, step back and realize that you’re doing it wrong.. my suggestion is if you run a code coverage tool and find parts of your freshly written code aren’t covered, delete that code and try again.

Deleting and rewriting code is a bit too extreme for my taste, but I often do something similar. When fleshing out new work, I’ll often write new classes and interfaces, bounce ideas off coworkers, and rename / refactor heavily. Once I feel like I’ve found the right approach, I will sometimes comment out blocks of code, write a quick unit test (that fails), and then replace the code.

Generic DTOs

Adam Bien presents the Generic DTO convention, where your DTOs wrap around Java Map instances.

If you are considering a generic DTO approach, you might want to investigate Protocol Buffers. Though you will have to create and maintain .proto files, you’ll gain language independence and (presumably) performance.

11 Questions for Jesse Wilson

Jesse Wilson created (the awesome) Glazed Lists and currently works for Google on projects such as Android and Guice. You can follow him on Twitter at @jessewilson.

1. How did you get started with computers?
My mom made me go to a computer graphics daycamp when I was 12. I wanted to just stay home and play lego, but she made me go. I loved it! From there I picked up HTML, then Netscape 2-era JavaScript, and high school CS BASIC. Computer science at university was a natural next step.

2. What is your current job?
Software Engineer. I work with Josh Bloch, Elliott Hughes and Bob Lee maintaining the Dalvik core libraries for Android. We do fun things like rewriting LinkedHashMap, and unfun things like fixing the X509 decoding in HTTPS.

3. What’s next for Glazed Lists, and what is your role in that project these days?
For the most part, Glazed Lists is stable and complete. There’s been some interest in adding support for platforms like GWT, Android, and FX, but nothing is actively under development. I’m currently only a consultant to the project; it’s difficult to stay involved in a project that you aren’t using!

4. Would Java be better off today if Glazed Lists was an “official” part of the JDK, or had a formal JSR?
Being in the JDK has severe disadvantages: an unpredictable release schedule, licensing problems, and a lack of competition. Consider java.util.logging, an absolutely horrible API that we’re all stuck with. Java would be better off if it were easier to adopt and manage third-party libraries. Often I’ll use a bad API that’s built-into the JDK to save the hassle of downloading a good open source alternative.

5. What’s the coolest thing you’ve coded? (like a clever little algorithm, or an application you are really excited about)
I wrote a JMS-like message queue with an awesome API based around interfaces. To define a message, create an interface whose methods all return void. Message-senders simply call the interface, and message-receivers just implement it. Behind the scenes, these messages-as-method-calls are stored in a Bigtable. Everything was managed, fault-tolerant, distributed and fast.

6. What are your thoughts on learning multiple programming languages?
Some developers get really hung up about syntax, which drives interest in languages with pretty “Hello World” examples but few tools and APIs. What gets me excited are the programming languages that go beyond syntax: Clojure has persistent collections; Noop is being designed for testability. But I haven’t used any alternative languages ’cause Java never really lets me down.

7. If you had the chance to work on whatever software project you wanted to for the next year, and money was no object, what kind of problem would you tackle?
Ironically, I’ve got an idea for a programming platform. I’d like to build a programming language with structure rather than syntax. And one that is comprehensive: refactoring, versioning, collaboration, compilation, and deployment would all be an integrated part of the program’s development environment.

8. How is programming different today compared to when you started?
In the 1990’s, all software was bad. It was hard to use, buggy, slow, and dumb. Think about fighting IRQ settings in Windows 95. Today’s software is generally easy-to-use and also easy to maintain. An individual developer has incredible resources at his disposal: APIs that can do almost anything, deployment targets like clouds and devices.

9. Has Java jumped the shark? What’s next, in your opinion?
Java is still a productive language and platform; I haven’t seen anything that improves upon it enough for mainstream users to switch.

10. What is the biggest challenge facing programmers today?
There are many, but a particularly tragic one is security. As we put more personal information into connected systems, they become more appealing targets for criminals. Attacks like the recent Twitter break-in are easy and we’re all vulnerable. Securing applications is very hard, and we don’t have the tools to even measure whether our applications are secure.

11. What are Timbits, and where can I get the best donuts in the world?
Timbits are donut holes from Tim Horton’s, Canada’s ubiquitous community centre and cafe. Their double-chocolate is among the best donuts in the world; available at 3500 stores in the US and Canada.

Thanks, Jesse!

Roy T. Fielding on REST-*

Roy Fielding offers his opinion on the REST-* effort:

Quite frankly, this is the single dumbest attempt at one-sided
“standardization” of anti-REST architecture that I have ever seen.
It even manages to one-up the previous all-time-idiocy of IBM
when they renamed their CORBA toolkit “Web Services” in a
deliberate attempt to confuse customers into thinking they
had something to do with the Web.

Ouch.

Guice with GWT

This article shows how to configure Guice with server side code in Google Web Toolkit (GWT) applications1. I use Guice 2.0 with GWT 1.7.0.

Steps include:

  • Obtain the Guice JAR files
  • Extend GWT’s RemoteServiceServlet
  • Extend Guice’s GuiceServletContextListener
  • Extend Guice’s ServletModule
  • Set all RemoteService relative paths to GWT.rpc
  • Configure GuiceFilter and your context listener in web.xml
  • (optional, but good) Your remote service implementation classes no longer have to extend RemoteServiceServlet

Phew! That seems like a long list, but I want to ensure I list every step. This approach is based on the excellent GuiceRemoteServiceServlet by Pavel Jbanov. His initial work pointed me in the right direction, making this much easier.

Get Guice

Grab guice-2.0.zip from the Guice downloads page. This ZIP contains all of the required JARs. You may also want guice-2.0-src.zip.

To use Guice with GWT, you’ll need two JARs: guice.jar and guice-servlet.jar. Just drop these into your war/WEB-INF/lib directory.

Extend GWT’s RemoteServiceServlet

This code comes almost verbatim from Pevel Jbanov’s blog, with the modifications mentioned in the first comment on that page. Here is the source:

@Singleton
public class GuiceRemoteServiceServlet extends RemoteServiceServlet {
  @Inject
  private Injector injector;

  @Override
  public String processCall(String payload) throws SerializationException {
    try {
      RPCRequest req = RPC.decodeRequest(payload, null, this);

      RemoteService service = getServiceInstance(
            req.getMethod().getDeclaringClass());

      return RPC.invokeAndEncodeResponse(service, req.getMethod(),
        req.getParameters(), req.getSerializationPolicy());
    } catch (IncompatibleRemoteServiceException ex) {
      log("IncompatibleRemoteServiceException in the processCall(String) method.",
          ex);
      return RPC.encodeResponseForFailure(null, ex);
    }
  }

  @SuppressWarnings({"unchecked"})
  private RemoteService getServiceInstance(Class serviceClass) {
    return (RemoteService) injector.getInstance(serviceClass);
  }
}

All GWT RPC requests will go through this single servlet. Thus, your remote service implementation classes will not have to extend RemoteServiceServlet.

  • GuiceFilter will inject the Injector
  • The @Singleton annotation is required for Guice-managed servlets

Extend Guice’s GuiceServletContextListener

This step creates a Guice-friendly servlet context listener.

public class MyGuiceContextListener extends GuiceServletContextListener {
  @Override
  protected Injector getInjector() {
    return Guice.createInjector(
      new MyServletModule(),
      new AnotherOneOfMyModules(), etc...);
  }
}

You can hook up as many Guice modules as you want. The first, MyServletModule, replaces much of what traditionally goes in web.xml.

Extend Guice’s ServletModule

In order to use constructor injection with servlets, Guice must construct your servlet instances. Thus, you no longer list each servlet in web.xml. Here is a simple module:

public class MyServletModule extends ServletModule {
    @Override
    protected void configureServlets() {
        serve("/MyApp/GWT.rpc").with(GuiceRemoteServiceServlet.class);

        // cannot use @ImplementedBy
        bind(MyService.class).to(MyServiceImpl.class);
    }
}

Go check out the Guice ServletModule documentation for a full explanation.

You cannot use @ImplementedBy on the MyService interface. That’s because MyService is in GWT client code, and the MyServiceImpl is in GWT server code. Instead, the binding is configured in MyServletModule as shown.

Remember — this replaces most of what you typically place in web.xml.

Set all RemoteService relative paths to GWT.rpc

All of your GWT remote services will dispatch to the GuiceRemoteServiceServlet shown earlier.

@RemoteServiceRelativePath("GWT.rpc")
public interface MyService extends RemoteService {
    ...
}

Create the web.xml

In old-style GWT, you list your remote service implementations in the GWT module XML file (MyApp.gwt.xml). If you have any servlets listed there, you can remove them. Your GWT module should look something like this:

<module rename-to='MyApp'>
  <inherits name='com.google.gwt.user.User'/>
  etc...

  <entry-point class='com.abc.whatever.client.MyEntryPoint'/>
</module>

Your web.xml should list the Guice filter and your custom Guice context listener.


<web-app>
  <filter>
    <filter-name>guiceFilter</filter-name>
    <filter-class>com.google.inject.servlet.GuiceFilter</filter-class>
  </filter>

  <filter-mapping>
    <filter-name>guiceFilter</filter-name>
    <url-pattern>/*</url-pattern>
  </filter-mapping>

  <listener>
    <listener-class>com.yourcompany.server.MyGuiceContextListener</listener-class>
  </listener>

  <!-- NOTE: List all Servlets in MyServletModule for Guice injection -->

  <welcome-file-list>
    <welcome-file>Css.html</welcome-file>
  </welcome-file-list>
</web-app>

Clean up Remote Service Implementations

Your GWT remote service implementations do not have to extend RemoteServiceServlet any more.

Old code:

public class MyServiceImpl
    extends RemoteServiceServlet implements MyService {
  ...
}

New code:

public class MyServiceImpl implements MyService {

  private final AnInterface anInterface;

  // Guice injection here!
  @Inject
  public MyServiceImpl(AnInterface anInterface) {
    this.anInterface = anInterface;
  }
  ...
}

Summary

Once all of the above pieces are in place, you can use normal Guice dependency injection in all of your GWT remote service implementation classes. This includes both constructor and setter injection.

Please let me know if you find any mistakes, and I’ll be sure to update this article.

1 To use Guice with GWT client code, check out the GIN project. (I have not tried GIN)

Updates

Sep 17, 2009

Changed: RPCRequest req = RPC.decodeRequest(payload);
To this: RPCRequest req = RPC.decodeRequest(payload, null, this);

No More Word

A Texas Judge just decided Microsoft cannot sell Word in the US because it saves data as XML. They are expected to pay $200 million dollars.

That just happened.

  1. Every successful software company will eventually be sued for infringing some patent.
  2. Thus, every successful product “violates a patent”, i.e. builds on ideas from some earlier work.
  3. Since every software product builds on ideas from previous generations (or as lawyers say, violates a patent), no software is patentable.

I believe we should eliminate all software patents. Judges, lawyers, and juries lack the technical expertise to understand why patents like this are so silly.

Update

In addition to being fined $200 million dollars for allegedly violating someone else’s word processing XML patent, Microsoft was recently granted patent 7571169 for…saving Word docs as XML.

Ten Signs You Might be in Trouble

  1. You still use JDK 1.4
  2. When your build master goes on vacation, nobody is allowed to commit or compile (because nobody else knows how)
  3. Compiling on a developer PC requires a Word doc full of instructions filled with manual steps
  4. Your PC is the exact same configuration as the receptionist’s PC
  5. Incompetent programmers get demoted to “QA”
  6. Your code is locked in to a particular IDE and is unbuildable with any other IDE
  7. You have hundreds of TODO comments littered throughout the code
  8. So many tests always fail that nobody pays attention or even bothers to run them any more
  9. The compile + deploy + run cycle takes over an hour for each trivial change
  10. People laugh at you when you suggest GWT might be better than hand-coded Servlets and JSPs

The First 10 Seconds is the Most Important

I really enjoyed 10 Second Code Review.

If you fail to hold code reviews, the crappy code that works its way into your production code base really is riddled with obvious bugs.

A full review definitely takes more than ten seconds, but maybe the first ten seconds are the most important. If you don’t have time for a complete review, at least ask a peer to drop by and give your code a quick look.