Showing posts with label mvc. Show all posts
Showing posts with label mvc. Show all posts

Monday, March 18, 2013

Unit of Work Pattern Proved Useful in the View Layer

Today, I'm going to talk about the Unit of Work pattern and how it can be useful in a presentation tier.  For those of you familiar with this pattern, it was intended for aggregating an object and later committing to a database. The book definition for Unit of Work is:


Maintains a list of objects affected by a business transaction and coordinates the writing out of changes...

I discovered that at least part of this - Maintains a list ... and coordinates the writing out of changes - proved useful in creating cohesive, reusable web components.  Why?  Because in today's rich web experience, those components are comprised of both HTML and JavaScript.  HTML has a one-to-one correspondence between tag and element on the web page.  However, with JavaScript we can ascribe behavior to multiple elements at once; it can be one-to-many.  HTML is the templating language and so where it appears in the source matters.  JavaScript augments that markup and can be done before or after the page is rendered.  Let's walk through an example using Unit of Work for a "Unit on the Screen".

We're all in agreement that attaching JavaScript behavior after your DOM like this is good. It has Separation of Concerns. Putting it at the bottom allows the page to load faster.

// markup
<html>
 <body>
  <form>
   <input id="firstName" name="firstName" type="text" class="textbox">
   <input id="middleName" name="middleName" type="text" class="textbox">
   <input id="lastName" name="lastName" type="text" class="textbox">
   <input id="birthDate" name="birthDate" type="text" class="datebox">
  </form>
 </body>
 <script src="behavior.js"></script>
</html>

// behavior.js
$(document).ready(function() {
 $(".textbox").change(function() {
  Utils.uppercase($(this));
 });
 $("#birthDate").datepicker();
});

But what if we want to make some reusable components for our application? Afterall, that is the principle of DRY, Don't Repeat Yourself.

// ui:text
<input id="{{id}}" name="{{id}}" type="text" class="textbox">

// ui:date
<input id="{{id}}" name="{{id}}" type="text" class="datebox">

// markup
<html>
 <body>
  <form>
   <ui:text id="firstName"/>
   <ui:text id="middleName"/>   
   <ui:text id="lastName"/>   
   <ui:date id="birthDate"/>   
  </form>
 </body>
 <script src="behavior.js"></script>
</html>

// behavior.js
$(document).ready(function() {
 $(".textbox").change(function() {
  Utils.uppercase($(this));
 });
 $("#birthDate").datepicker();
});

This is bad. The caller of ui:text has no way of knowing the class of the resulting element to setup the CSS Selector. Also, the caller can forget to attach the behavior and the idea of reusable "ui:text" is not preserved within the application as being consistent. There is no cohesion.

Solution: BottomJS. It implements the Unit of Work pattern to have the reusable component render HTML and also add the JavaScript to be attached later at the bottom of the page.

// ui:text
<input id="{{id}}" name="{{id}}" type="text" class="textbox">
<ui:bottomJs>
$(".textbox").change(function() {
 Utils.uppercase($(this));
});
</ui:bottomJs>

// ui:date
<input id="{{id}}" name="{{id}}" type="text" class="datebox">
<ui:bottomJs>
$("{{id}}").datepicker();
</ui:bottomJs>

// markup
<html>
 <body>
  <form>
   <ui:text id="firstName"/>
   <ui:text id="middleName"/>   
   <ui:text id="lastName"/>   
   <ui:date id="birthDate"/>
  </form>
 </body>
 <ui:bottomJs/>
</html>

Generates the following. The reason is BottomJS builds an in-memory set of the JavaScripts to be added at the last step so redundant calls are ignored.

<html>
 <body>
  <form>
   <input id="firstName" name="firstName" type="text" class="textbox">
   <input id="middleName" name="middleName" type="text" class="textbox">
   <input id="lastName" name="lastName" type="text" class="textbox">
   <input id="birthDate" name="birthDate" type="text" class="datebox">
  </form>
 </body>
 <script>
  $(document).ready(function() {
   $(".textbox").change(function() {
    Utils.uppercase($(this));
   });
   $("#birthDate").datepicker();
  });
 </script>
</html>
Read More »

Thursday, February 11, 2010

Web UI Strategies: A Conceptual Take

From Rails to PHP, JSPs, ASPs, Flex, and straight up JavaScript, how do you choose a view technology for your RIA website?
Even within just the Java world, there is Tapestry, Stripes, Wicket, JSTL and JavaFX.
So where do you start? Find out what they mean at their core.
I see only 2 Web UI Strategies:

  1. Data first-View second
  2. View first-Data second




