posted on August 25th, 2010 ·

posted on August 10th, 2010 ·

Like most other developers, when I first came across the Flex data-binding, I thought of it as an interesting feature, but haven’t realized the true implications of it until much later. Data-binding in Flex has revolutionized the way I think about building UIs.

To understand why data-binding is so revolutionary, let’s look at standard Model-View-Controller setup for building UIs.

Let’s start off with a model. A model is simply an object which has properties for all of information we may wish to display.

Boiler plate problem

Without data-binding we have to write a lot of boiler plate code which copies the data from the model to the view. In our example this may be simple as we only have three fields to copy, but in a complex forms this may be several hundred things to copy. With time, this gets so complicated that adding a new field requires us to change many things in unison: the view, the model and and code which copies it to the view.

Circular Dependency Problem

At this point we need the view to be able to lay it out in MXML. Now imagine there is no data-binding. We have a problem, we need to notify the view to update itself from the model, and we need to get the view to call the login() function in the controller. This creates a circular dependency between the controller and the view, and there is just no way around it. This means that we can not use constructor dependency-injection.

Testing Nightmare

But there is a more serious problem, we need to test our code to make sure that it works as intended. We can easily instantiate the model, but instantiating the controller requires us to also instantiate the view. In many cases it may be impractical or impossible to instantiate the view in the test, and therefore the dependency on the view from the controller is causing the problems. The reason why it may be hard to instantiate the view is that the view may have dependency on other views and other controllers.

One way to solve this circular dependency is to create an interface for the view. That way we can have two implementations of the view. One is the real view, and second is a mock implementation of the view. In the tests we can just instantiate the mock view and we are home free. While this is a good solution it requires us to write extra interfaces and extra implementations, and so it is cumbersome. Worse, any changes to the view require us to change 4 files (controller, interface, view, and mock view). Can we do better?

Data-binding reverses dependencies

Data-binding comes to the rescue. Data-binding solves our circular problem in a very clever way. It makes it so that the controller has no reference to the view. View still recognizes the controller, as the former needs to call methods on the latter when the user interacts with it, but the circular dependency is broken. Better yet, the remaining dependency is from the view to the controller, and not the other way around. This is very important, because it allows us to test the controller in isolation: we can easily instantiate the model and the controller without pulling in the view dependency.

The magic of data-binding comes from the curly brackets ‘{}’. As you can see in the MXML above, the TextInput and the Label are both controlled by the ‘{}’. The data-binding acts as a kind of reverse dependency, a property which is very welcome, as we are trying to isolate the controller.

What I want is reverse data-binding

Unfortunately, Flex has not taken the data-binding far enough. When the model changes, the View changes as well. But since the view is a TextField, we also want the model to change when the user changes the form. This revers data-binding is not available in Flex out of the box and so we have to simulate it by adding change events that copy the data back to the model. You can see this in the MXML above, the forward data-bindings are marked in yellow and the reverse are marked in blue. This creates a lot of extra code which clutters the application.

Conclusion

So what have we learned about data-binding:

MVC inherently suffers from circular dependencies which create problem in code, that makes unit-testing of the code very difficult.

Data-binding reverses the normal flow of dependencies allowing us to break up circular dependencies, and thus get a less coupled system.

Data-binding eliminates a lot of boiler plate code which shuttles the data from the model to the view, which makes our code easier to read and understand.

posted on July 14th, 2010 ·

posted on May 29th, 2010 ·

As you can tell I am a big fan of DI, but I kept hearing that DI is not needed with dynamic languages, so after using JS for many months I am happy to say that DI is important there as well. In other words dependency managment and controll matters. But it is different.

While this code is fine, it does not follow the spirit of JavaScript which is a functional language. Why have a Greeter noun when you can just have greet verb. (see: Execution in the kingdom of nouns) So let’s rewrite it in functional style:

Notice that in all cases the DI of greeting is preserved just fine. Now here comes an interesting thing. Objects have scopes. For example the alert method in JavaScript (or System.out.println method in Java) needs to be DI as well since we want to verify that the right thing is printed in test. But the alert method needs to be injected not just into our function but most likely into hundreds of other functions in our application. It is kind of a singleton. So in java we have to do this:

But that means that we are no better than Java in injecting the same thing everywhere. The trick is in realizing that object injection is nested in scopes, and that every factory which needs alert share the same alert so we can rewrite this like this;

