Wednesday, December 30, 2009

REST-style URLs for older Java web applications using UrlRewriteFilter

Say you have an old old Java Web application that uses URLs like this:


You want your URLs to be pretty and more RESTful like so:


Well, you have two options. You can re-write your web application to use newer web frameworks that supports REST-style URLs such as Spring MVC 3.0, which will probably take months to do. Or you can use UrlRewriteFilter which should take no more than 30 minutes and will work with any existing Java web application.

UrlRewriteFilter very easy to use. You basically:
  1. Add UrlRewriteFilter as a servlet filter in your WEB-INF/web.xml
  2. Populate WEB-INF/urlrewrite.xml with mappings of REST-style URLs to the corresponding URLs of your legacy web application (with query params and what not).
 That's pretty much it.

UrlRewriteFilter is extremely powerful. It supports regular expression pattern matching, allowing you to perform pretty complex mapping. Check out the manual page for details.

Monday, December 14, 2009

Remove ifs/switches from your JSPs through feature labeling

In this post, I outline a technique I call "feature labeling" as a means of organizing your web application's HTML views into features that can be selectively enabled and disabled without unmaintainable if/switch statements. I will use JSP and Spring in my example though this technique can be generalized to any view technology that allows for custom tags and any dependency injection container.

Say we are writing a prototypical blogging web application. All blogging applications give authors the ability to edit a blog entry. One straightforward way to implement this is to check if logged user is the author of the blog and then displaying the edit link to the user like so:

<c:if test="${user ==}">
  <a href="/blog/233/edit">Edit Blog</a>
Months later, say we decide that the administrator should also have the ability to edit blogs. We can add an 'or' condition to the if statement like so:
<c:if test="${user == || user.role == 'admin'}">
  <a href="/blog/233/edit">Edit Blog</a>
The good developer, however, should see that we are going down the path of littering our JSP/HTML view with too much logic, which will ultimately become harder to test and less maintainable. The "right thing" to do is to push this logic to a middle tier.

First, remove the if logic and replace it with the custom JSP tag "dm:feature" (to be created) like so:
<dm:feature name="blogEditing">
  <a href="/blog/233/edit">Edit Blog</a>
Note the attribute name="blogEditing" which will effectively label the inside body as the blogEditing feature.

Second, create a custom JSP tag that will:
  1. Get a FeatureService object from your Spring web application context.
  2. Do a featureService.isEnabled(featureName) to determine whether the body should be evaluated or skipped.