Data first-View second
(1st Generation Client-Server Strategy)
This is when you make a request, the server processes the request, comes up with all the data needed to populate the page and renders the page back to the client as HTML with the data in it.
i.e.

http://server/customer.page -> [Server side logic] -> fill in the template with data -> html on page

Examples:
PHP, ASP, JSP, JSTL, JSF, Tapestry, Freemarker, Wicket, Tiles, Sitemesh

Each of these views are Dynamically pieced together and Interpreted by the client browser at runtime.

The server mashes up the page layout with the data!

Think Run-time.


View first-Data second (2nd Generation Client-Server Strategy)
This is when you make a request, the server gives you a view that you download.
The view knows how to populate itself and makes a request to the server to do so.
i.e.

http://server/customer.page -> [Client downloads view from Server] -> html on page -> now fetch data from Server to fill it in

Examples:

Flex, Silverlight, JavaFX,
GWT, Generic Onload AJAX

Flex, JavaFX, and Silverlight are "sheltered" in their own runtime within the browser. Each of those 3 and GWT have a concept of getting precompiled, which aids in finding bugs earlier in the process. All make use of additional server requests after the fact to fetch the data. This idea of pushing data off until later, has been made possible with high-speed internet connections and more bandwidth where it is no longer a problem to make more HTTP trips to the server.

The view works standalone by itself with -or without- data!

Think Compile-time.

Read More »

Thursday, September 24, 2009

JavaScript - Anything is a Boolean

There is a JavaScript Trick out there that if discovered, is probably being misunderstood. The trick is to force convert any value into a boolean variable using the double not (!!) operation as follows:
var myBoolean1 = "abc"; //you end up with a String type
var myBoolean2 = !!"abc"; //you end up with a boolean type
However, watch closely as here are the results of each use:
equals(true, !!"some text", "Any non-empty String results in true");
equals(true, !!"False");
equals(true, !!"false");
equals(true, !!"True");
equals(true, !!"true");
equals(true, !!"null");
equals(false, !!"", "JavaScript treats if ('') as false");
equals(false, !!null, "JavaScript treats if (null) as false";
equals(ERROR, !!MyObject, "Throws exception because undefined object";
var MyObject = null;
equals(false, !!MyObject, "JavaScript treats any null object as false";
equals(true, !!window, "JavaScript treats any non-null object as true";
equals(true, !!32, "Any non-zero number results in true");
equals(true, !!1);
equals(false, !!0, "Hopefully as you expected since everything is binary");
equals(false, !!false, "As expected");
equals(true, !!true, "As expected");
Read More »

Tuesday, March 31, 2009

JavaScript Classes

Most people hate JavaScript and for that reason copy snippets here and there without thinking about how to make it more object-oriented and encapsulated like they do in their other languages. I have found these 4 ways to make javascript classes, which gives them scope and control over what is exposed. It also reduces the chance that your page has a function getName() and so does that .js file you are including! (BTW, the last one interpreted by the browser wins.)

Here is code for 4 different ways to do it, with each outcome below it. My preferred way is Three.


var One = {
me: "me",
myself: "myself",
i: function() {
return 1;
}
};

One cannot be constructed, all fields are public static.

equals( "me", One.me );
equals( "myself", One.myself );
equals( 1, One.i() );

------------

var Two = function() {
var me = "me";
this.myself ="myself";
this.i = function() {
return 1;
}
};

Two must be instantiated. Fields declared with 'var' are private, those declared with 'this.' are public.

var twoInst = new Two();
equals ( undefined, twoInst.me ); //because it is private
equals ( "myself", twoInst.myself );
equals ( 1, twoInst.i() );

------------

var Three = new function() {
var me = "me";
this.myself ="myself";
this.i = function() {
return 1;
};
};

*Three is my preferred way. Three is a singleton (already instantiated), fields may be private or public, called like a static. Fields declared with 'var' are private, those declared with 'this.' are public.

equals ( undefined, Three.me ); // because it is private
equals ( "myself", Three.myself );
equals ( 1, Three.i() );

------------

function Four() {
var me = "me";
this.myself = "myself";
}

Four.prototype.getMe = function() {
return this.me;
}

Four.prototype.getMyself = function() {
return this.myself;
}

Four.prototype.i = function() {
return 1;
}

Four must be instantiated, but the class is open and you can continue to add fields to it. Every instance gets every prototype of that class the window knows about.

var fourInst = new Four();
equals( undefined, fourInst.me ); // because it is private
equals( "myself", fourInst.myself );
equals( undefined, fourInst.getMe() ); // because it is private
equals( "myself", fourInst.getMyself() );
equals( 1, fourInst.i() );

Read More »