posted on May 26th, 2010 ·

A friend of mine has put together a set of documents which talk about do-it-yourself dependency-inject. Being that I am a fan of DI and how it helps with testability I wanted to share it with you. It is a good read for anyone interested in getting better at DI.

by Chad Parry

I want to evangelize this technique so that people know a lightweight way they can adopt DI. I think we need to refine the definition of dependency injection. It shouldn’t mean the use of a framework like Guice, because that’s just one possible implementation. It should mean the separation of glue code from business logic. The glue code, (which is represented by annotations in Guice, but could just as well be static helpers), is neither easy nor important to test. On the other hand, the business logic should be made easy to test. The secret to testability does not lie in removing untestable code as much as in segregating the untestable code.

The “dependency injection” (DI) technique is a way to improve testability and maintainability of object-oriented code. Typically adoption of dependency injection is coupled with adoption of a dependency injection framework, such as Guice[1] or Spring[2]. These materials show how dependency injection can be accomplished without any framework. The same benefits provided by frameworks can be realized using “do-it-yourself” (DIY) handcrafted code. This model is named DIY-DI, pronounced die-die.

posted on April 7th, 2010 ·

I spent the past year developing <angular/> in JavaScript (client) and Ruby on the server, and I have totally changed my opinion of dynamic languages, and I wanted to share some thought with you.

Tests are a must

Compilers are great at telling you that you have miss-typed something or that you assumptions about classes are wrong, but so is executing the code. So if all of my code is already exercised by the tests, than why do I need to have additional check of the compiler. Compile does not make the need for tests to go away, but the tests do make the need for compiler to go away. So if you have close to 100% coverage than you don’t need compiler to tell you that you mistyped something.

To get close to 100% coverage, you need to do tests first, and it has to be second nature to you. I run all of my JavaScript tests on every save across most browser using JSTestDriver and all my tests execute under a second. This instant feedback on every save is as good as having Eclipse underline your code that you made a mistake, and so I really don’t miss the compiler.

I can see how a dynamic language can be a nightmare if you don’t have tests.

Tests are easier to write

Since there are is no compiler to harrass you about types, it is very easy to fake out dependencies. Are you expecting a complicated class, but you know that in your test you are only exercising one method which should return a constant? Piece of cake! Create a nameless object with a single property which has the method and you are done.

Typing is a lot of typing

Look how much longer java line is and how much shorter JavaScript is. Is there any information missing? Both say that I have a list of Books, but one says it by convention (variable names ending in ‘s’ are arrays of the name) where as the other is explicit and makes me repeat myself by typing book three times and List twice. (Tests, prove that my code works, no need for compiler.)

Code Density

Code Density in dynamic languages are phenomenal! All of the endless casting, coercing and repetition in declaration simply is not there resulting in very dense code. But, I am master Eclipse jedi and can generate all of that verbosity with few keystrokes so typing is not an issue! True, but reading/compression is! 10 lines of code are easier to understand than 100, and in JavaScript those 10 lines often do more than 100 in Java. (To start with 100 lines of code does not fit on my screen at once.) Turns out JavaScript is still wordy and CoffeeScript is even better!

Functions as first class citizens & Classes with single methods are functions

Having functions as first class citizens which can be passed around is awesome! See Execution in the Kingdom of Nouns! Functions are verbs, and you need both, verbs and nouns to make a sentence.

Recently I got an email from someone pointing out that doing proper Single Responsibility Principle, often resulted in classes which had exactly one method. Odd? Well, actually, it is a function in disguise.

Function closure == Constructor injection

If Class with one method is a function, than dependency injection for that class is the functions closure. Where the function is created specifies what are its dependencies and its visibility, nicely solving the dependency injection problem for functions.

JavaScript is so simple

I am constantly in awe, just how simple JavaScript really is! I can explain all of the rules of JavaScript to you in few hours, something which I can not do with Java. And yet, I feel like JavaScript is so much more powerful than Java because it has functions as first class citizens.

Everything is still true

All of the things which I have talked about in my blog is still true. Dependency Injection is a must and JavaScript’s dynamic nature does not make go away. Anyone who claims that DI is only for Java and that his language somehow makes it exempt form the rules of managing your dependencies, needs to lear more about DI. Similarly global state is a bad idea, and JavaScript is extra bad here, as global is the default and you have to do extra typing to get propers scoping, same goes to functions and their default affinity to global state. Bad JavaScript, Bad! Separation of wiring from logic still holds true and no amount monkey patching, will keep you sane in the long run.