Here is a tutorial that covers the topic of creating custom JSP tag. Hint: Extend TagSupport instead of creating it from scratch. Then to get the Spring web application context, do:
context = (ApplicationContext)pageContext.getAttribute(

Third, create your FeatureService interface and implementation. In this example, the implementation would need to be aware of the current user and the current blog so you can do the check "if current user is the blog author." Leave a comment if you want more details.

This should dramatically reduce unnecessary logic in your view and make it more testable because you are pushing the logic into a middle-tier.

Keep in mind that this only eliminates blog editing from the view. You still need to disable the controllers/services for blog editing as well. This is where Spring's Aspect Oriented Programming comes in. Here's a brief outline of what you need to do:
  1. Create an @Feature annotation that requires feature name (e.g., @Feature("blogEditing"). This annotation will basically label methods as being part of a feature.
  2. Create a FeatureAspect bean with FeatureService as a dependency.
  3. Create an around advice (method in the FeatureAspect bean annotated with @Around). This advice should check if the feature specified in the @Feature is enabled. If enabled, execute the method. Otherwise, throw a runtime FeatureNotEnabledException and add top-level handlers to redirect user to a 403 unauthorized page.
Note that the FeatureAspect uses the same logic (i.e., FeatureService) that is responsible for determining whether a feature should be enabled. There's no need to duplicate logic both in the view and middle tier.

Helpful? Let me know.

Wednesday, December 9, 2009

Usability findings: You look where they look -- False!

I came across this article on 10 Useful Usability Findings and Guidelines. Points listed are not too surprising. However, I disagree with #2. Essentially, the author is concluding that you can increase people's attention if you have a picture with a face looking at the target text. I think the "study" lacks the proper control to warrant such conclusion.

It could be that a frontward face draws attention away from the text. In other words, the frontward face has a negative affect on attention as opposed to directional face having a positive affect. A simple control stimulus with a face looking in the opposite direction of the text would have revealed whether a directional face actually increases attention. There should have also been a control stimulus of no face or a non-face image to establish a baseline.

The author is also concluding that glances directly translates into attention. The peer-reviewed eye tracking literature have shown that while this is generally true, there are many levels of attention that must be considered. The level of attention desired by content providers is one where the user is reading and comprehending the text, in other words, a high level of attentional processing. It could be the case that a significant number of the glances are accidental or reflexive glances as a result of being steered by the directional face. One way to tease out these accidental glances is to subtract the data from the first few glances across all the images. The glances remaining would be the more intentional ones, the ones that reflect higher level processing.

This is a demonstration of the lack of rigor in non-peer reviewed studies.

Saturday, November 21, 2009

Flashing BIOS in Ubuntu Linux without floppy

I was trying to update the flash BIOS of an old ECS K7SOM+, a 1 Ghz-era AMD Athlon motherboard. The problem is that most older motherboard flash upgrades are designed with a DOS bootable floppy in mind. I have no DOS, no Windows, no floppy drive, and no floppy disks. Fortunately, there's UNetbootin, a tool design specifically to make bootable USB flash drives from Linux. Here are the general instructions for Ubuntu Linux users:
  1. Use gparted to create a single FAT16 formatted partition on the flash drive.
    • You can install gparted using apt-get install gparted
    • You may need to first umount the USB flash drive before you can partition and format it.
    1. Use unetbootin to install a bootable FreeDOS onto the flash drive.
      • Install unetbootin using apt-get install unetbootin or read WestCoastSuccess' comment.
      • Run unetbootin and:
        • Select the distribution FreeDOS.
        • Select your USB flash drive
        • Click OK. This will download FreeDOS to create a DOS bootable flash drive.
    2. Copy your motherboard's BIOS update and flashing utility files into the root of flash drive. These files will be located in B: or C: drive when you boot into FreeDOS.
    That's it. Boot off your flash drive -- you may need to configure your CMOS setup to do so.

    Update 2010/01/02: Updated instruction as per WestCoastSuccess.

    Monday, November 16, 2009

    Maven database migration plugin

    I finally got around to testing c5-db-migration -- a database migration plugin for Maven. Essentially, it's tool for managing your database changes. The plugin is very straightforward to use:
    1. Copy and paste the plugin configuration to your pom.xml.
    2. Add a couple of SQL scripts into your src/main/db/migrations in the format of yyyyMMddHHmmss_some_description.sql
    3. And run mvn db-migration:migrate to run the SQL scripts against your database.
    The plugin tracks your migration in a table called schema_version. It's not as comprehensive as Rail's database migration tool (e.g., it doesn't support downward migrations). Nevertheless, it's simple and unobtrusive.

    If you're managing database changes manually through collections of SQL scripts, there's no reason why you shouldn't give this plugin a try.

    Wednesday, November 11, 2009

    SpringSource tc Server Developers Edition

    At the risk of becoming a SpringSource shrill, check out the video on Spring's Tomcat server for developers.

    It's basically a modified version of Tomcat that makes it very easy to profile web applications. It's free but NOT open source.

    Monday, October 19, 2009

    Saros Pair Programming Plugin for Eclipse

    Saros is a pretty impressive open source plugin for Eclipse that allows collaborative editing (i.e., pair programming). It requires only a Jabber server. Check out this 11 minute video of Saros.

    Saturday, October 17, 2009

    Java Beans without getters/setters using lombok

    Project Lombok is probably going to be one of the most useful library for Java. The library (requires Java 1.6) provides annotations that generate getters, setters, toString, hashCode, & equals for your POJOs. For example:
    @Data // Lombok annotation
    public class Person {
    private String firstName;
    private String lastName;

    // Now your class has all the getters, setters,
    // equals(), hashCode(), and toString()
    C#/.NET has had this syntactic sugar built into the language for years but I was ambivalent about the approach. I'm more of a fan of languages with sparse syntax set such as C but the downside is that you end up writing much more boilerplate code. I think Lombok's approach is a nice compromise between bloated language feature set and having verbose code because of sparse language feature set. And it's supposedly supported in Eclipse.

    Tuesday, October 6, 2009

    Integration testing with Spring

    Watch this Rod Johnson talk if you're not already familiar with rolling back transaction as a means of performing integration tests:

    You can probably skip to the 30 minute mark if you're already familiar with the reasons for testing.

    Sunday, September 27, 2009

    Languages for JVM

    The Java language is mature and that in the software development world means that it's dying. The Java language was designed around object-oriented programming but the trend now is moving towards more functional programming (which is arguably better suited in concurrent environments). I've been looking at newer languages built on top of JVM: Groovy, Scala, and Clojure.

    Groovy is basically a dynamic version of the Java language with some new language features such as closures (a feature in functional programming). In essence, Groovy is "Java scripted" inspired from Python and Ruby.

    Scala is an object oriented language with functional language features. It is not a scripting language and has features such as type inference:

    var t = new Tiger();

    The compiler knows that t is a Tiger -- no need to do:

    Tiger t = new Tiger();

    This type information is available at compile-time which allows for compile-time optimizations, making Scala on par with native Java performance.

    Clojure essentially Lisp-inspired language running on the JVM.

    All the above languages do not differ much with their Java interop (i.e., you can pretty much call existing Java code directly). All reduces the verbosity of Java. If I had to learn one language, I would pick Scala. I think Groovy is too small of an evolution over Java (i.e., not much benefits). Clojure just seems to radical for object-oriented developers.

    Here's some additional points in no particular order:

    - Martin Odersky, father of Groovy, said "I can honestly say if someone had shown me the Programming Scala book by by Martin Odersky, Lex Spoon & Bill Venners back in 2003 I'd probably have never created Groovy."

    - Scala is available both JVM and .NET.

    Wednesday, September 16, 2009

    Integration test hell

    For those of you spending lots of time fixing up integration tests, J.B. Rainsberger explains why he thinks integration tests are a scam:

    I think the point he is driving home is that we should be focusing more on comprehensive unit tests rather than comprehensive integration tests. I've started changing how I write my integration tests: They should only be verifying the interactivity of components, rather the expected results of the component.

    Let's say that a User Service class (UserService) that calls a User Data Access Object class (UserDAO). The unit tests for UserService should use a mock of UserDao and asserting exact equality with the data and exceptions returned from UserDao properly (-- nothing new here). Your integration tests for UserService should use a real UserDao that is connected database (-- again, nothing new here). However, these types of test should NOT be asserting data and exceptions equality. Rather, these integration tests should just be verifying that some data/exceptions are returned. Integration tests should be testing the seams between the UserService and UserDao components, rather than asserting the equality of the value themselves.

    Overally, I recommend watching this talk if you have done lots of unit and integration tests writing and wondering if you are duplicating effort.

    Monday, August 31, 2009

    Review: The Cathedral & The Bazaar

    I finished reading Eric S. Raymond's The Cathedral & The Bazaar (catb). Just a couple of points I want to metion:

    - Raymond makes a critical distinction between sale versus use value. I think this is the seminal point in the book. Closed source software that derives most of its value from sales price. Providing technical support eats away at the sale value so it's fundamentally in the interest of closed source companies to limit technical support for at given sale price. In other words, the ideal situation for closed source software companies is for people buy their software and never use it. In contrast, open source derives most of its value from use. The business model of open source companies is centered around support. The more people use the software, the more support resources that will be consumed which benefits these companies that center around support.

    - Raymond is not as hardcore open source advocate as I assumed. He does acknowledges places where open source would not be suitable.

    - Open source excels in domains where software is a commodity, e.g., infrastructure such as operating system, middle ware space, browsers.

    - Open source development is analogous to academic peer review. I would what would Raymond say about more artistic work?

    Raymond's writing style is like that of a hacker: It may not be pretty at times but he gets his point through. There's plenty of self-citation which hurts the credibility of some of his arguments. Overall, I'd recommend reading catb primarily as a historical reference. Those of you aware of the open source revolution probably will not benefit much from it. I think it is a must read if you want to start a business centered around open source.

    Saturday, August 1, 2009

    Lean start-ups

    Here's a thoughtful webcast talk about 'lean start-ups':

    Lean start-up is not limited to your traditional start-up company. Rather, it can also refer to a small department in a large company. Essentially, the speaker, Ries, believes that an effective lean start-up can be boiled down to rapid releases. Ries suggests a couple of techniques to get to rapid releases. One of the more radical technique is continuous deployment where source check-ins that pass integration tests are deployed automatically. Of course, there would need to be a mechanism in place to revert back quickly. Ries also describes split testing where new features are tested in parallel with existing code, essentially a control and experimental group comparison. Ries also recommends asking the 5-why's on every issue (e.g., asking why did this bug occur 5 times at different level from the programming level to the management level).

    This talk is worth the hour if you are interested in improving your development process.

    Friday, July 24, 2009

    Java Templating APIs

    Many web view technologies are very difficult to unit test. This includes JSP/JSTL, PHP views, Rails views, and probably ASP.NET views. The problem is the lack of the ability to set an arbitrary model to a view and doing a string assertion on the view. (Correct me of I'm wrong.)

    I did a bit of research on templating engines for Java. Here they are:

    Freemarker - Not specific to the web, unit testable without servlet container, replacement of JSP. Last update in December 2008.

    Velocity - Greater community than Freemarker (according to Freemarker themselves). Also not web specific and a replacement for JSP. Last update in May 2009.

    String Template
    - Very minimalistic approach to templating with ports to Python and C#. Also not specific to the web. Last update June 2008.

    All of these technologies basically solve the problem of making the view accessible without a servlet container. This makes it easier to pass the responsibility of HTML/CSS design and JavaScript coding off to other developers. Spring supports Velocity and Freemarker though it shouldn't be too difficult to write an adapter for String Template. Right now, I'm leaning towards Velocity because of the better community support.

    In addition to templating engines, I also looked at page composition frameworks:

    Tiles - Originally part of Struts. Employs the composite pattern where each page explicitly define header, footers, and etc. to include. Support for Freemarker and Velocity templates. Last release in February 2009.

    SiteMesh - Alternative to Tiles. Employs the decorator pattern where pages are not aware of the header and footer. Can work with other web technologies (CGI, PHP, and etc.) -- this is COOL. Last update in March 2009.

    I am really excited about using SiteMesh. Here's a SiteMesh tutorial.

    Sunday, July 19, 2009

    Database anti-patterns that all developers should know

    Josh Berkus, one of the core developers of PostgreSQL, gives a tongue-in-check talk on 10 ways to wreck your database.

    The talk is about 40 minutes long -- a decent enough talk. However, the Q&A portion that followed the talk is stellar. Unfortunately, you can't really just skip to the Q&A portion and you definitely don't want to stop watching after the talk because you would get the wrong impression.

    The most important point for me was that I need to start using natural keys in my database and normalized through natural keys rather than primary keys.

    Tuesday, July 14, 2009

    Why and how of test first development

    Test-first development is the process of writing your test code before your implementation code. I have always felt this was the ideal approach but NOT necessarily the pragmatic approach to development. The thought of writing a full test before writing the code was essentially writing the specifications first and feels almost like a micro-waterfall approach to development.

    I attended a couple of talks recently that made me realize that test-first is not necessarily about writing the entire test case before the implementation. Rather, you can take a very iterative approach. The idea is that you write just enough of the test code to get your implementation code to fail followed by just enough implementation code to get it to pass. Then you write just enough test code to get your implementation code to fail again and repeat the process until your test and implementation code is complete.

    To be more specific, the first line of test code could simply be calling a method that does not exist in your implementation. This will cause a compile error (for those of us on stronger typed languages). Then you write just enough code to get the compile error to go away. Some of you may be thinking that compiling is not unit testing which is true but it is a form of testing nevertheless.

    The second line of test code could simply be an assertion that the returned object is not null. This should result in a test failure. To pass this test, you can simply return a dummy object. Now obviously your implementation code should not be returning dummy objects. So, the third line of test code could compared the return value with an expected value which should cause the test to fail since it was initially returning a dummy value. Then at this point you would modify the implementation method to return the appropriate value dummy object.

    Note that this approach breaks up your test into finer grain assertions. Had you write the test first, you would probably have never thought about performing an assertNull which would aid in debugging. In more complex methods, there would probably be many forgotten assertions. This finer grain approach also makes the test easier to write since we are taking a small bite at a time.

    I have been using this approach for the last few months and this has actually become my preferred means of development. In fact, I now get that dirty feeling when I write tests after implementation, much in the same way a test-infected person feels dirty pushing code without unit tests.

    Saturday, July 11, 2009

    Rolling your own security authentication/authorization?

    Before you do, watch this 50 minute video on Spring Security:

    Make sure your implementation of security rolling matches the ease of implementation and features of Spring Security. If not, use Spring Security.

    Saturday, July 4, 2009

    Database Connection Pooling: c3p0 versus dbcp

    I was looking at database connection pooling the other day and was trying to decide between c3p0 and Apache Common's dbcp. Both are open source (of course) and implement the standard DataSource interface, which means that you can pretty much swap out one for the other without breaking functionality. Both are not very up-to-date with their last stable releases being over two years ago: The last stable release of dbcp (1.2.2) was 2007-04-04 while for c3p0 ( was 2007-5-21. The consensus appears to say that dbcp is better for single threaded applications while c3p0 is better on multi-threaded applications (which would include your webapp). Based on this alone, I favor c3p0.

    Spring Forum posting
    Javatech comparison of c3p0 versus dbcp
    Stack Overflow discussion

    Wednesday, July 1, 2009

    Spring versus Hibernate Validator

    I looked at both Hibernate and Spring Validation briefly today.

    Hibernate is annotation-based and works something like this: (1) You annotate with the proper validation rule (e.g., @NotNull) on the fields of your bean; (2) You call Hibernate's ClassValidator to validate, which returns the validation errors. Presumably, it inspects the annotations on the bean fields and performs the appropriate validation.

    Pros: Easy declaration based validation.
    Cons: I haven't figure out a way to perform database check for uniqueness.

    Spring's validation is programatically-based. You implement the Validator interface which contains two methods, one of which is the validate method. You perform your validation manually, either writing the rules yourself or using Spring's utility methods, e.g., ValidationUtils.rejectIfEmpty(...)

    Pros: Very flexible which allows for database record-based validation
    Cons: More complex than Hibernate's Validator.

    Neither solution is particularly ideal. Hibernate seems too simplistic while Spring's requires too much programming. I lean towards Spring's Validator mainly because it's very apparent as to how one would perform database record validation.

    Tutorial: Getting Started with Hibernate Validator
    [Chapter] 6.2 Validation using Spring's Validator interface

    Saturday, June 20, 2009

    Groovy over Java

    Dynamic languages, once relegated to hobbyist and small mom-pop development shops, now (as in the last 2-3 years) seem to be the latest fad in "enterprise" development shops. I think this was largely due to the success of Ruby on Rails and Python which showed that you can write maintainable large scale software using dynamic languages.

    Groovy appears to be the Java community's answer to dynamic languages. Groovy is a superset of Java which means that your existing Java code should mostly work in a Groovy interpreter. Groovy provides many of the syntactic sugar that you see in dynamic languages such as key-value dictionaries (hash tables), named parameters, closure, and etc.. Groovy has been submitted to Java Community Process program for standardization.

    I'm still a bit mixed about using dynamic languages because I like the security of compile-time type checking. However, I do see myself using Groovy to write my unit tests since the syntactic sugar can potentially make my unit tests easier and faster to write.

    Tuesday, June 9, 2009

    Spring MVC

    Here is a nice link describing the features of Spring MVC:

    The information may be outdated with Spring 3.0 just around the corner.

    One of things I like about the Spring Framework in general is that it's not very intrusive. Depending on your requirements, you can use the Spring Framework without: extending any class, implementing any interface; nor writing any adapter classes. This makes the framework extremely flexible because you are not locked into their application programming interface (API). If you're reading this blog, then you probably know that using open source frameworks is a way to avoid vendor lock-in. However, using open source alone is not enough to prevent vendor lock-in. We also have to think about API lock-in. The more your framework requires implementing/extending framework specific interfaces/classes, the more at-risk you are to API lock-in.

    The Spring Framework also has a la carte style approach of integration into your existing software components. You use what you need and can add the incrementally framework as you evolve as a developer. In my current project, I started off using Spring's mock (stub) objects for testing (instead of writing my own MockHttpServletRequest). Then I used Spring's Object/XML Mapping (OXM) framework to domain convert objects to XML and vice versa. Now I'm looking to use Spring's MVC framework and eventually move all my object configuration and construction using Spring's core bean container.

    Friday, June 5, 2009

    Failed Searches

    I'm lazy. Very lazy. I don't like keyword searches that do not return what I want on the first page. I don't like it because I have to make extra mouse clicks to find what I want. And I don't like extra mouse clicks because I'm lazy.

    I'm sure I'm not alone. As obvious as this may seem, many commerce websites don't get it. They develop interfaces that make me perform unnecessary mouse clicks. They make me turn pages. If I have to turn to the next page of a results set, then your search has failed. Your search should have return the relevant results on the first page. Many sites also make me sort my search results. If I have to waste mouse clicks to sort my results, then your search has failed. Your search should have returned in the order of most relevant results. Some sites have even gone as far as making me filter my results set. If I have to filter the results set, then your search has failed. Your search should have returned only filtered results.

    This all may seem a bit harsh. The point, however, is not to set unrealistically high criteria of what constitutes a good search engine. Rather, I'm suggesting that as developers we need to value mouse clicks. Every mouse click is precious and should not be wasted on paging, sorting, and filtering -- none of which would be needed if the search was done right in the first place. In the end, paging, sorting, and filtering are all crutches for broken searches.

    Sunday, May 24, 2009

    Review: Java FTP Servers

    I needed an FTP server to perform functional testing of some FTP client Java code (commons vfs). The top 5 Google results for "Java FTP Server" were:

    Apache MINA FtpServer - Runs as standalone or embedded; free and open source (Apache License)

    FtpGoServer - Runs as standalone; source can be purchased

    jftpd - Runs as standalone; appears outdated (last release in 2001); incomplete implementation

    Java Secure FTP Server - Runs as standalone; free and open source (GPL)

    Colorado FTP - Runs as standalone; free and open source (LGPL)

    My pick is Apache Mina FtpServer. It's an active project. It can be easily embedded into any functional test -- the alternatives require peering into the source, writing adapter classes, etc.. It's also the only one that shows significant activity in Google Trends.

    UPDATE 5/26/09: Documentation of Apache Mina is pretty thin (as with the other FTP packages).

    Reduce IDE clutter with Mylyn

    One of the problems with working on a large project in Eclipse (or in any IDE) is navigating through various project resources (e.g., classes, methods, and etc..). Mylyn, a Eclipse feature, attempts to solve this problem by providing a focused view that shows only the relevant resources for a given task:

    Skip the first 4 section because the speaker blathers on and on about various impediments to a software developer's productivity. Begin at section 5 and watch until you get bored (~30 minutes).

    Key features of Mylyn include:
    • Integrated view with ticket issue tracker software such as Bugzilla, Trac, and JIRA. Issues assigned to you are downloaded into the Eclipse project so that they can be viewed offline without the delay of launching a browser and waiting for a page load.
    • As you work on an issue, Mylyn tracks your visits to classes, methods, and resources to create a task context. You can upload the task context to share with other developers who would be able to view the classes, methods, and resources relevant to the ticket issue.
    • Bug numbers inlined in code comments can be clicked to bring the ticket issue into view.
    In other words, Mylyn integrates Eclipse with your issue tracker so that only the relevant project resources are visible at any given time.

    Sunday, May 17, 2009

    JavaScript is elegant

    I used to think that jQuery made JavaScript elegant. I was wrong. JQuery just helped me understand what is already a quite elegant language. Watch this entertaining 1 hour Google Tech Talk by Douglas Crockford, author of JSLint, JS Min, and several essays on JavaScript misconceptions.

    Among the things he discusses are:
    • The origins of JavaScript and the design flaws
    • General constructs to avoid in JavaScript
    • How closures are used to create objects
    • Benefits of using as a functional language
    • Uses of the triple equality (===) operator
    Probably his best statement about JavaScript is that most of us know how to use JavaScript without taking the time to understand it.

    If you've done or will do any work in JavaScript, please take the full one hour to watch this talk. It's worth it.

    Saturday, May 16, 2009

    Inspirational talk

    Damien Katz talks about the path that led him to develop CouchDB, an open source document oriented database. It's not very technical and it's inspirational in an ordinary down-to-earth way.

    Thursday, May 14, 2009

    Clean code talks

    Below are four fantastic talks (~30 min each + Q&A) on clean code and unit testing. I wish I came across them a few years ago when I was first starting out unit testing -- would have saved me so much pain.

    If you're a developer with a few years down your belt, you should know why:
    • if statements are bad
    • new statements are generally bad
    • singletons are an anti-pattern
    • service locators were the pre-cursor to dependency injection
    If not, watch the talks and you will feel much smarter!