<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-5782963451915595803</id><updated>2012-02-16T02:16:10.834-08:00</updated><category term='Design'/><category term='View'/><category term='JSP'/><category term='Professional Development'/><category term='Testing'/><title type='text'>The Software Forest</title><subtitle type='html'>taking the path less traveled by</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://daneking.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5782963451915595803/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://daneking.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>Dane</name><uri>http://www.blogger.com/profile/08190098834299132102</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>13</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-5782963451915595803.post-3013169827288429406</id><published>2011-10-29T04:23:00.000-07:00</published><updated>2011-10-29T04:23:34.084-07:00</updated><title type='text'>I Spy with My Little Mockito</title><content type='html'>Recently I was stuck trying to get some code under test. There was some complex code, with random generating ids, side effects, etc. Generally all the things that make testing hard.&lt;br /&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;I'm using &lt;a href="http://code.google.com/p/mockito/downloads/list"&gt;mockito &lt;/a&gt;and I am not familiar with all its features, but I did know that it was supposed to give me the ability to partially mock. So away I went.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Remember this is a very contrived example.&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;pre style="background-color: #eeeeee; border: 1px dashed #999999; color: black; font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; font-size: 12px; line-height: 14px; overflow: auto; padding: 5px; width: 100%;"&gt;&lt;code&gt;package controller;&lt;br /&gt;&lt;br /&gt;public class ComplexClass {&lt;br /&gt;&lt;br /&gt;    String someComplexCode() {&lt;br /&gt;        long num = Math.round(Math.random());&lt;br /&gt;        if (num % 2 == 0) {&lt;br /&gt;            return "Even";&lt;br /&gt;        } else {&lt;br /&gt;            return "Odd";&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    public String callsComplexCode(){&lt;br /&gt;        String output=someComplexCode();&lt;br /&gt;        return output;&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;This is the code I want to add&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;pre style="background-color: #eeeeee; border-bottom-color: rgb(153, 153, 153); border-bottom-style: dashed; border-bottom-width: 1px; border-left-color: rgb(153, 153, 153); border-left-style: dashed; border-left-width: 1px; border-right-color: rgb(153, 153, 153); border-right-style: dashed; border-right-width: 1px; border-top-color: rgb(153, 153, 153); border-top-style: dashed; border-top-width: 1px; font-family: 'Andale Mono', 'Lucida Console', Monaco, fixed, monospace; font-size: 12px; line-height: 14px; overflow-x: auto; overflow-y: auto; padding-bottom: 5px; padding-left: 5px; padding-right: 5px; padding-top: 5px; width: 100%;"&gt;&lt;code&gt;package controller;&lt;br /&gt;&lt;br /&gt;public class ComplexClass {&lt;br /&gt;&lt;br /&gt;    String someComplexCode() {&lt;br /&gt;        long num = Math.round(Math.random());&lt;br /&gt;        if (num % 2 == 0) {&lt;br /&gt;            return "Even";&lt;br /&gt;        } else {&lt;br /&gt;            return "Odd";&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    public String callsComplexCode(){&lt;br /&gt;        String output=someComplexCode();&lt;br /&gt;&lt;span class="Apple-style-span" style="color: blue;"&gt;       &lt;b&gt; if("Odd".equals(output)){&lt;br /&gt;            output+=" man out";&lt;br /&gt;        }else{&lt;br /&gt;            output+=" More";&lt;br /&gt;        }&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;        return output;&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;br /&gt;And here are my tests that I want to run&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;pre style="background-color: #eeeeee; border: 1px dashed #999999; color: black; font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; font-size: 12px; line-height: 14px; overflow: auto; padding: 5px; width: 100%;"&gt;&lt;code&gt;package controller;&lt;br /&gt;&lt;br /&gt;import static org.junit.Assert.assertNotNull;&lt;br /&gt;&lt;br /&gt;import org.junit.Test;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;public class ComplexClassTest {&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;    @Test&lt;br /&gt;    public void testCallsComplexCode(){&lt;br /&gt;        ComplexClass complexClass=new ComplexClass();&lt;br /&gt;        String output=complexClass.callsComplexCode();&lt;br /&gt;        assertNotNull(output);&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    @Test&lt;br /&gt;    public void testCallsNewComplexCodeEven(){&lt;br /&gt;        ComplexClass complexClass=new ComplexClass();&lt;br /&gt;        String output=complexClass.callsComplexCode();&lt;br /&gt;        assertEquals("Even More",output);&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    @Test&lt;br /&gt;    public void testCallsNewComplexCodeOdd(){&lt;br /&gt;        ComplexClass complexClass=new ComplexClass();&lt;br /&gt;        String output=complexClass.callsComplexCode();&lt;br /&gt;        assertEquals("Odd man out",output);&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;}&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;As you can see the tests will fail since the output is randomly generated. This is actually a big problem with legacy code. I don't really care right now abut the method someComplexCode and I don't want to refactor it without some tests in place or taking a long time to try to understand it. I just want to add code to callsComplexCode.&lt;br /&gt;&lt;br /&gt;What I need is a way of mocking the class that I'm testing. Partial mocks to the rescue.&lt;br /&gt;&lt;br /&gt;Partial mocks give us the ability to mock sections of the code and use the actually code for other sections. This allows us to get some of the class under test. In an ideal world we should be able to test everything from public interface, but I have to deal with legacy code and this is a very powerful tool to test my changes.&lt;br /&gt;&lt;br /&gt;And here is the new test&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre style="background-color: #eeeeee; border-bottom-color: rgb(153, 153, 153); border-bottom-style: dashed; border-bottom-width: 1px; border-left-color: rgb(153, 153, 153); border-left-style: dashed; border-left-width: 1px; border-right-color: rgb(153, 153, 153); border-right-style: dashed; border-right-width: 1px; border-top-color: rgb(153, 153, 153); border-top-style: dashed; border-top-width: 1px; font-family: 'Andale Mono', 'Lucida Console', Monaco, fixed, monospace; font-size: 12px; line-height: 14px; overflow-x: auto; overflow-y: auto; padding-bottom: 5px; padding-left: 5px; padding-right: 5px; padding-top: 5px; width: 100%;"&gt;&lt;code&gt;&lt;br /&gt;package controller;&lt;br /&gt;&lt;br /&gt;import static org.junit.Assert.assertEquals;&lt;br /&gt;import static org.junit.Assert.assertNotNull;&lt;br /&gt;import static org.mockito.Mockito.doReturn;&lt;br /&gt;import static org.mockito.Mockito.spy;&lt;br /&gt;&lt;br /&gt;import org.junit.Test;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;public class ComplexClassTest {&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;    @Test&lt;br /&gt;    public void testCallsComplexCode(){&lt;br /&gt;        ComplexClass complexClass=new ComplexClass();&lt;br /&gt;        String output=complexClass.callsComplexCode();&lt;br /&gt;        assertNotNull(output);&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    @Test&lt;br /&gt;    public void testCallsNewComplexCodeEven(){&lt;br /&gt;        ComplexClass complexClass=new ComplexClass();&lt;br /&gt;&lt;span class="Apple-style-span" style="color: blue;"&gt;        complexClass=spy(complexClass);&lt;br /&gt;        doReturn("Even").when(complexClass).someComplexCode();&lt;/span&gt;&lt;br /&gt;        String output=complexClass.callsComplexCode();&lt;br /&gt;        assertEquals("Even More",output);&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    @Test&lt;br /&gt;    public void testCallsNewComplexCodeOdd(){&lt;br /&gt;        ComplexClass complexClass=new ComplexClass();&lt;br /&gt;&lt;span class="Apple-style-span" style="color: blue;"&gt;        complexClass=spy(complexClass);&lt;br /&gt;        doReturn("Odd").when(complexClass).someComplexCode();&lt;/span&gt;&lt;br /&gt;        String output=complexClass.callsComplexCode();&lt;br /&gt;        assertEquals("Odd man out",output);&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;Now I have the complex method under control and I can test my code.&lt;br /&gt;&lt;br /&gt;Ok, sounds great but what are the drawbacks? Well all the methods to be mocked have to be visible to the test and non final. I wrote before about testing private method and I still tend to think its a bad practice, but I also think as a last resort its OK to use some of these techniques.&lt;br /&gt;&lt;br /&gt;There is also a danger here is that we bypass code that really needs to be refactored. One of the reason this code is hard to test is its designed badly.&lt;br /&gt;&lt;br /&gt;In the book &lt;a href="http://www.amazon.com/Working-Effectively-Legacy-Michael-Feathers/dp/0131177052"&gt;Working Effectively with Legacy Code&lt;/a&gt;, Michael Feathers talks about using sprouts to bypass functionality we don't have the time to understand and growing new clean code in its place or around it. Also if some changes the someComplexCode our test will still pass since we are mocking the behavior. However, &amp;nbsp;to add some functionality and get that new code under test partial mocks could be a valuable tool.&lt;br /&gt;&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5782963451915595803-3013169827288429406?l=daneking.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://daneking.blogspot.com/feeds/3013169827288429406/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://daneking.blogspot.com/2011/10/i-spy-with-my-little-mockito.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5782963451915595803/posts/default/3013169827288429406'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5782963451915595803/posts/default/3013169827288429406'/><link rel='alternate' type='text/html' href='http://daneking.blogspot.com/2011/10/i-spy-with-my-little-mockito.html' title='I Spy with My Little Mockito'/><author><name>Dane</name><uri>http://www.blogger.com/profile/08190098834299132102</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5782963451915595803.post-5043086814159559625</id><published>2010-10-07T08:34:00.000-07:00</published><updated>2010-11-07T08:35:30.099-08:00</updated><title type='text'>He Man Java Haters Club</title><content type='html'>&lt;img src="http://4.bp.blogspot.com/_feMqCz9F1hc/TNbJM0t47VI/AAAAAAAAAA8/Cpcp18mNe64/s320/HeManJavaHatersClub.jpg" width="250" /&gt;&lt;br /&gt;&lt;br /&gt;If you ever watched Little Rascals, you know about the &lt;a href="http://www.facebook.com/group.php?gid=2263118961"&gt;He-Man Woman Haters Club&lt;/a&gt;. Well now that there are a billion new languages for the JVM, I'm starting to see another club, the He-Man Java Haters Club, and it has a similar oath. First, I'm not saying Java is the one true language that replaces all others. Learning new languages is important. And its important even if you don't use them right away because it gives you a new way of looking at a problem, a new way of thinking. As Einstien said, "Problems cannot be solved by the same level of thinking that created them."&lt;br /&gt;&lt;br /&gt;For instance, after I learned a little Haskell, I think I wrote better methods that didn't have side effects. As much as I would enjoy coding for a while in a Lisp based language, I realize that most of my work involves coding Java and since I am a consultant, most of my future work will also involve Java. So I try to include the essence of it in my programming until I can get a chance to program in it.&lt;br /&gt;&lt;br /&gt;Does that make Java stupid or ugly or whatever negative adjective you can think of? The answer is no. Of course it has limitations, so does every language and if you don't see that you are missing the point. Java is an object oriented language, this is where it excels, it has a mature set of tools and a ready source of developers. That is why it is popular for enterprise level programs that need to model a business problem. That is why it works well in implementing the Model in the MVC pattern. It's also why new disruptive websites programs that need to evolve quickly and are starting to be written in other languages.&lt;br /&gt;&lt;br /&gt;But hating Java is like hating the hammer because you can't use it as a screwdriver. Mainframe programming is still being used in some big companies. What made it a good tool before is why it is still around. It may have gotten a bad rep for trying to do everything, and it took it awhile to find its niche, but for certain problems it still works well.&lt;br /&gt;&lt;br /&gt;So, learn the other languages. Figure out what they do well and add them to your toolbox. But don't do the same thing that the old language did, which is try to do everything with your shiny new tool. Don't be a one tool&amp;nbsp;programmer, because if all you have is a hammer everything looks like a nail.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5782963451915595803-5043086814159559625?l=daneking.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://daneking.blogspot.com/feeds/5043086814159559625/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://daneking.blogspot.com/2010/11/he-man-java-haters-club.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5782963451915595803/posts/default/5043086814159559625'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5782963451915595803/posts/default/5043086814159559625'/><link rel='alternate' type='text/html' href='http://daneking.blogspot.com/2010/11/he-man-java-haters-club.html' title='He Man Java Haters Club'/><author><name>Dane</name><uri>http://www.blogger.com/profile/08190098834299132102</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_feMqCz9F1hc/TNbJM0t47VI/AAAAAAAAAA8/Cpcp18mNe64/s72-c/HeManJavaHatersClub.jpg' height='72' width='72'/><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5782963451915595803.post-4936547362217680459</id><published>2010-05-15T04:42:00.000-07:00</published><updated>2010-07-03T04:43:03.436-07:00</updated><title type='text'>The Code is Not a Requirement Document</title><content type='html'>The other day I got one of the infamous requirements conversations that developers have every so often. It goes like this. &lt;br /&gt;&lt;br /&gt;BA        - And your change should not affect the existing behavior of the system. &lt;br /&gt;Developer - OK, what is the existing behavior of the system.&lt;br /&gt;BA        - UM, look at the code&lt;br /&gt;Developer - So what is the final result so I can look at the code.&lt;br /&gt;BA        - UM, look at the code&lt;br /&gt;Developer - What should I tell QA to test&lt;br /&gt;BA        - UM, look at the code&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;The code is not a requirement document. Unless the code is very simple, you cannot effectively tell what the final behavior is because the code is not a final state, it's a state machine. It takes inputs in the form of data and delivers an output. Based on the inputs it can deliver an infinite amount of outputs. This is why we have bugs in our software. We don't intentionally write code that will break, its usually that some input in the software takes us down another path that we didn't expect.&lt;br /&gt;&lt;br /&gt;Yes, I will admit that many times this is possible and even probable for a method, maybe for a class, but it doesn't tell us all the interactions of our code. There are a host of interactions, UI, database, middle ware, back-end processes, etc. Add to this the ability of callbacks, dependency injection or manipulation of the data somewhere other than in the code and it quickly gets complex.&lt;br /&gt;&lt;br /&gt;Even if I can decipher the code, it might anchor me into a horrible solution. Maybe the code I'm looking at is the worst possible way to solve this particular problem, maybe there are simpler, easier solutions, its hard to step back and look at a problem once I see the current code as the "solution".&lt;br /&gt;&lt;br /&gt;I use the analogy of a car in the parking lot. I can tell you a lot about that car, make and model, where it is parked. However, if you ask me to start defining rules of behavior, basically the requirements, I would start to struggle. It would depend on the driver, which way do they drive to work, maybe what time they drive to work. What is the average speed, the maximum? Do they make right turns on red? Do they take the long way, because there is always congestion on the freeway? I would probably get many of the rules right, but that because I know how a car works and some of the driving laws in my area. But if its code that I don't know very well, then all bets are off.&lt;br /&gt;&lt;br /&gt;Am I complaining, maybe a little. But I do enjoy working with this level of detail, that why I do this and get paid for it. Its complex and messy and hard, but it's also fun. As much as I enjoy untangling some code, it doesn't tell me what the intent was or what the business is trying to accomplish. Looking at the code to see what the requirements are works in some cases, but most of the time we just need to do the hard work of hashing out what exactly it is we are trying to program.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5782963451915595803-4936547362217680459?l=daneking.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://daneking.blogspot.com/feeds/4936547362217680459/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://daneking.blogspot.com/2010/07/code-is-not-requirement-document.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5782963451915595803/posts/default/4936547362217680459'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5782963451915595803/posts/default/4936547362217680459'/><link rel='alternate' type='text/html' href='http://daneking.blogspot.com/2010/07/code-is-not-requirement-document.html' title='The Code is Not a Requirement Document'/><author><name>Dane</name><uri>http://www.blogger.com/profile/08190098834299132102</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5782963451915595803.post-2907295081529386395</id><published>2010-04-15T06:11:00.000-07:00</published><updated>2010-05-02T06:17:57.930-07:00</updated><title type='text'>Spicy curry for my javascript</title><content type='html'>I had came across currying when studying functional languages, and I struggled a bit with the concept. I always saw mathematical examples and complex explanations, but never a concrete example of how and why I should use it. Until the other day when I had an Aha moment. &lt;br /&gt;&lt;br /&gt;So what is currying? It is a partial application of a function. For example you have a function that takes 2 arguments and you only pass one and wait until later to supply the second argument. This could be on a callback or in a closure. &lt;br /&gt;&lt;br /&gt;Its also useful the other way, if you have a function that only takes 1 argument and you want to pass another argument. This is where I had my moment of zen. I was trying to get an event into a DWR callback function. The problem is the function only takes 1 argument supplied by the DWR call. &lt;br /&gt;&lt;iframe src="http://rcm.amazon.com/e/cm?t=theso0d5-20&amp;o=1&amp;p=8&amp;l=bpl&amp;asins=1590599195&amp;fc1=000000&amp;IS2=1&amp;lt1=_blank&amp;m=amazon&amp;lc1=0000FF&amp;bc1=000000&amp;bg1=FFFFFF&amp;f=ifr" style="align:left;padding-top:5px;width:131px;height:245px;padding-right:10px;"align="left" scrolling="no" marginwidth="0" marginheight="0" frameborder="0"&gt;&lt;/iframe&gt;&lt;br /&gt;Since we are using Prototype, I discovered Prototype had a curry function also. By the way here is a good reference book on Prototype. I am starting to find the more I learn about Prototype the more I like it.&lt;br /&gt;&lt;br /&gt;Well, enough talking, time for some code. For simplicity, I included the prototype.js in the same directory has my html.&lt;br /&gt;&lt;pre style="font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; color: #000000; background-color: #eee;font-size: 12px;border: 1px dashed #999999;line-height: 14px;padding: 5px; overflow: auto; width: 100%"&gt;&lt;code&gt;&amp;lt;script type=&amp;quot;text/javascript&amp;quot; src=&amp;quot;prototype.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;&amp;lt;script type=&amp;quot;text/javascript&amp;quot;&amp;gt;&lt;br /&gt;function baseMethod(msg){&lt;br /&gt;    alert(msg);&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;baseMethod(&amp;quot;Normal operation&amp;quot;);&lt;br /&gt;&lt;br /&gt;function wrappedMsg(times,msg){&lt;br /&gt;    for(i=1;i&amp;lt;=times;i++){&lt;br /&gt;        baseMethod(msg);&lt;br /&gt;    }&lt;br /&gt;};&lt;br /&gt;var newBaseMsg=wrappedMsg.curry(2);&lt;br /&gt;newBaseMsg(&amp;quot;Curried Operation&amp;quot;);&lt;br /&gt;&amp;lt;/script&amp;gt;&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;In the code we have a function that takes only one argument, like the DWR callback function. By wrapping the code I am able to change the behavior of the function and the use the newBaseMsg wherever I would use the DWR callback function. &lt;br /&gt;&lt;br /&gt;&lt;br /&gt;If you aren't using Prototype don't despair. I found a good link that &lt;br /&gt;&lt;a href="http://www.webreference.com/programming/javascript/rg17/"&gt;explains it very well.&lt;/a&gt;&lt;br /&gt;Replacing the prototype function with the curry function will accomplish the same thing. &lt;br /&gt;&lt;pre class="source-code"&gt;&lt;code&gt;&amp;lt;script type=&amp;quot;text/javascript&amp;quot;&amp;gt;&lt;br /&gt;Function.prototype.curry = function() &lt;br /&gt;{ &lt;br /&gt;  var method = this, args = Array.prototype.slice.call(arguments); &lt;br /&gt;  return function() &lt;br /&gt;  { &lt;br /&gt;    return method.apply(this, args.concat(Array.prototype.slice.call(arguments))); &lt;br /&gt;  }; &lt;br /&gt;}; &lt;br /&gt;function baseMethod(msg){&lt;br /&gt;    alert(msg);&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;baseMethod(&amp;quot;Normal operation&amp;quot;);&lt;br /&gt;&lt;br /&gt;function wrappedMsg(times,msg){&lt;br /&gt;    for(i=1;i&amp;lt;=times;i++){&lt;br /&gt;        baseMethod(msg);&lt;br /&gt;    }&lt;br /&gt;};&lt;br /&gt;var newBaseMsg=wrappedMsg.curry(2);&lt;br /&gt;newBaseMsg(&amp;quot;Curried Operation&amp;quot;);&lt;br /&gt;&amp;lt;/script&amp;gt;&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;I think we forget sometimes that JavaScript has many attributes of a functional language that make it very powerful and can provide some elegant solutions to some problems we have.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5782963451915595803-2907295081529386395?l=daneking.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://daneking.blogspot.com/feeds/2907295081529386395/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://daneking.blogspot.com/2010/05/spicy-curry-for-my-javascript.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5782963451915595803/posts/default/2907295081529386395'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5782963451915595803/posts/default/2907295081529386395'/><link rel='alternate' type='text/html' href='http://daneking.blogspot.com/2010/05/spicy-curry-for-my-javascript.html' title='Spicy curry for my javascript'/><author><name>Dane</name><uri>http://www.blogger.com/profile/08190098834299132102</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5782963451915595803.post-5808784931336920176</id><published>2010-02-16T06:19:00.000-08:00</published><updated>2010-04-13T15:19:33.477-07:00</updated><title type='text'>Information Architecture (IA) That Sucks Less</title><content type='html'>If you have ever went to a site that was hard to use its probably because someone left it up to the developers to make the site "look OK". Often as a web developer on a small team, we don't have the resources of large enterprises. Tasks like usability and design often fall to the developer writing the web pages. &lt;br /&gt;&lt;br /&gt;Since I've found myself in this position more than a few times, I decided I could learn a little about these fields that might help me suck less at it. I found a book called &lt;iframe src="http://rcm.amazon.com/e/cm?t=theso0d5-20&amp;o=1&amp;p=8&amp;l=bpl&amp;asins=0596527349&amp;fc1=000000&amp;IS2=1&amp;lt1=_blank&amp;m=amazon&amp;lc1=0000FF&amp;bc1=000000&amp;bg1=FFFFFF&amp;f=ifr" style="align:left;padding-top:5px;width:131px;height:245px;padding-right:10px;"align="left" scrolling="no" marginwidth="0" marginheight="0" frameborder="0"&gt;&lt;/iframe&gt;. Its a great introduction to Information Architecture (IA),this is a fairly new discipline and there are many views on what an IA is and what it should they be. Are they the designer that focuses on the look and feel or in my case the developer that makes is all work together? It could be creating the content or focusing on usability. In truth its a little of all of this, that's why its so hard. Maybe some of the larger projects would need a formal position, but I think we can go a long way by learning a little ourselves and making the interface of our sites suck less.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5782963451915595803-5808784931336920176?l=daneking.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://daneking.blogspot.com/feeds/5808784931336920176/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://daneking.blogspot.com/2010/03/information-architecture-ia-that-suck.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5782963451915595803/posts/default/5808784931336920176'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5782963451915595803/posts/default/5808784931336920176'/><link rel='alternate' type='text/html' href='http://daneking.blogspot.com/2010/03/information-architecture-ia-that-suck.html' title='Information Architecture (IA) That Sucks Less'/><author><name>Dane</name><uri>http://www.blogger.com/profile/08190098834299132102</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5782963451915595803.post-4555315885971572006</id><published>2010-02-16T04:59:00.000-08:00</published><updated>2010-02-16T04:59:54.271-08:00</updated><title type='text'>Theory of Constraints and The Efficient Programmer</title><content type='html'>The &lt;a href="http://en.wikipedia.org/wiki/Theory_of_Constraints"&gt;Theory of Constraints&lt;/a&gt; is a management theory that comes from the book &lt;a href="http://www.amazon.com/Goal-Process-Ongoing-Improvement/dp/0884271781/ref=sr_1_1?ie=UTF8&amp;s=books&amp;qid=1266322099&amp;sr=8-1"&gt;The Goal&lt;/a&gt;. Basically it says in a process there are a few constraints that limit how fast the whole pipeline works. An example in software development would be waiting on the database team to design the tables or the waiting for BAs to write the requirements. If they are the slowest point then it doesn't matter how fast we code. The book also talks about optimizing points in the process may or may not help the entire process. &lt;br /&gt;&lt;br /&gt;Why is this? Imagine a factory floor that produces widgets. The process has to go through 10 machines. One of the machines is 1/2 as slow as the rest. Its obvious that this will result in everything piling up in front of the machine. However, what if some engineers tweaked another machine so it was 2 times as fast. First a backup would occur in front of the machine that comes after the machine that runs faster and the other thing is that the process is not any faster. Since we still have one machine running at 1/2 the speed it doesn't speed up the overall process. The most efficient use of our resources would be to optimize the slow machine.&lt;br /&gt;&lt;br /&gt;How does this relate to being an efficient programmer. I've seen efficient programmers get their work done and always try to get more work. Their utilization looks good, everyone comments on how fast they go through the code. However, do they ask questions of the lead who is already swamped. Do they bother other resources that our busy with fixing priority defects, do they do anything to improve the process. In other words are they optimizing their work at the expense of the overall process. In the goal it suggests that it may be better to idle a resource rather than have it pile up backlogs. I'm not suggesting that the person sits and twiddles their thumbs. I'm saying they should be aware of what time and resources they are pulling to get their task done and is pulling those resources away the best for the overall project. Could they work on unit tests or conducting a spike on a new technology, updating documentation or somehow improving the throughput of the entire process instead of a laser beam focus on getting their code done. Could they look at who has the most work and pair program or take some workload off of them. I feel this would be a better use of their time.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5782963451915595803-4555315885971572006?l=daneking.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://daneking.blogspot.com/feeds/4555315885971572006/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://daneking.blogspot.com/2010/02/theory-of-constraints-and-efficient.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5782963451915595803/posts/default/4555315885971572006'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5782963451915595803/posts/default/4555315885971572006'/><link rel='alternate' type='text/html' href='http://daneking.blogspot.com/2010/02/theory-of-constraints-and-efficient.html' title='Theory of Constraints and The Efficient Programmer'/><author><name>Dane</name><uri>http://www.blogger.com/profile/08190098834299132102</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5782963451915595803.post-3519116145576917869</id><published>2009-11-10T04:46:00.000-08:00</published><updated>2009-11-22T07:14:52.678-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='JSP'/><category scheme='http://www.blogger.com/atom/ns#' term='View'/><title type='text'>Keep Your Complexity Out of My JSP View - JSP Functions</title><content type='html'>&lt;style type="text/css"&gt;&lt;br /&gt;pre.source-code {&lt;br /&gt;  font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; &lt;br /&gt;  color: #000000;&lt;br /&gt;  background-color: #eee;&lt;br /&gt;  font-size: 12px;&lt;br /&gt;  border: 1px dashed #999999;&lt;br /&gt;  line-height: 14px;&lt;br /&gt;  padding: 5px;&lt;br /&gt;  overflow: auto;&lt;br /&gt;  width: 100%&lt;br /&gt;}&lt;br /&gt;&lt;/style&gt;&lt;br /&gt;&lt;br /&gt;The JSTL library comes with built in &lt;a href="http://java.sun.com/products/jsp/jstl/1.1/docs/tlddocs/index.html"&gt;functions&lt;/a&gt; that are very useful. Hopefully these functions meet your needs, but sometimes you need to write your own. Sometimes you might want to expose some static util functions to your page. Well with JSP 2.0 you can write you own. &lt;br /&gt;&lt;br /&gt;In my example I'm going to write a debug tag to be able to print out session and request variables. It also gives you a convenient point to set a debug point so you can inspect context variables. &lt;br /&gt;&lt;br /&gt;The first thing to do is to write a tld file. This is just like we do for old JSP tags. I put the tld under WEB-INF/tld/ and I will reference that path when I declare it in the JSP page. &lt;br /&gt;&lt;br /&gt;Here is my tld file&lt;br /&gt;The main parts are under the function node. There is the name that you will use to call the function, the function-class is the java class that contains the function and the function-signature is the signature of the function. We need to use fully qualified names for the return and parameters.&lt;br /&gt;&lt;pre class="source-code"&gt;&lt;code&gt;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;ISO-8859-1&amp;quot; ?&amp;gt;&lt;br /&gt;&amp;lt;taglib xmlns=&amp;quot;http://java.sun.com/xml/ns/j2ee&amp;quot;&lt;br /&gt;xmlns:xsi=&amp;quot;http://www.w3.org/2001/XMLSchema-instance&amp;quot;&lt;br /&gt;xsi:schemaLocation=&amp;quot;http://java.sun.com/xml/ns/j2ee web-jsptaglibrary_2_0.xsd&amp;quot;&lt;br /&gt;version=&amp;quot;2.0&amp;quot;&amp;gt;&lt;br /&gt;    &amp;lt;tlib-version&amp;gt;1.0&amp;lt;/tlib-version&amp;gt; &lt;br /&gt;    &amp;lt;jsp-version&amp;gt;2.1&amp;lt;/jsp-version&amp;gt;&lt;br /&gt;    &amp;lt;short-name&amp;gt;fnt&amp;lt;/short-name&amp;gt;&lt;br /&gt;    &amp;lt;uri&amp;gt;http://daneking.blogspot.com&amp;lt;/uri&amp;gt;&lt;br /&gt;    &amp;lt;description&amp;gt;A debug function&amp;lt;/description&amp;gt;&lt;br /&gt;    &amp;lt;function&amp;gt;&lt;br /&gt;       &amp;lt;name&amp;gt;debugPage&amp;lt;/name&amp;gt;&lt;br /&gt;       &amp;lt;function-class&amp;gt;&lt;br /&gt;           viewhelper.JSPMethodCall&lt;br /&gt;       &amp;lt;/function-class&amp;gt;&lt;br /&gt;       &amp;lt;function-signature&amp;gt;&lt;br /&gt;           java.lang.String callFactoryMethod(javax.servlet.jsp.PageContext)&lt;br /&gt;       &amp;lt;/function-signature&amp;gt;&lt;br /&gt;   &amp;lt;/function&amp;gt;&lt;br /&gt;&amp;lt;/taglib&amp;gt;&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Now here is the java code to create a string of the session and request variables. I bolded the call to the implementation of the my method.&lt;br /&gt;&lt;br /&gt;&lt;pre class="source-code"&gt;&lt;code&gt;package viewhelper;&lt;br /&gt;&lt;br /&gt;import java.util.Enumeration;&lt;br /&gt;&lt;br /&gt;import javax.servlet.ServletRequest;&lt;br /&gt;import javax.servlet.http.HttpSession;&lt;br /&gt;import javax.servlet.jsp.PageContext;&lt;br /&gt;&lt;br /&gt;public class JSPMethodCall {&lt;br /&gt;  &lt;br /&gt;   private static final String CR = "&amp;lt;br/&amp;gt;";&lt;br /&gt;  &lt;br /&gt;   private static String printSessionAttributes(HttpSession s,String header){&lt;br /&gt;       StringBuffer sb=new StringBuffer(header);&lt;br /&gt;       sb.append(CR);&lt;br /&gt;       Enumeration e=s.getAttributeNames();&lt;br /&gt;       while(e.hasMoreElements()){&lt;br /&gt;           String var=(String)e.nextElement();&lt;br /&gt;           sb.append(var);&lt;br /&gt;           sb.append(" = " + s.getAttribute(var));&lt;br /&gt;           sb.append(CR);&lt;br /&gt;       }&lt;br /&gt;       return sb.toString();&lt;br /&gt;      &lt;br /&gt;   }&lt;br /&gt;   private static String printRequestAttributes(ServletRequest r,String header){&lt;br /&gt;       StringBuffer sb=new StringBuffer(header);&lt;br /&gt;       sb.append(CR);&lt;br /&gt;       Enumeration e=r.getAttributeNames();&lt;br /&gt;       while(e.hasMoreElements()){&lt;br /&gt;           String var=(String)e.nextElement();&lt;br /&gt;           sb.append(var);&lt;br /&gt;           sb.append(" = " + r.getAttribute(var));&lt;br /&gt;           sb.append(CR);&lt;br /&gt;       }&lt;br /&gt;       return sb.toString();&lt;br /&gt;      &lt;br /&gt;   }&lt;br /&gt;&lt;b&gt;   public static String callFactoryMethod(PageContext ctx)&lt;/b&gt;{&lt;br /&gt;       HttpSession session =ctx.getSession();&lt;br /&gt;      &lt;br /&gt;       StringBuffer sb=new StringBuffer(CR + "--- Debug Values ---" + CR);&lt;br /&gt;       sb.append(printSessionAttributes(session,"---Session ---"));&lt;br /&gt;       ServletRequest servletRequest = ctx.getRequest();&lt;br /&gt;       sb.append(printRequestAttributes(servletRequest,"---Request ---"));&lt;br /&gt;       return sb.toString();&lt;br /&gt;   }&lt;br /&gt;&lt;br /&gt;}&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;And the finally the call from the JSP page. I've bolded the important parts where we call the function and the declaration of the tld page where we defined our function.&lt;br /&gt;&lt;br /&gt;&lt;pre class="source-code"&gt;&lt;code&gt;&amp;lt;%@ page language=&amp;quot;java&amp;quot; contentType=&amp;quot;text/html; charset=ISO-8859-1&amp;quot;&lt;br /&gt;    pageEncoding=&amp;quot;ISO-8859-1&amp;quot; %&amp;gt;&lt;br /&gt;&amp;lt;%@ taglib prefix=&amp;quot;c&amp;quot; uri=&amp;quot;http://java.sun.com/jsp/jstl/core&amp;quot; %&amp;gt;&lt;br /&gt;&lt;b&gt;&amp;lt;%@ taglib uri=&amp;quot;/WEB-INF/tlds/fntags.tld&amp;quot; prefix=&amp;quot;fnt&amp;quot; %&amp;gt;&lt;/b&gt;&lt;br /&gt;  &lt;br /&gt;&lt;br /&gt;&amp;lt;!DOCTYPE html PUBLIC &amp;quot;-//W3C//DTD HTML 4.01 Transitional//EN&amp;quot; &amp;quot;http://www.w3.org/TR/html4/loose.dtd&amp;quot;&amp;gt;&lt;br /&gt;&amp;lt;html&amp;gt;&lt;br /&gt;&amp;lt;head&amp;gt;&lt;br /&gt;&amp;lt;meta http-equiv=&amp;quot;Content-Type&amp;quot; content=&amp;quot;text/html; charset=ISO-8859-1&amp;quot;&amp;gt;&lt;br /&gt;&amp;lt;title&amp;gt;Calling Functions&amp;lt;/title&amp;gt;&lt;br /&gt;&amp;lt;/head&amp;gt;&lt;br /&gt;&amp;lt;body&amp;gt;&lt;br /&gt;&amp;lt;c:set scope=&amp;quot;session&amp;quot; var=&amp;quot;sessionVar&amp;quot; value=&amp;quot;sessionValue&amp;quot;/&amp;gt;&lt;br /&gt;&amp;lt;c:set scope=&amp;quot;request&amp;quot; var=&amp;quot;requestVar&amp;quot; value=&amp;quot;requestValue&amp;quot;/&amp;gt;&lt;br /&gt;This is my function .....&lt;br /&gt;&lt;b&gt;${fnt:debugPage(pageContext)}&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;&amp;lt;/body&amp;gt;&lt;br /&gt;&amp;lt;/html&amp;gt;&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Many times we get so caught up in the latest widgets and technologies that we don't look at some of the basic things we can do to refactor out som complexity out of our views. Hopefully this is another tool to help you do that.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5782963451915595803-3519116145576917869?l=daneking.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://daneking.blogspot.com/feeds/3519116145576917869/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://daneking.blogspot.com/2009/11/keep-your-complexity-out-of-my-jsp-view.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5782963451915595803/posts/default/3519116145576917869'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5782963451915595803/posts/default/3519116145576917869'/><link rel='alternate' type='text/html' href='http://daneking.blogspot.com/2009/11/keep-your-complexity-out-of-my-jsp-view.html' title='Keep Your Complexity Out of My JSP View - JSP Functions'/><author><name>Dane</name><uri>http://www.blogger.com/profile/08190098834299132102</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5782963451915595803.post-2139046273150375600</id><published>2009-08-29T11:35:00.000-07:00</published><updated>2009-08-29T11:35:00.081-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='JSP'/><category scheme='http://www.blogger.com/atom/ns#' term='View'/><title type='text'>Keep Your Complexity Out of My JSP View - JavaBeans</title><content type='html'>&lt;style type="text/css"&gt;&lt;br /&gt;pre.source-code {&lt;br /&gt;  font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; &lt;br /&gt;  color: #000000;&lt;br /&gt;  background-color: #eee;&lt;br /&gt;  font-size: 12px;&lt;br /&gt;  border: 1px dashed #999999;&lt;br /&gt;  line-height: 14px;&lt;br /&gt;  padding: 5px;&lt;br /&gt;  overflow: auto;&lt;br /&gt;  width: 100%&lt;br /&gt;}&lt;br /&gt;&lt;/style&gt;&lt;br /&gt;&lt;br /&gt;Perhaps the most easiy understood of the view helper &lt;a href="http://java.sun.com/blueprints/corej2eepatterns/Patterns/ViewHelper.html"&gt;Core J2EE patterns&lt;/a&gt;  is the Javabean helper strategy. This one is fairly straight forward. Its also used by a variety of frameworks.&lt;div&gt;&lt;br /&gt;To get started first you need a java bean. I know the word has been overused, with EJB and similar technologies but what I'm refering to is what &lt;a href="http://www.stardeveloper.com/articles/display.html?article=2001071901&amp;amp;page=1"&gt;Faisal Khan describes&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;You need 3 things.&lt;br /&gt;1. Implements java.io.Serializable interface&lt;br /&gt;&lt;br /&gt;2. A no argument constructor - this comes by default unless you define another argument constructor. Then you have to explicitly declare one&lt;br /&gt;&lt;br /&gt;3. And provide getters and setters to properties&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;And here is the java code.&lt;br /&gt;&lt;pre class="source-code"&gt;&lt;code&gt;package viewhelper.javabeans;&lt;br /&gt;&lt;br /&gt;import java.io.Serializable;&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;pre class="source-code"&gt;&lt;code&gt;public class MySimpleBean implements Serializable {&lt;br /&gt;  private String propertyOne;&lt;br /&gt;  private Integer propertyTwo;&lt;br /&gt;&lt;br /&gt;  public String getPropertyOne() {&lt;br /&gt;      return propertyOne;&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  public void setPropertyOne(String propertyOne) {&lt;br /&gt;      this.propertyOne = propertyOne;&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  public Integer getPropertyTwo() {&lt;br /&gt;      return propertyTwo;&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  public void setPropertyTwo(Integer propertyTwo) {&lt;br /&gt;      this.propertyTwo = propertyTwo;&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  //I get the no argument default without declaring, but&lt;br /&gt;  //I have to explicitly declare if I have another argument constructor&lt;br /&gt;  public MySimpleBean() {&lt;br /&gt;      super();&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  public MySimpleBean(String propertyOne, Integer propertyTwo) {&lt;br /&gt;      super();&lt;br /&gt;      this.propertyOne = propertyOne;&lt;br /&gt;      this.propertyTwo = propertyTwo;&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Fairly simple code, right? And this is how we access it from the JSP page. Notice that we don't use getPropertyOne, but propertyOne. This is javabeans naming convention, if we name our methods in the java code (get + camel case method name), to access we drop the get or set and make the first letter lower case. &lt;br /&gt;&lt;br /&gt;&lt;pre class="source-code"&gt;&lt;code&gt;&amp;lt;html&amp;gt;&lt;br /&gt;&amp;lt;head&amp;gt;&lt;br /&gt;&amp;lt;title&amp;gt;Using the bean&amp;lt;/title&amp;gt;&lt;br /&gt;&amp;lt;/head&amp;gt;&lt;br /&gt;&amp;lt;body&amp;gt;&lt;br /&gt;&amp;lt;jsp:useBean id="beanHelper" scope="request"&lt;br /&gt; class="viewhelper.javabeans.MySimpleBean" &amp;gt;&lt;br /&gt;     &amp;lt;jsp:setProperty name="beanHelper" property="propertyOne" value="My Name"/&amp;gt;&lt;br /&gt;     &amp;lt;jsp:setProperty name="beanHelper" property="propertyTwo" value="10"/&amp;gt;&lt;br /&gt;  &amp;lt;/jsp:useBean&amp;gt;&lt;br /&gt; &amp;lt;h1&amp;gt;First Property ${beanHelper.propertyOne}&amp;lt;/h1&amp;gt;&lt;br /&gt; &amp;lt;h3&amp;gt;Second Property ${beanHelper.propertyTwo}&amp;lt;/h3&amp;gt;&lt;br /&gt;&amp;lt;/body&amp;gt;&lt;br /&gt;&amp;lt;/html&amp;gt;&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;pre class="source-code"&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;This is a simple example and really doesn't show all the benefits of using JavaBeans. They are really great if you have complex view preparation logic, maybe a custom sorting code or text transformations. The ultimate goal is to streamline the view so that JSP is strictly more of a template engine like it was designed to be. JavaBeans are just another tool to work towards that goal.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5782963451915595803-2139046273150375600?l=daneking.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://daneking.blogspot.com/feeds/2139046273150375600/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://daneking.blogspot.com/2009/08/keep-your-complexity-out-of-my-jsp-view_05.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5782963451915595803/posts/default/2139046273150375600'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5782963451915595803/posts/default/2139046273150375600'/><link rel='alternate' type='text/html' href='http://daneking.blogspot.com/2009/08/keep-your-complexity-out-of-my-jsp-view_05.html' title='Keep Your Complexity Out of My JSP View - JavaBeans'/><author><name>Dane</name><uri>http://www.blogger.com/profile/08190098834299132102</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5782963451915595803.post-165526390927927142</id><published>2009-08-06T03:07:00.000-07:00</published><updated>2009-08-06T05:11:48.782-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='JSP'/><category scheme='http://www.blogger.com/atom/ns#' term='View'/><title type='text'>Keep Your Complexity Out of My JSP View - JSP tags files</title><content type='html'>&lt;style type="text/css"&gt;&lt;br /&gt;pre.source-code {&lt;br /&gt;  font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; &lt;br /&gt;  color: #000000;&lt;br /&gt;  background-color: #eee;&lt;br /&gt;  font-size: 12px;&lt;br /&gt;  border: 1px dashed #999999;&lt;br /&gt;  line-height: 14px;&lt;br /&gt;  padding: 5px;&lt;br /&gt;  overflow: auto;&lt;br /&gt;  width: 100%&lt;br /&gt;}&lt;br /&gt;&lt;/style&gt;&lt;br /&gt;&lt;br /&gt;When I was writing &lt;a href="http://daneking.blogspot.com/2009/08/keep-your-complexity-out-of-my-view.html"&gt;a previous post&lt;/a&gt; I came across the notion of tag files. Some people don't like the notion of tlds and compiled Java files and find them too complex. Well in JSP 2.0 there is the ability to write tag files. This has been out for awhile and honestly I haven't seen it used in a production environment before. However it looks like could be very useful.&lt;br /&gt;&lt;br /&gt;OK we first need to create some files under WEB-INF, in this example I created a folder called tags and 2 tag files.&lt;br /&gt;&lt;b&gt;&lt;i&gt;stringTag.tag &lt;/i&gt;&lt;/b&gt;&lt;br /&gt;&lt;pre class="source-code"&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;&amp;lt;% &lt;br /&gt; String aString = &amp;quot;I am a String within a scriptlet&amp;quot;;&lt;br /&gt;%&amp;gt;&lt;br /&gt;&lt;br /&gt;Hello There,  &amp;lt;%= aString %&amp;gt;&lt;br /&gt;&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;and &lt;b&gt;&lt;i&gt;uppercase.tag&lt;/i&gt;&lt;/b&gt;&lt;br /&gt;&lt;pre class="source-code"&gt;&lt;code&gt;&amp;lt;jsp:doBody var=&amp;quot;body&amp;quot;/&amp;gt;&lt;br /&gt;Hey You!&lt;br /&gt;&amp;lt;br&amp;gt;&lt;br /&gt;&amp;lt;%&lt;br /&gt;String msg = (String) jspContext.getAttribute(&amp;quot;body&amp;quot;);&lt;br /&gt;%&amp;gt;&lt;br /&gt;&amp;lt;%= msg.toUpperCase() %&amp;gt;&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;And now the JSP that uses the tags.&lt;br /&gt;&lt;br /&gt;&lt;pre class="source-code"&gt;&lt;code&gt;&amp;lt;%@ page language=&amp;quot;java&amp;quot; contentType=&amp;quot;text/html; charset=ISO-8859-1&amp;quot;&lt;br /&gt;    pageEncoding=&amp;quot;ISO-8859-1&amp;quot;%&amp;gt;&lt;br /&gt;&amp;lt;%@ taglib prefix=&amp;quot;tags&amp;quot; tagdir=&amp;quot;/WEB-INF/tags&amp;quot; %&amp;gt;&lt;br /&gt;&amp;lt;%@ taglib uri=&amp;quot;/WEB-INF/tlds/mytags.tld&amp;quot; prefix=&amp;quot;mytag&amp;quot; %&amp;gt;&lt;br /&gt;&amp;lt;!DOCTYPE html PUBLIC &amp;quot;-//W3C//DTD HTML 4.01 Transitional//EN&amp;quot; &amp;quot;http://www.w3.org/TR/html4/loose.dtd&amp;quot;&amp;gt;&lt;br /&gt;&amp;lt;html&amp;gt;&lt;br /&gt;&amp;lt;head&amp;gt;&lt;br /&gt;&amp;lt;meta http-equiv=&amp;quot;Content-Type&amp;quot; content=&amp;quot;text/html; charset=ISO-8859-1&amp;quot;&amp;gt;&lt;br /&gt;&amp;lt;title&amp;gt;Insert title here&amp;lt;/title&amp;gt;&lt;br /&gt;&amp;lt;/head&amp;gt;&lt;br /&gt;&lt;br /&gt;&amp;lt;body&amp;gt;&lt;br /&gt;&lt;br /&gt;Wow, you can do that&lt;br /&gt;&amp;lt;br&amp;gt;&lt;br /&gt;&amp;lt;mytag:myfirsttag name=&amp;quot;what is my tag doing here&amp;quot;/&amp;gt;&lt;br /&gt;&lt;br /&gt;&amp;lt;tags:stringTag/&amp;gt;&lt;br /&gt;&amp;lt;br/&amp;gt;&lt;br /&gt;&amp;lt;tags:uppercase&amp;gt;&lt;br /&gt;I really want to be in capital letters.&lt;br /&gt;&amp;lt;/tags:uppercase&amp;gt;&lt;br /&gt;&lt;br /&gt;&amp;lt;/body&amp;gt;&lt;br /&gt;&amp;lt;/html&amp;gt;&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;We can also have attributes passed to the tag to allow us to change the behavior appearance here is &lt;br /&gt;&lt;b&gt;&lt;i&gt;new_uppercase.tag&lt;/i&gt;&lt;/b&gt;&lt;br /&gt;Notice also that you can use EL to streamline your tags&lt;br /&gt;&lt;br /&gt;&lt;pre class="source-code"&gt;&lt;code&gt;&amp;lt;%@attribute name=&amp;quot;size&amp;quot; required=&amp;quot;true&amp;quot;  %&amp;gt;&lt;br /&gt;&amp;lt;font size=&amp;quot;${pageScope.size}&amp;quot;&amp;gt;&lt;br /&gt;    &amp;lt;jsp:doBody/&amp;gt;&lt;br /&gt;&amp;lt;/font&amp;gt;&lt;br /&gt;&amp;lt;/div&amp;gt;&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;and adding it to the JSP, , I bolded the lines I added from the previous JSP&lt;br /&gt;&lt;br /&gt;&lt;pre class="source-code"&gt;&lt;code&gt;&amp;lt;%@ page language=&amp;quot;java&amp;quot; contentType=&amp;quot;text/html; charset=ISO-8859-1&amp;quot;&lt;br /&gt;    pageEncoding=&amp;quot;ISO-8859-1&amp;quot;%&amp;gt;&lt;br /&gt;&amp;lt;%@ taglib prefix=&amp;quot;tags&amp;quot; tagdir=&amp;quot;/WEB-INF/tags&amp;quot; %&amp;gt;&lt;br /&gt;&amp;lt;%@ taglib uri=&amp;quot;/WEB-INF/tlds/mytags.tld&amp;quot; prefix=&amp;quot;mytag&amp;quot; %&amp;gt;&lt;br /&gt;&amp;lt;!DOCTYPE html PUBLIC &amp;quot;-//W3C//DTD HTML 4.01 Transitional//EN&amp;quot; &amp;quot;http://www.w3.org/TR/html4/loose.dtd&amp;quot;&amp;gt;&lt;br /&gt;&amp;lt;html&amp;gt;&lt;br /&gt;&amp;lt;head&amp;gt;&lt;br /&gt;&amp;lt;meta http-equiv=&amp;quot;Content-Type&amp;quot; content=&amp;quot;text/html; charset=ISO-8859-1&amp;quot;&amp;gt;&lt;br /&gt;&amp;lt;title&amp;gt;Insert title here&amp;lt;/title&amp;gt;&lt;br /&gt;&amp;lt;/head&amp;gt;&lt;br /&gt;&lt;br /&gt;&amp;lt;body&amp;gt;&lt;br /&gt;Wow, you can do that&lt;br /&gt;&amp;lt;br&amp;gt;&lt;br /&gt;&amp;lt;mytag:myfirsttag name=&amp;quot;what is my tag doing here&amp;quot;/&amp;gt;&lt;br /&gt;&lt;br /&gt;&amp;lt;tags:stringTag/&amp;gt;&lt;br /&gt;&amp;lt;br/&amp;gt;&lt;br /&gt;&amp;lt;tags:uppercase&amp;gt;&lt;br /&gt;I really want to be in capital letters.&lt;br /&gt;&amp;lt;/tags:uppercase&amp;gt;&lt;br /&gt;&lt;br /&gt;&amp;lt;br&amp;gt;&lt;br /&gt;&lt;b&gt;&lt;br /&gt;&amp;lt;tags:new_uppercase size=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;Really I do&lt;br /&gt;&amp;lt;/tags:new_uppercase&amp;gt;&lt;br /&gt;&lt;/b&gt;&lt;br /&gt;&amp;lt;br&amp;gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;&lt;br /&gt;&amp;lt;tags:new_uppercase size=&amp;quot;15&amp;quot;&amp;gt;&lt;br /&gt;I said really I do &lt;br /&gt;&amp;lt;/tags:new_uppercase&amp;gt;&lt;br /&gt;&lt;/b&gt;&lt;br /&gt;&amp;lt;/body&amp;gt;&lt;br /&gt;&amp;lt;/html&amp;gt;&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;I haven't worked out all the details here, like how does a tag within a tag behave. It seems to work, but what happens if you redefine a html attribute, what is the order that the nested tags fire, etc. I want to look at this a little further and I'll post what I learn. &lt;br /&gt;&lt;br /&gt;If you want to read more, I took these from the J2EE blue patterns site, This pattern is called &lt;a href="http://java.sun.com/blueprints/corej2eepatterns/Patterns/ViewHelper.html"&gt;JSP View Helper Strategy&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Here is a &lt;a href="http://articles.techrepublic.com.com/5100-10878_11-5215024.html"&gt;post &lt;/a&gt;on getting started that is more detailed than what I covered.&lt;br /&gt;&lt;br /&gt;Look at the comments on this post, some of the people make good &lt;a href="http://weblogs.java.net/blog/jfalkner/archive/2005/05/blarg_14_why_cu.html"&gt;arguments&lt;/a&gt; about when to use tag files.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5782963451915595803-165526390927927142?l=daneking.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://daneking.blogspot.com/feeds/165526390927927142/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://daneking.blogspot.com/2009/08/keep-your-complexity-out-of-my-jsp-view.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5782963451915595803/posts/default/165526390927927142'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5782963451915595803/posts/default/165526390927927142'/><link rel='alternate' type='text/html' href='http://daneking.blogspot.com/2009/08/keep-your-complexity-out-of-my-jsp-view.html' title='Keep Your Complexity Out of My JSP View - JSP tags files'/><author><name>Dane</name><uri>http://www.blogger.com/profile/08190098834299132102</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5782963451915595803.post-4556629748984135182</id><published>2009-08-01T06:08:00.000-07:00</published><updated>2009-08-06T03:07:37.997-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='JSP'/><category scheme='http://www.blogger.com/atom/ns#' term='View'/><title type='text'>Keep Your Complexity Out of My JSP View</title><content type='html'>&lt;span style="font-family: -webkit-monospace; font-size: 13px; white-space: pre;"&gt;&lt;style type="text/css"&gt;pre.source-code {  font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace;   color: #000000;  background-color: #eee;  font-size: 12px;  border: 1px dashed #999999;  line-height: 14px;  padding: 5px;  overflow: auto;  width: 100%}&lt;/style&gt;&lt;/span&gt;&lt;br /&gt;As a web developer I spend way too much of my time tracking down defects in the UI. Many of these involve big complex pieces of business logic that represent untested code or complex pieces of html. As a result I'm always trying to find ways to get some of that complexity out of the view layer. This is often the advice other people give you, keep your view simple. What they don't offer are some ways to actually do it.&lt;br /&gt;&lt;br /&gt;One way we can get some of that logic out of our html pages is JSP tags. I don't see this used very&amp;nbsp;often, but it can provide a clean separation between your code and your html and allows you to introduce some unit testing. &amp;nbsp;That's not to say you can't have html code in your JSP tags, the article on &lt;a href="http://www.javaworld.com/javaworld/jw-11-2001/jw-1130-jsp.html"&gt;best practices&lt;/a&gt;&amp;nbsp;is OK with this. They make 2 points, one is that the tag is a custom tag, &amp;nbsp;with the key word being custom, so its only useful to a specific page, if you want to generalize some code they suggest some kind of helper class. Secondly, they say that it's better to have html in your Java than Java code in your JSP. I kind of agree with that, however this should be done carefully, the current project I'm on has a custom button tag that everyone avoids because it has alot of table html and css code in it. It tends to break when we use it with frameworks such as ExtJs that use alot of divs, and it is very difficult to get it positioned properly.&lt;br /&gt;&lt;br /&gt;OK, time to code, the first step is to create our tld file. It should look something like below. Make sure you follow the format for the correct &lt;a href="http://dtddoc.sourceforge.net/example/j2ee131/web-jsptaglibrary_1_2.dtd.html"&gt;DTD&lt;/a&gt;. Now save it in your WEB-INF directory, I created a folder called tlds and created a file named mytags.tld. We also declare any attributes we want to use, I created one called name. I also can make it required if I want, by changing the required tag to true.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre class="source-code"&gt;&lt;code&gt;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;ISO-8859-1&amp;quot; ?&amp;gt;&lt;br /&gt;&amp;lt;!DOCTYPE taglib&lt;br /&gt;        PUBLIC &amp;quot;-//Sun Microsystems, Inc.//DTD JSP Tag Library 1.2//EN&amp;quot;&lt;br /&gt;    &amp;quot;http://java.sun.com/j2ee/dtd/web-jsptaglibrary_1_2.dtd&amp;quot;&amp;gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&amp;lt;taglib&amp;gt; &lt;br /&gt;    &amp;lt;tlib-version&amp;gt;1.0&amp;lt;/tlib-version&amp;gt; &lt;br /&gt;    &amp;lt;jsp-version&amp;gt;1.2&amp;lt;/jsp-version&amp;gt;&lt;br /&gt;    &amp;lt;short-name&amp;gt;HelloWorldTags&amp;lt;/short-name&amp;gt;&lt;br /&gt;    &amp;lt;uri&amp;gt;http://daneking.blogspot.com&amp;lt;/uri&amp;gt;&lt;br /&gt;    &amp;lt;description&amp;gt;A simple tag &amp;lt;/description&amp;gt;&lt;br /&gt;    &amp;lt;tag&amp;gt; &lt;br /&gt;        &amp;lt;name&amp;gt;myfirsttag&amp;lt;/name&amp;gt; &lt;br /&gt;        &amp;lt;tag-class&amp;gt;com.mytags.MyCustomTag&amp;lt;/tag-class&amp;gt;&lt;br /&gt;        &amp;lt;body-content&amp;gt;empty&amp;lt;/body-content&amp;gt;&lt;br /&gt;        &amp;lt;description&amp;gt;Your first JSP Tag&amp;lt;/description&amp;gt; &lt;br /&gt;        &amp;lt;attribute&amp;gt;&lt;br /&gt;            &amp;lt;name&amp;gt;name&amp;lt;/name&amp;gt;&lt;br /&gt;            &amp;lt;required&amp;gt;false&amp;lt;/required&amp;gt;&lt;br /&gt;        &amp;lt;/attribute&amp;gt;&lt;br /&gt;    &amp;lt;/tag&amp;gt; &lt;br /&gt;&amp;lt;/taglib&amp;gt;&lt;br /&gt;&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;Now we have to declare it in the JSP. Notice the bold lines, the first bolded line is the import and the second bolded line is where I use the tag. I also pass the value "what is my tag doing" as the name attribute that I declared in the tld file above.&lt;br /&gt;&lt;br /&gt;&lt;pre class="source-code"&gt;&lt;code&gt;&amp;lt;%@ page language=&amp;quot;java&amp;quot; contentType=&amp;quot;text/html; charset=ISO-8859-1&amp;quot;&lt;br /&gt;    pageEncoding=&amp;quot;ISO-8859-1&amp;quot;%&amp;gt;&lt;br /&gt;&lt;b&gt;&lt;br /&gt;&amp;lt;%@ taglib uri=&amp;quot;/WEB-INF/tlds/mytags.tld&amp;quot; prefix=&amp;quot;mytag&amp;quot; %&amp;gt;&lt;br /&gt;&lt;/b&gt;&lt;br /&gt;&amp;lt;%@ taglib prefix=&amp;quot;tags&amp;quot; tagdir=&amp;quot;/WEB-INF/tags&amp;quot; %&amp;gt;    &lt;br /&gt;&amp;lt;!DOCTYPE html PUBLIC &amp;quot;-//W3C//DTD HTML 4.01 Transitional//EN&amp;quot; &amp;quot;http://www.w3.org/TR/html4/loose.dtd&amp;quot;&amp;gt;&lt;br /&gt;&amp;lt;html&amp;gt;&lt;br /&gt;&amp;lt;head&amp;gt;&lt;br /&gt;&amp;lt;meta http-equiv=&amp;quot;Content-Type&amp;quot; content=&amp;quot;text/html; charset=ISO-8859-1&amp;quot;&amp;gt;&lt;br /&gt;&amp;lt;title&amp;gt;Insert title here&amp;lt;/title&amp;gt;&lt;br /&gt;&amp;lt;/head&amp;gt;&lt;br /&gt;&amp;lt;body&amp;gt;&lt;br /&gt;Wow, you can do that&amp;lt;br&amp;gt;&lt;br /&gt;&lt;b&gt;&lt;br /&gt;&amp;lt;mytag:myfirsttag name=&amp;quot;what is my tag doing&amp;quot;/&amp;gt;&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;&amp;lt;/body&amp;gt;&lt;br /&gt;&amp;lt;/html&amp;gt;&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;Now for the Java code. I downloaded the &lt;a href="http://tomcat.apache.org/download-60.cgi"&gt;Tomcat 6.0 source code&lt;/a&gt; and looked at the tags that were available. I decided to keep it simple and use the implementation of SimpleTag called SimpleTagSupport. It already has alot of the trivial getters and setters implemented. So I only needed to override the method I was interested in. I'm using Apache Commons WordUtils to capitalize the words. So if you're following along add &lt;a href="http://commons.apache.org/downloads/download_lang.cgi"&gt;commons-lang-2.4.jar&lt;/a&gt; and add it to your web library. Eclipse EE users can add a &lt;a href="http://draft.blogger.com/://dev.eclipse.org/newslists/news.eclipse.webtools/msg11326."&gt;J2EE Module Dependency&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre class="source-code"&gt;&lt;code&gt;package com.mytags;&lt;br /&gt;&lt;br /&gt;import java.io.IOException;&lt;br /&gt;&lt;br /&gt;import javax.servlet.jsp.JspException;&lt;br /&gt;import javax.servlet.jsp.tagext.SimpleTagSupport;&lt;br /&gt;&lt;br /&gt;import org.apache.commons.lang.WordUtils;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;public class MyCustomTag extends SimpleTagSupport  {&lt;br /&gt;    private String name;&lt;br /&gt;    &lt;br /&gt;    public String getName() {&lt;br /&gt;        return name;&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    public void setName(String name) {&lt;br /&gt;        this.name = WordUtils.capitalizeFully(name);&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    @Override&lt;br /&gt;    public void doTag() throws JspException, IOException {&lt;br /&gt;        super.doTag();&lt;br /&gt;        getJspContext().getOut().print(&amp;quot;Hello There&amp;lt;br&amp;gt;&amp;quot;);&lt;br /&gt;        getJspContext().getOut().print(name);&lt;br /&gt;    }&lt;br /&gt;    &lt;br /&gt;    &lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;And of course the test.&lt;br /&gt;&lt;pre class="source-code"&gt;&lt;code&gt;package com.mytags;&lt;br /&gt;&lt;br /&gt;import java.io.IOException;&lt;br /&gt;&lt;br /&gt;import javax.servlet.jsp.JspException;&lt;br /&gt;import javax.servlet.jsp.tagext.SimpleTagSupport;&lt;br /&gt;&lt;br /&gt;import org.apache.commons.lang.WordUtils;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;public class MyCustomTag extends SimpleTagSupport  {&lt;br /&gt;    private String name;&lt;br /&gt;    &lt;br /&gt;    public String getName() {&lt;br /&gt;        return name;&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    public void setName(String name) {&lt;br /&gt;        this.name = WordUtils.capitalizeFully(name);&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    @Override&lt;br /&gt;    public void doTag() throws JspException, IOException {&lt;br /&gt;        super.doTag();&lt;br /&gt;        getJspContext().getOut().print(&amp;quot;Hello There&amp;lt;br&amp;gt;&amp;quot;);&lt;br /&gt;        getJspContext().getOut().print(name);&lt;br /&gt;    }&lt;br /&gt;    &lt;br /&gt;    &lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;I know this is a trivial example, but if you need some complex html code, especially things like looping this would be an ideal solution. You could also send in attributes such as the style sheet or html templates to further abstract the html from the code.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5782963451915595803-4556629748984135182?l=daneking.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://daneking.blogspot.com/feeds/4556629748984135182/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://daneking.blogspot.com/2009/08/keep-your-complexity-out-of-my-view.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5782963451915595803/posts/default/4556629748984135182'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5782963451915595803/posts/default/4556629748984135182'/><link rel='alternate' type='text/html' href='http://daneking.blogspot.com/2009/08/keep-your-complexity-out-of-my-view.html' title='Keep Your Complexity Out of My JSP View'/><author><name>Dane</name><uri>http://www.blogger.com/profile/08190098834299132102</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5782963451915595803.post-8060099017517739678</id><published>2009-07-24T04:18:00.000-07:00</published><updated>2009-07-29T10:03:18.284-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Testing'/><category scheme='http://www.blogger.com/atom/ns#' term='Design'/><title type='text'>Keep Your Privates Private</title><content type='html'>&lt;div&gt;On my current project,  some developers discovered that they could test private methods using reflection.  I asserted my opinion(which of course rarely happens) that we shouldn't be testing private methods. My point was that my public methods are my interface to let others know how to use my class. My tests are a verification of that contract. If something changes to break that contract it will let me know. Its sort of a contract on a contract. So after a lively discussion about it, I did some research (I googled) and found that there is indeed some debate on the matter. &lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;Instead of rehashing that debate, I would like to add another view,  that once developers can test private methods, they do it without thinking of alternatives.  I never say never, so I'm not totally against the idea of testing these private methods, but it just feels wrong.  I think once developers have a test around a complex method they stop. My mantra is if its hard to test, then something is wrong with your design.&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;The methods I have seen with private methods tested usually have some side effects. They are changing class level variables or the arguments of the method without any return values. Sometime they are just encapsulating some complex behavior that should moved into another class. &lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;Test Driven Development (TDD) is not so much about testability but about designing for testability. A application that is redesigned to be easily testable is an application with less coupling, more focused objects and less side effects of the methods.&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;I realize that with the pressures of deadlines and legacy code, its not always possible to refactor and testing private methods could be a solution to get more test coverage. I just think we should first try to refactor and only if that isn't feasible should we test private methods.&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;If  you do find that you must test private methods, &lt;a href="http://www.artima.com/suiterunner/private2.html"&gt;Bill Venners&lt;/a&gt; has a good article on testing private methods, I particularly like his translating the reflection exceptions into assert exceptions. He also has a good example of the kind of private methods that are hard to test. &lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5782963451915595803-8060099017517739678?l=daneking.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://daneking.blogspot.com/feeds/8060099017517739678/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://daneking.blogspot.com/2009/07/keep-your-privates-private.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5782963451915595803/posts/default/8060099017517739678'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5782963451915595803/posts/default/8060099017517739678'/><link rel='alternate' type='text/html' href='http://daneking.blogspot.com/2009/07/keep-your-privates-private.html' title='Keep Your Privates Private'/><author><name>Dane</name><uri>http://www.blogger.com/profile/08190098834299132102</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5782963451915595803.post-6697032865963642720</id><published>2009-07-21T04:24:00.000-07:00</published><updated>2009-07-29T10:03:46.746-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Professional Development'/><title type='text'>Always Something to Learn</title><content type='html'>&lt;span class="Apple-style-span"  style=" border-collapse: collapse; color: rgb(50, 29, 2); font-family:georgia;"&gt;&lt;i&gt;I am always ready to learn although I do not always like being taught.  ~Winston Churchill&lt;/i&gt;&lt;br /&gt;&lt;/span&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="color:#321D02;"&gt;&lt;span class="Apple-style-span" style="border-collapse: collapse;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="color:#321D02;"&gt;&lt;span class="Apple-style-span" style="border-collapse: collapse;"&gt;I'm always surprised at the number of people in the software industry that don't strive to learn. Programmers that brag that they don't touch a computer at home or read a computer book. A programmer that doesn't like to learn is like a doctor that doesn't like the sight of blood. I think that with a constant barrage of new frameworks, technologies and the pressures of deadlines we not only should always be learning something new, but its a necessary part of our job. &lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="color:#321D02;"&gt;&lt;span class="Apple-style-span" style="border-collapse: collapse;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="color:#321D02;"&gt;&lt;span class="Apple-style-span" style="border-collapse: collapse;"&gt;I understand it's not always useful to learn Widget 0.9 framework that will be obsolute when TheNextBigThing 1.2 comes out.  But that's not an excuse to then not learn anything. There are still many things to learn to make you more productive.&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="color:#321D02;"&gt;&lt;span class="Apple-style-span" style="border-collapse: collapse;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="color:#321D02;"&gt;&lt;span class="Apple-style-span" style="border-collapse: collapse;"&gt;What about the programming language you use, are you up on the latest features? What about just basic programming techniques? Reading code from open source projects or the the code of the language itself if possible is a great way to learn.  &lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="color:#321D02;"&gt;&lt;span class="Apple-style-span" style="border-collapse: collapse;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="color:#321D02;"&gt;&lt;span class="Apple-style-span" style="border-collapse: collapse;"&gt;What about testing your code or learning different programming methodologies? What about your IDE of choice, do you know all the shortcuts and plugins that can help you? &lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="color:#321D02;"&gt;&lt;span class="Apple-style-span" style="border-collapse: collapse;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="color:#321D02;"&gt;&lt;span class="Apple-style-span" style="border-collapse: collapse;"&gt;Learning shouldn't be an either/or proposition. It should be more of a Return on Investment (ROI), if I invest (x) hours, I should be able to save (y) time. I find that learning time tested concepts give me more bang for the buck than learning the latest framework or technology.  Also a better understanding of the concepts makes working with the frameworks easier. &lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="color:#321D02;"&gt;&lt;span class="Apple-style-span" style="border-collapse: collapse;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="color:#321D02;"&gt;&lt;span class="Apple-style-span" style="border-collapse: collapse;"&gt;Topics like testing, refactoring and design patterns seem to stay around longer. Also the books for these topics can be found fairly cheap in used, but like new condition on Amazon or Alibris, or if your lucky at you're local Half price bookstore. &lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="color:#321D02;"&gt;&lt;span class="Apple-style-span" style="border-collapse: collapse;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="color:#321D02;"&gt;&lt;span class="Apple-style-span" style="border-collapse: collapse;"&gt;The shelf life for a developers knowledge is extremely short, however if we concentrate on concepts that are time tested, ones that have been around for awhile, and topics that make us more productive, we should be able to maximize our learning and be more professional in our jobs.&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="color:#321D02;"&gt;&lt;span class="Apple-style-span" style="border-collapse: collapse;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="color:#321D02;"&gt;&lt;span class="Apple-style-span" style="border-collapse: collapse;"&gt;By the way, I put together an Amazon &lt;a href="http://www.amazon.com/gp/richpub/listmania/fullview/R3MQYNGKVVSJY9/ref=cm_lm_pthnk_view?ie=UTF8&amp;amp;lm_bb="&gt;list &lt;/a&gt;of some of the books I have enjoyed that haven't "depreciated" over time.&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="color:#321D02;"&gt;&lt;span class="Apple-style-span" style="border-collapse: collapse;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5782963451915595803-6697032865963642720?l=daneking.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://daneking.blogspot.com/feeds/6697032865963642720/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://daneking.blogspot.com/2009/07/always-something-to-learn.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5782963451915595803/posts/default/6697032865963642720'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5782963451915595803/posts/default/6697032865963642720'/><link rel='alternate' type='text/html' href='http://daneking.blogspot.com/2009/07/always-something-to-learn.html' title='Always Something to Learn'/><author><name>Dane</name><uri>http://www.blogger.com/profile/08190098834299132102</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5782963451915595803.post-815641362902032305</id><published>2009-07-01T00:00:00.000-07:00</published><updated>2010-02-16T05:10:30.934-08:00</updated><title type='text'>Re-Finding Tools in My Toolbox</title><content type='html'>As developers, especially Java developers, we are always looking for the next big thing. I like nice new shiny things as much as the next programmer, but I think its extremely valuable to learn the what our basic tools can do. We don't seem to study the basics anymore like Java, HTML, JSTL, JSP. I started this blog as a way to go back and make sure that I know the fundamentals of what I'm doing before I reach for another tool to solve my problem. Who knows I just might already have the tool in my toolbox.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5782963451915595803-815641362902032305?l=daneking.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://daneking.blogspot.com/feeds/815641362902032305/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://daneking.blogspot.com/2009/07/re-finding-tools-in-my-toolbox.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5782963451915595803/posts/default/815641362902032305'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5782963451915595803/posts/default/815641362902032305'/><link rel='alternate' type='text/html' href='http://daneking.blogspot.com/2009/07/re-finding-tools-in-my-toolbox.html' title='Re-Finding Tools in My Toolbox'/><author><name>Dane</name><uri>http://www.blogger.com/profile/08190098834299132102</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry></feed>