Where did the inheritance go?

I have written 10,000′s of lines of JavaScript and I am yet to come across a need for inheritance. Where did it go? Proper use of inheritance == polymorphic behavior but one can get that with duck typing just by implementing the right kind of methods.

Scaling the Team

I have heard this many times before: I like (insert your dynamic language here) for the first 1000 lines than I miss my types. Well, I have written 10,000′s of lines and I don’t miss the compiler one bit, quite the opposite I have learned to loath when I am back in Java and the compiler gets in the way. So why is my experience different? One word: Tests! I am very serious about testing, and so are my team mates! As long as you have tests, lack of compiler is not a problem and the code scales just fine across more team members. But argument can be made that it scales better:

Less code to maintain, write and understand

If you can’t understand it, just rewrite it, after all its just couple of hundred lines, how long can it take you?

JavaScript on the Server

Developing web-applications means that you have to be expert in both Java and JavaScript, but lets fix that problem by moving JavaScript to the server. Node.js is a perfect example of that, and I love it.

Non-blocking API

Non-blocking API are a stroke of Genius! In short it makes it impossible to write slow tests. After all how can you make the tests slow if all method calls return immediately? That is the reason why I can execute 400 test in under 500ms an every save.

The book starts right at the beggining as to why we want to develop test first and covers advanced topics such as testing persistance, threads, and asynchronous code. I particulary like the style with which the book delivers the message. They start by building a simple application and add new requirements to it, morphing the codebase in the process. As they do so they introduce new classes and walk the reader through the thought process considering alternatives finally choosing a solution. This gives the reader a good understanding as to what to think about when looking at code. Of course all of these changes are driven by tests, and a lot of discussion is spent on explaining why a test was written in a particular way and how to refactor it as it grows with the applications, so that tests do not become a liability.

Reading the book I sometimes felt that I was listening to myself, especially when the authors warned about global state, singletons, overusing mocks, and doing work in constructors among other things. But unlike myself, who draws sharp lines between right and wrong, the authors did a good job of presenting things on the gray scale of benefits and drawbacks. The book shows what a typical code most people will write, and then show how tests point a way towards refactoring.

If you are newbie, or an intermediate to developing with tests than this book is a must for your library!

posted on December 4th, 2009 ·

Difference between JsTestDriver and other testing solution is the difference between flying economy and flying First Class. If you are serious about testing and TDD, than JsTestDriver is for you.

It is not another Assertion Framework
JsTestDriver as the name suggest, is not another assertion framework, but rather test runner. It can easily integrate with other assertion frameworks out there. There are already adapters for QUnit, and Yahoo Testing Frameworks, as well as Ruby autotest runner. We will help you integrate your favorite test runner.

Speed
JsTestDriver is blink of an eye fast. <angular/> is no small JavaScript project and it has about 300 unit tests and 10K lines of JavaScript. With JsTestDriver I can execute all of the tests on all major browser in under 400ms. That means that I run all of my tests on every save, giving me instantaneous feedback.

IDE Integration
It is nice to be able to run your unit tests in a browser but it is better to be able to run them from the the IDE. We have integration with Eclipse and InteliJ with instant run on every change. We even marshal the browser console into the IDE console for easier debugging.

Continuos Build Integration
If you are serious about testing, than you are serious about continuous integration. Because JsTestDriver can be controlled from the command line, it can easily integrate into your continuous build. Single command starts the browsers, runs the tests, and reports the test results in a XML file which is compatible with most continuos integration servers such as Hudson.

Code Coverage Built In
JsTestDriver allows JavaScript instrumentation on the fly, which means that it can instrument your code for coverage and generate LCOV format, which can be easily converted into source annotated report of your code. This is done transparently and works on all browsers.

Remote Test Execution
I develop on Mac, but need to test on IE. I run JsTestDriver on my build machine which can be accessed by HTTP and have IE always captured. No matter where I am in the world, I can run my tests against IE. This allows me to have a small browser farm ready to do my bidding.

Support form Mobile Browsers
Just as I can capture desktop browsers, I can also capture mobile browsers. This allows me to develop in my favorite IDE and have my tests run on every save on the mobile platform.