<?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-8386036339756925674</id><updated>2011-07-07T20:15:10.621-07:00</updated><title type='text'>TofuBeer</title><subtitle type='html'></subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://tofubeer.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8386036339756925674/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://tofubeer.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>TofuBeer</name><uri>http://www.blogger.com/profile/17555313388131451916</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/_x_xRpNcK438/Sz_AD0IUa5I/AAAAAAAAAAM/Xq9ClBTP-fE/S220/duke.png'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>15</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-8386036339756925674.post-4127418614129390438</id><published>2010-04-12T11:39:00.000-07:00</published><updated>2010-04-12T11:39:17.778-07:00</updated><title type='text'>Die Flash Die</title><content type='html'>(yeah, yeah, not the proper type of title, but not a "regular" post either, also I'll throw in that these are my personal thoughts and do not represent those of the company I work for :-) (did you know someone once tried to get me fired when I worked at Symantec for suggesting that they should not ask other people on Usenet to do their homework for them?!))&lt;br /&gt;&lt;br /&gt;Recently, as you probably know, Apple released the beta version of the iPhone SDK with new terms stating that, in essence, for non web-based apps, you could only use C/C++/Objective-C.&amp;nbsp; This shuts out the upcoming Adobe product that compiles Flash to an iPhone app, as well as other things like MonoTouch.&lt;br /&gt;&lt;br /&gt;For years I searched for a language that I liked that was cross platform:&lt;br /&gt;&lt;br /&gt;- C sort of is, as long as you are careful about sizes of data types.&lt;br /&gt;- C++ is the same as C, but when I was doing it less so since the compilers were all over the map with their support.&amp;nbsp; Also C++ is a pretty large language and you get to remember a lot of special cases.&amp;nbsp; I don't like special cases.&lt;br /&gt;- Java was as close as I could get, and I have been using in since 1.0 Alpha 2, back in 1995 (so coming up on 15 years).&lt;br /&gt;&lt;br /&gt;Doing iPhone development you really need to learn Objective-C.&amp;nbsp; Every time I looked at Objective-C I would shudder.&amp;nbsp; It is NOT a natural extension of C.&amp;nbsp; C++ is a natural extension of C.&amp;nbsp; Objective-C is some whacked out thing.&amp;nbsp; That being said I sat down with a &lt;a href="http://bit.ly/bP1Sfc" rel="http://bit.ly/plugins/iframe?hashUrl=http%3A%2F%2Fbit.ly%2FbP1Sfc"&gt;book&lt;/a&gt; or &lt;a href="http://bit.ly/ccVqvC" rel="http://bit.ly/plugins/iframe?hashUrl=http%3A%2F%2Fbit.ly%2FccVqvC"&gt;two&lt;/a&gt; or &lt;a href="http://bit.ly/9zTgTP" rel="http://bit.ly/plugins/iframe?hashUrl=http%3A%2F%2Fbit.ly%2F9zTgTP"&gt;three&lt;/a&gt; and learned what I needed to.&lt;br /&gt;&lt;br /&gt;Back in school we had a C++ course, sadly the instructor didn't know the language (was too new) and he focused on teaching us some pretty useless things.&amp;nbsp; Once I finished school I taught myself C++ and did a pretty decent job learning what I needed to.&amp;nbsp; When Java came out it tool me a about 1 day to learn the syntax, a week to get comfortable in the language, and about a month to understand the libraries (I would say it would take me 6 months to do all of that if I started now since Java has gotten a lot larger).&lt;br /&gt;&lt;br /&gt;Objecticve-C took me about 1 week until I no longer needed to look at the book to write each line of code.&amp;nbsp; Fortunate for me I was exposed to Smalltalk in school and Objective-C has a lot of smalltalk ideas.&amp;nbsp; Once I clued into that it was easier.&lt;br /&gt;&lt;br /&gt;I have never looked at developing anything in Flash.&amp;nbsp; I don't want to develop anything in Flash.&amp;nbsp; I have Flash disabled in my browser because the last thing I care to see is moving advertisements.&amp;nbsp; Most Flash games I have seen are "neat" but not "wow cool!".&amp;nbsp; And there are some sites out there, such as the Lego site, that I cannot see most of the things on when using my iPhone since it is flash based (sucks when you have an 8 year old and you cannot go to the Lego site!).&lt;br /&gt;&lt;br /&gt;So Flash is used for:&lt;br /&gt;1) website navigation when it doesn't add value, and companies are too lazy to develop something people without Flash can see&lt;br /&gt;2) advertisements&lt;br /&gt;3) simple games&lt;br /&gt;4) videos&lt;br /&gt;&lt;br /&gt;Why on earth does Flash exist then?&amp;nbsp; The websites would be better off in HTML.&amp;nbsp; I never look at ads (since they are blocked), if I want to play a game I do it for an&amp;nbsp; immersive experience, and for Videos, well there are better alternatives than Flash (see &lt;a href="http://bit.ly/agngsf" rel="http://bit.ly/plugins/iframe?hashUrl=http%3A%2F%2Fbit.ly%2Fagngsf"&gt;HTML5&lt;/a&gt;).&lt;br /&gt;&lt;br /&gt;More importantly, do I want those people able to easily write things for anything I am on?&amp;nbsp; My answer is Hell No!&lt;br /&gt;&lt;br /&gt;Also, there are technical merits for Apple to do what they are doing (though I am sure developer locking is what they are really after):&lt;br /&gt;&lt;br /&gt;- say the iPhone didn't have a camera.&amp;nbsp; So Flash/MonoTouch/Whatever doesn't have anything for a camera.&lt;br /&gt;- now a new iPhone is released with a camera and Apple adds a number of camera APIs.&lt;br /&gt;- Flash/MonoTouch/whatever are slow to support the camera.&lt;br /&gt;&lt;br /&gt;Now you have the case where other companies are controlling what can happen on Apples platform.&amp;nbsp; That doesn't make for a good user experience.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;If you are a Flash developer and you are complaining about Apple because you are too lazy to go and learn C/C++/ObjectiveC this is what I hear:&lt;br /&gt;&lt;br /&gt;&lt;object height="385" width="480"&gt;&lt;param name="movie" value="http://www.youtube.com/v/myS9qKIFAN8&amp;hl=en_GB&amp;fs=1&amp;"&gt;&lt;/param&gt;&lt;param name="allowFullScreen" value="true"&gt;&lt;/param&gt;&lt;param name="allowscriptaccess" value="always"&gt;&lt;/param&gt;&lt;embed src="http://www.youtube.com/v/myS9qKIFAN8&amp;hl=en_GB&amp;fs=1&amp;" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="480" height="385"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;br /&gt;&lt;br /&gt;To the Adobe Flash Evangelist, as the former Symantec Java Evangelist, instead of telling Apple to "&lt;a bitly="BITLY_PROCESSED" href="http://theflashblog.com/?p=1888"&gt;Go screw [itself]&lt;/a&gt;" I think you should do this instead:&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;object height="385" width="480"&gt;&lt;param name="movie" value="http://www.youtube.com/v/-8Up4tLSXhM&amp;hl=en_GB&amp;fs=1&amp;"&gt;&lt;/param&gt;&lt;param name="allowFullScreen" value="true"&gt;&lt;/param&gt;&lt;param name="allowscriptaccess" value="always"&gt;&lt;/param&gt;&lt;embed src="http://www.youtube.com/v/-8Up4tLSXhM&amp;hl=en_GB&amp;fs=1&amp;" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="480" height="385"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;br /&gt;&lt;br /&gt;(And, yes, I know the videos are in Flash, and no, the irony is not lost on me...)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8386036339756925674-4127418614129390438?l=tofubeer.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://tofubeer.blogspot.com/feeds/4127418614129390438/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://tofubeer.blogspot.com/2010/04/die-flash-die.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8386036339756925674/posts/default/4127418614129390438'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8386036339756925674/posts/default/4127418614129390438'/><link rel='alternate' type='text/html' href='http://tofubeer.blogspot.com/2010/04/die-flash-die.html' title='Die Flash Die'/><author><name>TofuBeer</name><uri>http://www.blogger.com/profile/17555313388131451916</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/_x_xRpNcK438/Sz_AD0IUa5I/AAAAAAAAAAM/Xq9ClBTP-fE/S220/duke.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8386036339756925674.post-1981073941487496411</id><published>2010-03-18T12:59:00.000-07:00</published><updated>2010-03-18T12:59:27.721-07:00</updated><title type='text'>Another Brick in the Wall: Part 1 (Software Design, Part 1)</title><content type='html'>A while ago Judy asked me for the names of books I would recommend for programmers.&amp;nbsp; One of them isn't your typical book, and for me it is more of a guiding philosophy than anything.&amp;nbsp; It is the ISO OSI or the International Organization for Standardization Open System Interconnection Reference Model, also known as the OSI Seven Layer Model (yeah, I know the acronym and the words don't match.... google it!)&lt;br /&gt;&lt;br /&gt;The brief background on it is that a long time ago (the '70s) in galaxy far far away (well not too far actually, given it all happened on Earth) the ISO wanted to come up with a standard way of dealing with computer networks.&amp;nbsp; To do this they came up with seven layers (remember up above it is called the Seven Layer Model) that could be swapped out with different implementations.&lt;br /&gt;&lt;br /&gt;The seven layers are (top to bottom):&lt;br /&gt;&lt;br /&gt;Application - What the user interacts with&lt;br /&gt;Presentation - data formatting, like encryption&lt;br /&gt;Session - computer to computer handling, such as remote procedure calls&lt;br /&gt;Transport - data transfer between computers&lt;br /&gt;Network - routing between networks&lt;br /&gt;Datalink - low level data transfer, including things like error detection&lt;br /&gt;Physical - the actual device that sends the data&lt;br /&gt;&lt;br /&gt;While this model isn't really used in practice (TCP/IP is instead, which only has 4 layers) the concept is very powerful.&amp;nbsp; The whole idea is that you can swap out any given layer with a different implementation and it will not change any of the other layers.&amp;nbsp; For example you could swap out the encryption (presentation layer) without having to make any changes to the layers around it (Application or Session).&amp;nbsp; The reason why that works is that each layer is only allowed to talk to the immediate neighbours (for example Transport can only talk to Session and Network).&lt;br /&gt;&lt;br /&gt;So if we don't use something from the '70s then why on earth am I writing about it?&amp;nbsp; Well, IMNSHO, it is the best way to write software, and the principles that it embodies are very powerful.&lt;br /&gt;&lt;br /&gt;A common way to talk about Object Oriented programming a few years ago was the idea of "Software Integrated Circuits" which borrowed ideas from hardware where you could have off the shelf components that you just plug together to make software.&amp;nbsp; To do that, each piece (class) must have a well defined interface (API - essentially the public methods).&amp;nbsp; That sort of sounds like something the the OSI model would need doesn't it? &lt;br /&gt;&lt;br /&gt;The next step is to group the classes into functionality, which makes the layers.&amp;nbsp; For example, in the current application we are writing we have two sets of "layer" classes:&lt;br /&gt;&lt;br /&gt;- Database&lt;br /&gt;- DataSource&lt;br /&gt;&lt;br /&gt;The Database class takes care of all of the database access.&amp;nbsp; It has some sub-packages that it talks to that do the low level work while it provides a nice abstraction.&amp;nbsp; Any code that wants to talk to the database must go through the Database class and not make direct use of any of the classes in the subpackage.&lt;br /&gt;&lt;br /&gt;The exact same idea us used for the DataSource class which takes care of the network communication with the servers we are pulling data from.&amp;nbsp; Each REST API call we make to a server has a single method in the DataSource class.&lt;br /&gt;&lt;br /&gt;To make things testable the Database and DataSource types are interfaces.&amp;nbsp; This means we can substitute the "NetworkedDataSource" for the "DatabaseDataSource" and pull all of the data from a database instead of from live servers for testing (put the expected data into the database and have the DatabaseDataSource return that data instead of actually making a network connection to a server - you cannot test changing data!).&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a bitly="BITLY_PROCESSED" href="http://2.bp.blogspot.com/_x_xRpNcK438/S6KFp1M-5PI/AAAAAAAAABg/nULVsZY6ke0/s1600-h/NotLayered.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="145" src="http://2.bp.blogspot.com/_x_xRpNcK438/S6KFp1M-5PI/AAAAAAAAABg/nULVsZY6ke0/s200/NotLayered.png" width="200" /&gt;&lt;/a&gt;&lt;/div&gt;On the iPhone Apple provides the Core Data API to abstract the database.&amp;nbsp; It is great!!!!&amp;nbsp; Unfortunately every book and sample I have found mixes the Core Data code in with the rest of the application.&amp;nbsp; Same with the network code.&amp;nbsp; &lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a bitly="BITLY_PROCESSED" href="http://2.bp.blogspot.com/_x_xRpNcK438/S6KF3uxb7lI/AAAAAAAAABo/4ryN4Up7tDY/s1600-h/Layered.png" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"&gt;&lt;img border="0" height="137" src="http://2.bp.blogspot.com/_x_xRpNcK438/S6KF3uxb7lI/AAAAAAAAABo/4ryN4Up7tDY/s200/Layered.png" width="200" /&gt;&lt;/a&gt;&lt;/div&gt;We, however, have a Database and a Network class on the iPhone and anything that wants to interact with those pieces has to go through those classes.&amp;nbsp; The end result is that the code is easier to follow, easier to maintain, and less error prone.&lt;br /&gt;&lt;br /&gt;So remember kids, when you are writing code, try to isolate as much as possible into layers of functionality where you "hide" most of the work behind a few well defined methods rather than having stuff strewn all over the code.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8386036339756925674-1981073941487496411?l=tofubeer.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://tofubeer.blogspot.com/feeds/1981073941487496411/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://tofubeer.blogspot.com/2010/03/another-brick-in-wall-part-1-software.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8386036339756925674/posts/default/1981073941487496411'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8386036339756925674/posts/default/1981073941487496411'/><link rel='alternate' type='text/html' href='http://tofubeer.blogspot.com/2010/03/another-brick-in-wall-part-1-software.html' title='Another Brick in the Wall: Part 1 (Software Design, Part 1)'/><author><name>TofuBeer</name><uri>http://www.blogger.com/profile/17555313388131451916</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/_x_xRpNcK438/Sz_AD0IUa5I/AAAAAAAAAAM/Xq9ClBTP-fE/S220/duke.png'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/_x_xRpNcK438/S6KFp1M-5PI/AAAAAAAAABg/nULVsZY6ke0/s72-c/NotLayered.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8386036339756925674.post-7247722563419544207</id><published>2010-03-18T12:32:00.000-07:00</published><updated>2010-03-18T12:32:28.409-07:00</updated><title type='text'>The Final Cut (If you are deleting code you are doing something right!)</title><content type='html'>A long time ago I once worked with someone who said something along the lines of "If you are deleting code you are doing something right".&amp;nbsp; Of course one might wonder why you should write something that needs to be deleted... but if you are not doing that, you are probably doing something wrong.&lt;br /&gt;&lt;br /&gt;As you go through your code you should always keep an eye out for similarities - and once you find them get rid of them.&amp;nbsp; The way I look at it is if your code isn't all the same you are doing something wrong, and once you notice it is the same if you don't make it all different you are doing something wrong (what?!).&lt;br /&gt;&lt;br /&gt;Take the example that I just did in our code:&lt;br /&gt;&lt;br /&gt;- Connect to server X and request a JSON result&lt;br /&gt;- Parse the JSON result int a class (we use the Gson library from Google for that)&lt;br /&gt;- Store the information for further processing&lt;br /&gt;&lt;br /&gt;We also, for now, save some statistics such as the size and amount of time it took to get the result from the server so we can see if there are some patterns in what makes certain requests slower than others (once you have a lot of data you would be surprised what you can find out).&lt;br /&gt;&lt;br /&gt;Each connection to a server is handled pretty much the same way: make a URL, connect to it, read the resulting stream.&amp;nbsp; Each time we parse the JSON stream it is the same (except that the class we store into changes).&amp;nbsp; The way the data is stored is the same.&amp;nbsp; The way information is stored in the database is the same.&lt;br /&gt;&lt;br /&gt;Take any request cycle above for any website (we have about 5 requests that we make on 3 different sites) and the code should be pretty much the same.&amp;nbsp; If you were to blur the code (we will call this the "Blurry Code Stage") you would say that the code is all the same - the only difference would be some string constants, a class name, and, perhaps, some variable names.&amp;nbsp; &lt;br /&gt;&lt;br /&gt;It makes perfect sense that code that has to do something similar to something else looks pretty much the same.&amp;nbsp; If it doesn't look the same then you have a big problem.&amp;nbsp; Code that does the same sort of thing in a different way is harder to understand (now you need to understand 2 or more ways instead of just one) and you will probably have way more bugs in the code.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Once you are at the "Blurry Code Stage" you should realize that you  have done the right thing:  you have made the code the same.&lt;br /&gt;&lt;br /&gt;Once you are at the "Blurry Code Stage" you should realize that you  have done the wrong thing:  you have made the code the same. &lt;br /&gt;&lt;br /&gt;(WHAT?!????!!!!one!!!!!111?????)&lt;br /&gt;&lt;br /&gt;The "Blurry Code Stage" is a turning point; you have done the right thing by making a lot of code follow the same pattern, but at the same time the pattern repeats time and time again which means you can consolidate the code.&amp;nbsp;&amp;nbsp; Consolidating means deleting code, and "If you are deleting code you are doing something right".&amp;nbsp; You should strive to get your code to the "Blurry Code Stage" and then strive to remove as much code as possible.&lt;br /&gt;&lt;br /&gt;The above example in our code probably winds up being about 100 lines in total (no, I am not going to go check the code and count the lines!).&amp;nbsp; We have 5 sites.&amp;nbsp; That means there are about 500 lines when there only needs to be about 100 (that will actually go up a bit because you probably need to introduce some variables and probably some additional logic, so lets' say 125 lines instead of 500).&lt;br /&gt;&lt;br /&gt;If you are lucky you will notice after the 3rd one that the code is similar and you should refactor it.&amp;nbsp; For example, I caught it after the 2nd one and managed to move all of the database code into one place.&amp;nbsp; That meant that the other three requests automagically had the database code work with no further effort on my part.&amp;nbsp; I noticed that the website request was the same after the 4th one and took about 120 lines of code.&lt;br /&gt;&lt;br /&gt;Last night I noticed that I really have two ways of parsing the JSON data.&amp;nbsp; I also noticed that I didn't write the code the same way, so I really have three different ways of writing it (and in reality there are four ways I have written that code).&amp;nbsp; Grrrrrrr!&amp;nbsp; So how to fix it?&amp;nbsp; First up - parse the JSON data the same way.&amp;nbsp; That will get me down to three ways.&amp;nbsp; Next is to get three ways down to two... which will involve adding some new methods, some of which will do nothing (if they do nothing why add them?!, keep reading, I'll get to it).&lt;br /&gt;&lt;br /&gt;Doing all of this in a Object Oriented language (I am using Java) is pretty easy. For example:&lt;br /&gt;&lt;pre&gt;&lt;code&gt;&lt;br /&gt;public class Add&lt;br /&gt;{&lt;br /&gt;    public int add(final int a, final  int b)&lt;br /&gt;    { &lt;br /&gt;        if(a &amp;lt; 0)&lt;br /&gt;        {&lt;br /&gt;            throw new  IllegalArgumentException("a must be &amp;gt;= 0, was: " + a);&lt;br /&gt;        } &lt;br /&gt;&lt;br /&gt;        if(b &amp;lt; 0)&lt;br /&gt;        {&lt;br /&gt;            throw new  IllegalArgumentException("b must be &amp;gt;= 0, was: " + b);&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        return (a + b);&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;public class Subtract&lt;br /&gt;{&lt;br /&gt;    public int subtract(final int a, final  int b)&lt;br /&gt;    { &lt;br /&gt;        if(a &amp;lt; 0)&lt;br /&gt;        {&lt;br /&gt;            throw new  IllegalArgumentException("a must be &amp;gt;= 0, was: " + a);&lt;br /&gt;        } &lt;br /&gt;&lt;br /&gt;        if(b &amp;lt; 0)&lt;br /&gt;        {&lt;br /&gt;            throw new  IllegalArgumentException("b must be &amp;gt;= 0, was: " + b);&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        return (a - b);&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;/pre&gt;Now blur your eyes:&lt;br /&gt;&lt;pre&gt;&lt;code&gt;&lt;br /&gt;public class &lt;b&gt;Add/Subtract&lt;/b&gt;&lt;br /&gt;{&lt;br /&gt;    public int &lt;b&gt;add/subtract&lt;/b&gt;(final int a, final  int b)&lt;br /&gt;    { &lt;br /&gt;        if(a &amp;lt; 0)&lt;br /&gt;        {&lt;br /&gt;            throw new  IllegalArgumentException("a must be &amp;gt;= 0, was: " + a);&lt;br /&gt;        } &lt;br /&gt;         &lt;br /&gt;        if(b &amp;lt; 0)&lt;br /&gt;        {&lt;br /&gt;            throw new  IllegalArgumentException("b must be &amp;gt;= 0, was: " + b);&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        return (a &lt;b&gt;+/-&lt;/b&gt; b);&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;/pre&gt;You see it is only Add/Subtract, add/subtract, and +/- that are different.&amp;nbsp; We can easily fix that like this:&lt;br /&gt;&lt;pre&gt;&lt;code&gt;&lt;br /&gt;public abstract class Operation&lt;br /&gt;{&lt;br /&gt;    public final int perform(final int a, final  int b)&lt;br /&gt;    {&lt;br /&gt;        final int result;&lt;br /&gt;&lt;br /&gt;        if(a &amp;lt; 0)&lt;br /&gt;        {&lt;br /&gt;            throw new  IllegalArgumentException("a must be &amp;gt;= 0, was: " + a);&lt;br /&gt;        } &lt;br /&gt;&lt;br /&gt;        if(b &amp;lt; 0)&lt;br /&gt;        {&lt;br /&gt;            throw new  IllegalArgumentException("b must be &amp;gt;= 0, was: " + b);&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        result = doPerform(a, b); &lt;br /&gt;&lt;br /&gt;        return (result);&lt;br /&gt;    }&lt;br /&gt;   &lt;br /&gt;    protected int doPerform(int a, int b);&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;public class Add&lt;br /&gt;    extends Operation&lt;br /&gt;{&lt;br /&gt;    protected int doPeform(final int a, final int b)&lt;br /&gt;    {&lt;br /&gt;        return (a + b); &lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;public class Subtract&lt;br /&gt;    extends Operation&lt;br /&gt;{&lt;br /&gt;    protected int doPeform(final int a, final int b)&lt;br /&gt;    {&lt;br /&gt;        return (a - b); &lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;/pre&gt;Now if you want to add a new operation you just have to extend the Operation class and then override the doPerform method to do the right thing.&lt;br /&gt;&lt;br /&gt;In the case of divide we might want to do something special when dividing by zero...&lt;br /&gt;&lt;pre&gt;&lt;code&gt;&lt;br /&gt;public class Divide&lt;br /&gt;    extends Operation&lt;br /&gt;{&lt;br /&gt;    protected int doPeform(final int a, final int b)&lt;br /&gt;    {&lt;br /&gt;        // do not want a divide by zero error, but also don't necessarily want to handle the special case here... &lt;br /&gt;        return (a / b); &lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    protected void checkNumbers(final int dividend, final int divisor)&lt;br /&gt;    {&lt;br /&gt;        if(divisor == 0)&lt;br /&gt;        {&lt;br /&gt;            throw new IllegalArgumentException("divisor cannot be 0"); &lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;/pre&gt;now we need some way to call it:&lt;br /&gt;&lt;pre&gt;&lt;code&gt;&lt;br /&gt;public abstract class Operation&lt;br /&gt;{&lt;br /&gt;    public final int perform(final int a, final  int b)&lt;br /&gt;    {&lt;br /&gt;        final int result;&lt;br /&gt;&lt;br /&gt;        if(a &amp;lt; 0)&lt;br /&gt;        {&lt;br /&gt;            throw new  IllegalArgumentException("a must be &amp;gt;= 0, was: " + a);&lt;br /&gt;        } &lt;br /&gt;&lt;br /&gt;        if(b &amp;lt; 0)&lt;br /&gt;        {&lt;br /&gt;            throw new  IllegalArgumentException("b must be &amp;gt;= 0, was: " + b);&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        checkNumbers(a, b); &lt;br /&gt;        result = doPerform(a, b);&lt;br /&gt;&lt;br /&gt;        return (result);&lt;br /&gt;    }&lt;br /&gt;    &lt;br /&gt;    protected int doPerform(int a, int b);&lt;br /&gt; &lt;br /&gt;    protected void checkNumbers(final int a, final int b)&lt;br /&gt;    {&lt;br /&gt;        // add and subtract don't do anything, they just inherit this empty method &lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;/pre&gt;Great... but now we don't pass the "Blurry Code Test" since the a &amp;lt; 0 and b &amp;lt; 0 are pretty close to the divisor == 0... so I'd do:&lt;br /&gt;&lt;pre&gt;&lt;code&gt;&lt;br /&gt;public abstract class Operation&lt;br /&gt;{&lt;br /&gt;    public final int perform(final int a, final  int b)&lt;br /&gt;    {&lt;br /&gt;        final int result;&lt;br /&gt;&lt;br /&gt;        checkNumbers(a, b); &lt;br /&gt;        result = doPerform(a, b); &lt;br /&gt;&lt;br /&gt;        return (result);&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    protected int doPerform(int a, int b);&lt;br /&gt;&lt;br /&gt;    protected void checkNumbers(final int a, final int b)&lt;br /&gt;    {&lt;br /&gt;        if(a &amp;lt; 0)&lt;br /&gt;        {&lt;br /&gt;            throw new  IllegalArgumentException("a must be &amp;gt;= 0, was: " + a);&lt;br /&gt;        } &lt;br /&gt;    &lt;br /&gt;        if(b &amp;lt; 0)&lt;br /&gt;        {&lt;br /&gt;            throw new  IllegalArgumentException("b must be &amp;gt;= 0, was: " + b);&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;public class Divide&lt;br /&gt;    extends Operation&lt;br /&gt;{&lt;br /&gt;    protected int doPeform(final int a, final int b)&lt;br /&gt;    {&lt;br /&gt;        // do not want a divide by zero error, but also don't  necessarily want to handle the special case here... &lt;br /&gt;&lt;br /&gt;        return (a / b); &lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    protected void checkNumbers(final int dividend, final int divisor)&lt;br /&gt;    {&lt;br /&gt;        // could do it this way, or use a doCheckNumbers like the other way &lt;br /&gt;        super.checkNumbers(dividend, divisor);&lt;br /&gt;&lt;br /&gt;        if(divisor == 0)&lt;br /&gt;        {&lt;br /&gt;            throw new IllegalArgumentException("divisor cannot be  0"); &lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;/pre&gt;Add and Subtract remain unchanged.&lt;br /&gt;&lt;br /&gt;Some newer programmers (and probably some older programmers) don't feel comfortable with this because now you have to jump around the code to follow it. Short answer: get over it. Your methods should be small, and pretty easy to understand.&lt;br /&gt;&lt;br /&gt;The benefit is that you can add new operations (multiply for example) without having to do a lot of work. If that work consists of copy/paste then you are at the "Blurry Code Stage" and you really should stop and fix the code instead of continuing on.&lt;br /&gt;&lt;br /&gt;In my case I want to add a sixth call to a website and I'd rather do that in about 10 lines rather than 100. Is it slower to change the code then just add the new one? In the short term yes it is slower.. but in the long term you get a huge pay off in terms of time when coding something new or when fixing a bug (you can fix the bug in one place not many).&lt;br /&gt;&lt;br /&gt;While I swapped between this blog and the code I wound up doing the following:&lt;br /&gt;&lt;br /&gt;1) getting it down to one single way of parsing instead of 4&lt;br /&gt;2) normalizing the JSON I am parsing (I used to jump through some hoops to only parse certain bits, now all of the returned JSON is parsed in all cases)&lt;br /&gt;3) fixed a semi-related bit of ugliness in the code - some times I used the raw JSON results, other times I used extra classes that augmented the results.&amp;nbsp; Now I always use augmented results.&lt;br /&gt;&lt;br /&gt;The last two are important because they make the code consistent (consistent code is probably the most important thing) and may lead me to more blurry code later.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8386036339756925674-7247722563419544207?l=tofubeer.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://tofubeer.blogspot.com/feeds/7247722563419544207/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://tofubeer.blogspot.com/2010/03/final-cut-if-you-are-deleting-code-you.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8386036339756925674/posts/default/7247722563419544207'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8386036339756925674/posts/default/7247722563419544207'/><link rel='alternate' type='text/html' href='http://tofubeer.blogspot.com/2010/03/final-cut-if-you-are-deleting-code-you.html' title='The Final Cut (If you are deleting code you are doing something right!)'/><author><name>TofuBeer</name><uri>http://www.blogger.com/profile/17555313388131451916</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/_x_xRpNcK438/Sz_AD0IUa5I/AAAAAAAAAAM/Xq9ClBTP-fE/S220/duke.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8386036339756925674.post-4670687649707294897</id><published>2010-02-11T16:03:00.000-08:00</published><updated>2010-02-11T16:03:32.188-08:00</updated><title type='text'>Thinking is bad / It is hard work being lazy.</title><content type='html'>&amp;nbsp;It has been a while since I wrote anything on here... been too busy.&lt;br /&gt;&lt;br /&gt;I just checked and it has been exactly one month since the  first check-in of the code to subversion.&amp;nbsp; Given that I was hoping for  this to take two weeks you might think I'd be disappointed, but we  changed the focus a bit, I had a few things to learn, and there was some  refactoring of code to make it better.&amp;nbsp; The refactoring is one of those  things where it sucks up time now, but in the end it saves so much  time.&amp;nbsp; As I used to tell my students "Thinking is bad" - and "It is hard  work being lazy".&amp;nbsp; The refactoring made the code much simpler to  understand (less thinking) and it took a chunk of time to do the  refactoring but I have an easier time adding new features (I get to be  lazy). &lt;br /&gt;&lt;br /&gt;Speaking of thinking and lazy - I HATE programming books.&amp;nbsp; For a beginner they show you all sorts of bad habits, for someone who is more advanced they make you figure out what they are actually trying to do because you have to fight your way through all the bad habits.&amp;nbsp; A while back Judy asked me for a book list... I think I am going to take some time in the next while to do a blog on each book and why I like it.&amp;nbsp; If you ever write a book or sample code do the work a favour and make sure that you write nice, clean code, instead of something that tries to hide real work complexity.&lt;br /&gt;&lt;br /&gt;The server is very stable now - no memory leaks, runs for days without any issues (before  I stop it to put in some changes), and it is very easy to add in new  things.&amp;nbsp; The client is underway on the iPhone.&amp;nbsp; &lt;br /&gt;&lt;br /&gt;I have been doing my best to keep the number of messages between the client and the server low.&amp;nbsp; I thought I could get by with one type of message, but in order to keep the overall data transfer small I wound up with two required messages and an optional one.&amp;nbsp; Out of the two required messages one is, strictly speaking, optional but in reality I am sure it will be sent as often as the required one.&amp;nbsp; What this does is make the client a little slow on startup (but not too slow compared to the competition), but once it is up and running it is fast since there are no more data transfers required for the most common things.&amp;nbsp; I'll have to implement one more message (another optional one).&amp;nbsp; I also managed to get the size of the messages down very small.&amp;nbsp; Best case it is 10x smaller than the first way I did it, and on average it should be at least 5 times smaller I think.&lt;br /&gt;&lt;br /&gt;Now that the client is underway I am in the position of do some work on the client, then hop back over and make changes to the server (like adding new messages as needed).&amp;nbsp; I got part way setting up the database on OS X, I should go back to that so I can do the server coding under OS X instead of Windoze.&amp;nbsp; It is annoying to reboot, make the server changes, then reboot again to test the changes.&amp;nbsp; I could use two machines I suppose, but that smacks of effort :-)&lt;br /&gt;&lt;br /&gt;I found a handful of beta testers to try out the app once I get it a bit more functional.&amp;nbsp; The only comment so far was that the colour would have to change for one of them to test it (I liked that colour!).&amp;nbsp; If that is someones biggest complaint I'll be happy!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8386036339756925674-4670687649707294897?l=tofubeer.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://tofubeer.blogspot.com/feeds/4670687649707294897/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://tofubeer.blogspot.com/2010/02/thinking-is-bad-it-is-hard-work-being.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8386036339756925674/posts/default/4670687649707294897'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8386036339756925674/posts/default/4670687649707294897'/><link rel='alternate' type='text/html' href='http://tofubeer.blogspot.com/2010/02/thinking-is-bad-it-is-hard-work-being.html' title='Thinking is bad / It is hard work being lazy.'/><author><name>TofuBeer</name><uri>http://www.blogger.com/profile/17555313388131451916</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/_x_xRpNcK438/Sz_AD0IUa5I/AAAAAAAAAAM/Xq9ClBTP-fE/S220/duke.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8386036339756925674.post-3434314075080130532</id><published>2010-02-09T10:51:00.000-08:00</published><updated>2010-02-09T10:52:37.635-08:00</updated><title type='text'>Olympic Torch Run</title><content type='html'>Took a 5 minute break to go watch the torch pass by the local pub... you will notice that here in New Westminster it is more of a walk than a run... :-)&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a bitly="BITLY_PROCESSED" href="http://1.bp.blogspot.com/_x_xRpNcK438/S3Gul_Kur2I/AAAAAAAAABI/gepqz4-LuTM/s1600-h/olympic-torch.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="640" src="http://1.bp.blogspot.com/_x_xRpNcK438/S3Gul_Kur2I/AAAAAAAAABI/gepqz4-LuTM/s640/olympic-torch.png" width="480" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8386036339756925674-3434314075080130532?l=tofubeer.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://tofubeer.blogspot.com/feeds/3434314075080130532/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://tofubeer.blogspot.com/2010/02/olympic-torch-run.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8386036339756925674/posts/default/3434314075080130532'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8386036339756925674/posts/default/3434314075080130532'/><link rel='alternate' type='text/html' href='http://tofubeer.blogspot.com/2010/02/olympic-torch-run.html' title='Olympic Torch Run'/><author><name>TofuBeer</name><uri>http://www.blogger.com/profile/17555313388131451916</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/_x_xRpNcK438/Sz_AD0IUa5I/AAAAAAAAAAM/Xq9ClBTP-fE/S220/duke.png'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/_x_xRpNcK438/S3Gul_Kur2I/AAAAAAAAABI/gepqz4-LuTM/s72-c/olympic-torch.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8386036339756925674.post-3265669962221178468</id><published>2010-01-29T10:23:00.000-08:00</published><updated>2010-01-29T10:25:04.195-08:00</updated><title type='text'>It Would Be So Nice</title><content type='html'>&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;/div&gt;After about 18 hours of coding yesterday I feel like this... (http://xkcd.com/695)&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://imgs.xkcd.com/comics/spirit.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="400" src="http://imgs.xkcd.com/comics/spirit.png" width="296" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8386036339756925674-3265669962221178468?l=tofubeer.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://tofubeer.blogspot.com/feeds/3265669962221178468/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://tofubeer.blogspot.com/2010/01/it-would-be-so-nice.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8386036339756925674/posts/default/3265669962221178468'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8386036339756925674/posts/default/3265669962221178468'/><link rel='alternate' type='text/html' href='http://tofubeer.blogspot.com/2010/01/it-would-be-so-nice.html' title='It Would Be So Nice'/><author><name>TofuBeer</name><uri>http://www.blogger.com/profile/17555313388131451916</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/_x_xRpNcK438/Sz_AD0IUa5I/AAAAAAAAAAM/Xq9ClBTP-fE/S220/duke.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8386036339756925674.post-8115203302691043649</id><published>2010-01-19T23:51:00.000-08:00</published><updated>2010-01-20T08:40:41.476-08:00</updated><title type='text'>Signs of Life (Servers up, client is underway... oh and network bandwidth)</title><content type='html'>Ah the life of a programmer.&amp;nbsp; Nothing is ever "done".&amp;nbsp; I have a few "TODO" comments in the server code, some are simple (like this variable has no state so should not be a local - trying to keep things fast) others are more complex (this needs to be refactored out into a few other classes).&amp;nbsp; None of them are too difficult, but need to prioritize :-)&lt;br /&gt;&lt;br /&gt;Recently I learned that EclipseLink (the JPA provider that I am using for the database access) has some not-fun behaviours when you deal with two ore more EntityMangers - there is a a cache for each EntityManager which means that changes made to the database in one are not visible to changes in the other... sigh.&amp;nbsp; After some digging around I found I had to add a line to my persistence.xml: "&lt;property name="eclipselink.cache.type.default" value="Weak"&gt;" which fixes that issue.&lt;/property&gt;&lt;br /&gt;&lt;br /&gt;I took the time to make a number of changes to the database and the architecture... now things move much faster (coding wise).&amp;nbsp; The code is safer, easier to understand, and not slow.&amp;nbsp; I used JMeter to to a load test on the server... the good news is that it is network bound (meaning I am limited by how much data I can push out the Ethernet card) instead of CPU or disk bound.&amp;nbsp; Basically my code is faster than the network.&amp;nbsp; That puts me into the next part of optimization - reducing the network traffic.&amp;nbsp; I am now figuring out ways that I can send less data per request.&amp;nbsp; If the way I am thinking of doing it works then I should be able to at least double, if not triple or quadruple the number of concurrent connections.&amp;nbsp; &lt;br /&gt;&lt;br /&gt;When you (or your company) are paying for the bandwidth you need to be extra careful to keep the data your are sending out small!&amp;nbsp; I cannot imagine the bill youtube has for network bandwidth every day let alone every month&amp;nbsp; - just did a search: "&lt;a bitly="BITLY_PROCESSED" href="http://www.slate.com/id/2216162/"&gt;To serve up all these streams, the company has to pay for a broadband  connection capable of hurtling data at the equivalent of 30 million  megabits-per-second—about 6 million times as fast as your home Internet  connection. All this bandwidth costs Google $360 million a year, the  analysts estimate.&lt;/a&gt;",&lt;br /&gt;&lt;br /&gt;Wow... ok now my ~2500bytes per request doesn't seem so bad :-) (but I still want to get it WAY smaller).&lt;br /&gt;&lt;br /&gt;The bandwidth issue isn't just on the company side either, clients have to pay for their Internet access too.&amp;nbsp; When you are talking about a mobile device, such as the iPhone, you really want to reduce the number of times the app has to hit the network and the amount of data it has to send and request.&amp;nbsp; I'd say it should take more effort to design the data to be small than it does to ensure that the web service is fast enough to push the data out.&amp;nbsp; A client won't notice an extra 10ms spent on the server but they will notice an extra 2 seconds with the app fiddling around on the network.&amp;nbsp; 5 seconds and they will probably never start the app again.&lt;br /&gt;&lt;br /&gt;The server ran for a number of days without a hiccup (after I fixed a couple of minor issues).&amp;nbsp; I just added a new source of data which needed a database change and a service restart - so off it'll go for another few days.&amp;nbsp; While that happens I'll be working on the iPhone client.&amp;nbsp; I think I'll save working on the data reduction until Judy is fine with the functionality and the UI on the client.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8386036339756925674-8115203302691043649?l=tofubeer.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://tofubeer.blogspot.com/feeds/8115203302691043649/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://tofubeer.blogspot.com/2010/01/signs-of-life-my-list-gets-smaller-and.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8386036339756925674/posts/default/8115203302691043649'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8386036339756925674/posts/default/8115203302691043649'/><link rel='alternate' type='text/html' href='http://tofubeer.blogspot.com/2010/01/signs-of-life-my-list-gets-smaller-and.html' title='Signs of Life (Servers up, client is underway... oh and network bandwidth)'/><author><name>TofuBeer</name><uri>http://www.blogger.com/profile/17555313388131451916</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/_x_xRpNcK438/Sz_AD0IUa5I/AAAAAAAAAAM/Xq9ClBTP-fE/S220/duke.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8386036339756925674.post-5566562149965016810</id><published>2010-01-16T21:25:00.000-08:00</published><updated>2010-01-16T21:38:11.411-08:00</updated><title type='text'>RANT: Why do I want to shorten my Link?</title><content type='html'>&lt;span style="background-color: blue; font-size: large;"&gt;&lt;i&gt;&lt;b&gt;&lt;span style="background-color: orange;"&gt;We interrupt our regularly schedule blog to bring you this rant.&lt;/span&gt;&lt;/b&gt;&lt;/i&gt;&lt;/span&gt;&lt;br /&gt;&lt;rant&gt;&lt;br /&gt;&lt;/rant&gt;&lt;br /&gt;Facebook... whatever.&amp;nbsp; Why the hell do I care about your playing some Facebook based game?&amp;nbsp; You want a farm?&amp;nbsp; Go get a farm!&amp;nbsp; You want to be in the mafia?&amp;nbsp; Go join the mafia.&amp;nbsp; Poker?&amp;nbsp; Get a deck of cards.&amp;nbsp; The only interesting thing is &lt;a href="http://www.facebook.com/home.php?#/pages/St-My-Dad-Said-Says/139058343488?ref=ts"&gt;S**t My Dad Said&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/_x_xRpNcK438/S1Kc6eWlyyI/AAAAAAAAAAw/yIT97L767p4/s1600-h/facebook-1.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://3.bp.blogspot.com/_x_xRpNcK438/S1Kc6eWlyyI/AAAAAAAAAAw/yIT97L767p4/s320/facebook-1.png" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;Twitter... whatever.&amp;nbsp; People use it guess I'll have to get into it  too.&amp;nbsp; The one interesting thing is watching the trends.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/_x_xRpNcK438/S1KdAWCmjyI/AAAAAAAAAA4/chYD5SdxeLc/s1600-h/twitter-2.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://4.bp.blogspot.com/_x_xRpNcK438/S1KdAWCmjyI/AAAAAAAAAA4/chYD5SdxeLc/s320/twitter-2.png" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;MySpace... never been... don't plan on going either.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Blogging... some interesting things...&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;What the hell happened to people just talking?&amp;nbsp; The number of educated people I know who send emails with "U" is depressing.&amp;nbsp; Is it really hard to write you?&amp;nbsp; Y-O-U.&amp;nbsp; Seriously how hard can it be.&lt;br /&gt;&lt;br /&gt;Then you look at the stuff on facebook that I mostly wind up blocking (happy day when I found I could do that).&amp;nbsp; &lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Blogging?&amp;nbsp; My first though was "who the hell wants to read what other people have to say"?&amp;nbsp; (semi-ironic that I am now blogging about stuff I am sure nobody cares about :-)&amp;nbsp; &lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Personally I prefer to stay away from crowds of people, talk to a few people, hide in the background as much as I can... so perhaps it is the more extroverted people that are into all of this.&amp;nbsp; Me... dragging kicking and screaming (silently) into this.&amp;nbsp; I am not sure why people care about what kfed (whever that is) is eating for breakfast... I am just not sure which is worse - him telling people or people listening!&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/_x_xRpNcK438/S1KdZ07YWAI/AAAAAAAAABA/t71NCaqzyaQ/s1600-h/Twitter-1.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://4.bp.blogspot.com/_x_xRpNcK438/S1KdZ07YWAI/AAAAAAAAABA/t71NCaqzyaQ/s320/Twitter-1.jpg" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;What caused the rant (and the title)?&amp;nbsp; I have been using computers for about 30 years now.&amp;nbsp; I remember sending my first email.&amp;nbsp; When I first hooked up to the Internet.&amp;nbsp; I remember the first day I surfed the world wide web (on a modem... kids these days don't even know what a modem sounds like).&amp;nbsp; I remember having meetings at Netscape and Sun.&amp;nbsp; I've been programming since before high school (Commodore 64 Basic - peek and poke!)&amp;nbsp; and I have NEVER had a hard time figuring out how to get something, that should be simple, to work - bit.ly the URL shortener.&lt;br /&gt;&lt;br /&gt;bit.ly is a good idea, makes perfect sense, glad it exists.&amp;nbsp; The idea of a book mark in the toolbar - what the hell?&amp;nbsp; If you are going to do something make it intuitive!!!&amp;nbsp; At one point I uttered "why would I want to shorten my link?&amp;nbsp; Isn't all the spam telling me I want to make it longer?&amp;nbsp; .......... oh... link."&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Oh yeah - get off my lawn too.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8386036339756925674-5566562149965016810?l=tofubeer.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://tofubeer.blogspot.com/feeds/5566562149965016810/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://tofubeer.blogspot.com/2010/01/rant-why-do-i-want-to-shorten-my-link.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8386036339756925674/posts/default/5566562149965016810'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8386036339756925674/posts/default/5566562149965016810'/><link rel='alternate' type='text/html' href='http://tofubeer.blogspot.com/2010/01/rant-why-do-i-want-to-shorten-my-link.html' title='RANT: Why do I want to shorten my Link?'/><author><name>TofuBeer</name><uri>http://www.blogger.com/profile/17555313388131451916</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/_x_xRpNcK438/Sz_AD0IUa5I/AAAAAAAAAAM/Xq9ClBTP-fE/S220/duke.png'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/_x_xRpNcK438/S1Kc6eWlyyI/AAAAAAAAAAw/yIT97L767p4/s72-c/facebook-1.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8386036339756925674.post-5577035539281985161</id><published>2010-01-14T11:38:00.000-08:00</published><updated>2010-01-14T14:25:55.149-08:00</updated><title type='text'>Take Up Thy Stethoscope and Walk (Profiling Java Applications)</title><content type='html'>First off, you may have noticed I went back and gave my posts "better" titles... although I like having titles where you have to figure out what the meaning of the post is I also know it isn't as friendly as having a real topic.&amp;nbsp; Amazingly Judy didn't have to tell me to fix it!&lt;br /&gt;&lt;br /&gt;The story so far... Judy showed me an app on a web page, which inspired me to go off and do a different app for the iPhone.&amp;nbsp; This app is a great playground for working on larger applications as it has the basic architecture that we use for Smart Phone server-backed apps.&amp;nbsp; I now have the server running under Tomcat 6 and, for now, it is done.&lt;br /&gt;&lt;br /&gt;Once your software is "done" it is time to test it (not Unit Testing- you do that all the time!).&amp;nbsp; I haven't written the client yet, or the part of the server that the client will talk to.&amp;nbsp; What I have written is the part that gathers data from various places and stores it in a database.&amp;nbsp; This is a perfect time to check things out for speed and memory.&amp;nbsp; I am making use of Wicket, JPA, Google GSON and XmlBeans all of which have benefits, but they also come with overhead.&amp;nbsp; What I need to do is make sure that the overhead doesn't outweigh the benefits.&lt;br /&gt;&lt;br /&gt;I am using NetBeans 6.8 which has nice integration with Maven and Tomcat.&amp;nbsp; The first time I tried to profile the application it did bad things... hung NetBeans badly, and generally made me sad.&amp;nbsp; Today I got it working (I don't know why it works now... but it does... perhaps there was a chicken sacrifice or something I am unaware of).&lt;br /&gt;&lt;br /&gt;The result of the profiling?&amp;nbsp; Perfect!&amp;nbsp; about 82% of the time the server is reading from the network, the Wicket, JPA, Google GSON, and XmlBeans don't show up as taking an appreciable amount of time... just as I had hoped.&amp;nbsp; Memory usage is a little higher than my simple standalone test server that I wrote before I ported it over to Tomcat and Wicket... but no memory leaks (yes, you can have memory leaks in Java).&amp;nbsp; Watching the VM Telemetry (shows what is going on with garbage collection in real time) in NetBeans is way cool - even cooler when you see all the garbage collected and the peak memory usage never goes up! &lt;br /&gt;&lt;br /&gt;Why profile when everything is done rather than as you go?&amp;nbsp; Well sometimes (on rare occasions) you do profile as you go, usually when you are doing something that you have to have be fast, or use little memory, or both.&amp;nbsp; In general you want to write your code so that it is maintainable (refactor anything that looks ugly as you go along).&amp;nbsp; If you have "nice" code then odds are it is already fast and uses little memory - and if it doesn't then you can fix it when you find that it is slow.&amp;nbsp; The key here is to have as much of the application unit tested as possible so that you can make the refactoring changes without (much) fear of breaking something.&lt;br /&gt;&lt;br /&gt;Speaking of which having good code coverage on tests... I need to go check mine.&amp;nbsp; I know it is low since I haven't (yet) figured out how I am going to unit test the database and external server portions.&amp;nbsp; Right now I have tested to data that comes back from the server... but that isn't all I should be able to do.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8386036339756925674-5577035539281985161?l=tofubeer.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://tofubeer.blogspot.com/feeds/5577035539281985161/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://tofubeer.blogspot.com/2010/01/take-up-thy-stethoscope-and-walk.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8386036339756925674/posts/default/5577035539281985161'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8386036339756925674/posts/default/5577035539281985161'/><link rel='alternate' type='text/html' href='http://tofubeer.blogspot.com/2010/01/take-up-thy-stethoscope-and-walk.html' title='Take Up Thy Stethoscope and Walk (Profiling Java Applications)'/><author><name>TofuBeer</name><uri>http://www.blogger.com/profile/17555313388131451916</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/_x_xRpNcK438/Sz_AD0IUa5I/AAAAAAAAAAM/Xq9ClBTP-fE/S220/duke.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8386036339756925674.post-7264795974316804972</id><published>2010-01-13T09:23:00.000-08:00</published><updated>2010-01-14T11:16:56.535-08:00</updated><title type='text'>See Emily Play (A Simple iPhone Starter App)</title><content type='html'>I have been busy for the last few days.&amp;nbsp; Judy showed me some neat app on a website and that inspired me to write a different sort of app on the iPhone.&lt;br /&gt;&lt;br /&gt;Maven, so far, is much better than Ant.&amp;nbsp; It isn't perfect, and the documentation (that I admittedly skimmed) isn't great, but so far it just works.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://wicket.apache.org/"&gt;Wicket&lt;/a&gt; is successfully being abused to return &lt;a href="http://www.json.org/"&gt;JSON&lt;/a&gt; responses and start a timed service in the background (I figure we will be running Tomcat anyways, may as well use it for server side of this app as well as others rather than write a stand-alone server).&amp;nbsp; &lt;br /&gt;&lt;br /&gt;There is a bit more work to do on the server side (I need to clean up the code that parses some of the incoming data) and then the client needs to be written.&amp;nbsp; Once that happens we will setup a beta on the site while we send the app to the iTunes store to put it out for real.... woot!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8386036339756925674-7264795974316804972?l=tofubeer.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://tofubeer.blogspot.com/feeds/7264795974316804972/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://tofubeer.blogspot.com/2010/01/see-emily-play.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8386036339756925674/posts/default/7264795974316804972'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8386036339756925674/posts/default/7264795974316804972'/><link rel='alternate' type='text/html' href='http://tofubeer.blogspot.com/2010/01/see-emily-play.html' title='See Emily Play (A Simple iPhone Starter App)'/><author><name>TofuBeer</name><uri>http://www.blogger.com/profile/17555313388131451916</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/_x_xRpNcK438/Sz_AD0IUa5I/AAAAAAAAAAM/Xq9ClBTP-fE/S220/duke.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8386036339756925674.post-1252509026748998773</id><published>2010-01-07T17:50:00.000-08:00</published><updated>2010-01-14T11:16:12.437-08:00</updated><title type='text'>Have a Cigar (Project Started - Practical Programming Applied)</title><content type='html'>I skipped out on a posting yesterday, but I can now see my desk and I have a fresh install od Snow Leopard and Windows 7 on my desktop.&amp;nbsp; The laptop comes next sometime in the near future.&lt;br /&gt;&lt;br /&gt;First real Subversion commit #1 for project  $(I_cannot_say_the_name_yet)!&lt;br /&gt;&lt;br /&gt;After a number of years teaching programming in a practical way it is time to really put into practice what I have preached.&amp;nbsp; The first commit (that wasn't simply directories) was a JUnit test and the code to make it pass.&amp;nbsp; The unit test was written first.&amp;nbsp; The code does the bare minimum to make it pass.&amp;nbsp; Next up, write another test, make it pass, keep going until done :-) &lt;br /&gt;&lt;br /&gt;For years (going on 20 now) I have aimed at making sure the code I write is readable (pretty, neat, etc... just 'cause I have a messy desk doesn't mean I have messy code!).&amp;nbsp; I need to get maven configured so that I can keep that practice.&amp;nbsp; I love statically typed languages like Java since I can have the compiler do the work for me, also it more easily allows for Lint tools (tools that are even picker than the compiler) to find other mistakes I make.&amp;nbsp; Couple that with unit testing and code coverage and you can reasonably expect that the code works.&lt;br /&gt;&lt;br /&gt;The other interest I have right now is &lt;a href="http://www.mutationtest.net/twiki/bin/view/Resources/WebHome"&gt;mutation testing&lt;/a&gt; where the code is mutated and if the tests still pass some thing is wrong (if you change &amp;lt; to &amp;gt; and nothing breaks that means something is up).&amp;nbsp; I need to find a mutation tester that isn't too slow and works with maven.&amp;nbsp; Putting all of this into the build now should save time later on when I am not banging my head against my (now cleanish) desk trying to figure out where things went wrong.&lt;br /&gt;&lt;br /&gt;I much prefer to find all the bad things before customers do... the idea is that this process will help - at least that is what I have been telling students for the last 10 years :-)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8386036339756925674-1252509026748998773?l=tofubeer.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://tofubeer.blogspot.com/feeds/1252509026748998773/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://tofubeer.blogspot.com/2010/01/have-cigar.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8386036339756925674/posts/default/1252509026748998773'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8386036339756925674/posts/default/1252509026748998773'/><link rel='alternate' type='text/html' href='http://tofubeer.blogspot.com/2010/01/have-cigar.html' title='Have a Cigar (Project Started - Practical Programming Applied)'/><author><name>TofuBeer</name><uri>http://www.blogger.com/profile/17555313388131451916</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/_x_xRpNcK438/Sz_AD0IUa5I/AAAAAAAAAAM/Xq9ClBTP-fE/S220/duke.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8386036339756925674.post-3860526374904240243</id><published>2010-01-05T10:00:00.000-08:00</published><updated>2010-01-14T11:14:56.984-08:00</updated><title type='text'>Let There Be More Light (Cleaning Up)</title><content type='html'>Junk!&amp;nbsp; My office is filled with it.&amp;nbsp; Time to clean up!&amp;nbsp; How on earth do we accumulate so much stuff.&amp;nbsp; Looking around I see:&lt;br /&gt;- a telescope that needs to be in the basement- a large Lego box (no Lego in it, just junk)&lt;br /&gt;- a whack of paper, CDs, plastic bags&lt;br /&gt;&lt;br /&gt;The thing I cannot see, that I would really like to, is my desk!&lt;br /&gt;&lt;br /&gt;That and today is "OS Upgrade Day".&amp;nbsp; Time to put Snow Leopard on my Laptop, get onto the released version of Windows 7 on my desktop (the RC will start shutting down soon so now seems like a good time to do that).&amp;nbsp; I'll also refresh the OS X install on the desktop, re-do the XP install on the laptop.&amp;nbsp; Look at what Linux I want to run in VMWare too.&amp;nbsp;&amp;nbsp; I wonder how hostile other developers make their environments?&amp;nbsp; I seem to kill an OS every few months... I just don't like the clutter.&amp;nbsp; I also rarely have anything on the machine (email is on the server, files are in subversion, etc...).&amp;nbsp; I need to setup samba as a PDC and store my home directory on the server too... then I'll never have to burn a CD of backup data before the fresh install.&amp;nbsp; May as well get all this out of the way now so I can focus on programming!&lt;br /&gt;&lt;br /&gt;But back to stuff... and how much their is.&amp;nbsp; Reminds me of &lt;a href="http://www.youtube.com/watch?v=MvgN5gCuLac"&gt;George Carlin and A Place For My Stuff&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8386036339756925674-3860526374904240243?l=tofubeer.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://tofubeer.blogspot.com/feeds/3860526374904240243/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://tofubeer.blogspot.com/2010/01/let-there-be-more-light.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8386036339756925674/posts/default/3860526374904240243'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8386036339756925674/posts/default/3860526374904240243'/><link rel='alternate' type='text/html' href='http://tofubeer.blogspot.com/2010/01/let-there-be-more-light.html' title='Let There Be More Light (Cleaning Up)'/><author><name>TofuBeer</name><uri>http://www.blogger.com/profile/17555313388131451916</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/_x_xRpNcK438/Sz_AD0IUa5I/AAAAAAAAAAM/Xq9ClBTP-fE/S220/duke.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8386036339756925674.post-3205829802365677124</id><published>2010-01-04T09:29:00.000-08:00</published><updated>2010-01-14T11:14:33.047-08:00</updated><title type='text'>Sysyphus (Ant Sucks... Does Maven Suck Too?)</title><content type='html'>As I said in my first blog... &lt;a href="http://ant.apache.org/"&gt;Ant&lt;/a&gt; &lt;a href="http://www.google.com/search?hl=en&amp;amp;q=ant+sucks&amp;amp;aq=f&amp;amp;oq=&amp;amp;aqi="&gt;sucks&lt;/a&gt;.&amp;nbsp; It sucks hard.&amp;nbsp; I don't even want to go into detail about why it sucks - just trust me it sucks.&amp;nbsp; It is probably the worst tool ever invented.&amp;nbsp; I have used Ant for at least the last 4 years (it has taken that long to get it to do exactly what I want).&amp;nbsp; Now I am looking at using &lt;a href="http://wicket.apache.org/"&gt;Wicket&lt;/a&gt; for the web side of things... and Wicket works well with &lt;a href="http://maven.apache.org/"&gt;Maven&lt;/a&gt;.&amp;nbsp; I hope Maven doesn't &lt;a href="http://www.google.com/search?ie=UTF-8&amp;amp;oe=UTF-8&amp;amp;sourceid=navclient&amp;amp;gfns=1&amp;amp;q=maven+sucks"&gt;suck&lt;/a&gt; too...&lt;br /&gt;&lt;br /&gt;The one good thing about Maven is that all of the tools I talked about yesterday seem to be supported - and whats more they are automagically downloaded for you, so now I do not need to have a repository dedicated to the tools and I can easily (I hope) keep them up to date.&amp;nbsp; If this works out, it'll be a good thing.&lt;br /&gt;&lt;br /&gt;What finally pushed me over the edge and made me pull the trigger on Ant?&amp;nbsp; PMD has a new release (5.0) that is in testing.&amp;nbsp; Apparently it is stable, so I figured I'd start using it now.&amp;nbsp; If it doesn't work out I can always fall back to the old version.&amp;nbsp; In the process of porting over my Ant scripts I managed to break something with PMD.&amp;nbsp; So either PMD isn't ready for Ant yet, or I broke something.&amp;nbsp; In the end, my lazyness coupled with Wicket working well with Maven has given me the incentive to move away (far, far, far away) from Ant.&lt;br /&gt;&lt;br /&gt;Perhaps, in the end, I'll just go back to &lt;a href="http://www.gnu.org/software/make/"&gt;make&lt;/a&gt; - at least it works.&amp;nbsp; I'd write a batch file but, as someone once said when I worked at Symantec, "I would not trust Symantec to write a 5 line batch file"... if only they knew how large some of our batch files were... (and hey, they worked, mostly :-)&lt;br /&gt;&lt;br /&gt;Now I am off in search of a good resource or two on Maven.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8386036339756925674-3205829802365677124?l=tofubeer.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://tofubeer.blogspot.com/feeds/3205829802365677124/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://tofubeer.blogspot.com/2010/01/sysyphus.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8386036339756925674/posts/default/3205829802365677124'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8386036339756925674/posts/default/3205829802365677124'/><link rel='alternate' type='text/html' href='http://tofubeer.blogspot.com/2010/01/sysyphus.html' title='Sysyphus (Ant Sucks... Does Maven Suck Too?)'/><author><name>TofuBeer</name><uri>http://www.blogger.com/profile/17555313388131451916</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/_x_xRpNcK438/Sz_AD0IUa5I/AAAAAAAAAAM/Xq9ClBTP-fE/S220/duke.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8386036339756925674.post-5815757674459515875</id><published>2010-01-03T11:39:00.000-08:00</published><updated>2010-01-14T11:13:29.048-08:00</updated><title type='text'>Welcome to the Machine (Tools for Java Developers)</title><content type='html'>Goals for today:&lt;br /&gt;&lt;br /&gt;1) setup a subversion repository with my standard tool set for Java programming:&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;- &lt;a href="http://ant.apache.org/"&gt;Ant &lt;/a&gt;for building (one day I'll look at &lt;a href="http://maven.apache.org/"&gt;Maven&lt;/a&gt;, 'cause Ant is the suxorz, but I managed to get it to work the way I want)&lt;br /&gt;- Lint tools (&lt;a href="http://checkstyle.sourceforge.net/"&gt;checkstyle&lt;/a&gt;, &lt;a href="http://findbugs.sourceforge.net/"&gt;findbugs&lt;/a&gt;, &lt;a href="http://pmd.sourceforge.net/"&gt;PMD&lt;/a&gt;) to tell me when I do silly things in my code&lt;br /&gt;- &lt;a href="http://junit.org/"&gt;JUnit &lt;/a&gt;for testing&lt;br /&gt;- &lt;a href="http://xmlbeans.apache.org/"&gt;XMLBeans &lt;/a&gt;for XML parsing (oh how I hate parsing - yay tools that do it for you!)&lt;br /&gt;- &lt;a href="http://cobertura.sourceforge.net/"&gt;Cobertura &lt;/a&gt;for code coverage (to see what I forgot to test!)&lt;br /&gt;- &lt;a href="http://www.eclipse.org/eclipselink/"&gt;EclipseLink &lt;/a&gt;for &lt;a href="http://java.sun.com/javaee/technologies/persistence.jsp"&gt;JPA &lt;/a&gt;so I don't have to write a massive amount of &lt;a href="http://java.sun.com/javase/6/docs/technotes/guides/jdbc/index.html"&gt;JDBC &lt;/a&gt;code (ick)&lt;br /&gt;&lt;br /&gt;2) update to the latest &lt;a href="http://netbeans.org/"&gt;NetBeans&lt;/a&gt; (6.8) on the development machines&lt;br /&gt;&lt;br /&gt;3) Get approval from Judy to post this blog - oh wait I am not getting approval!&lt;br /&gt;&lt;br /&gt;Once that is all done I'll be able to start version 0.0.0 of something, which will be first end-to-end release of some code that does something simple (like &lt;a href="http://en.wikipedia.org/wiki/Hello_world_program"&gt;Hello, World!&lt;/a&gt;) - hopefully I can do that tomorrow since it'll require setting up some stuff on the test server and on the production server.&amp;nbsp; If all goes well there will be something on "tofubeer.terratap.com" tomorrow (of course I need to go register that name now...).&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8386036339756925674-5815757674459515875?l=tofubeer.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://tofubeer.blogspot.com/feeds/5815757674459515875/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://tofubeer.blogspot.com/2010/01/welcome-to-machine.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8386036339756925674/posts/default/5815757674459515875'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8386036339756925674/posts/default/5815757674459515875'/><link rel='alternate' type='text/html' href='http://tofubeer.blogspot.com/2010/01/welcome-to-machine.html' title='Welcome to the Machine (Tools for Java Developers)'/><author><name>TofuBeer</name><uri>http://www.blogger.com/profile/17555313388131451916</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/_x_xRpNcK438/Sz_AD0IUa5I/AAAAAAAAAAM/Xq9ClBTP-fE/S220/duke.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8386036339756925674.post-4391906497941957113</id><published>2010-01-02T13:18:00.000-08:00</published><updated>2010-01-14T11:12:59.639-08:00</updated><title type='text'>A Saucerful of Secrets (Startup)</title><content type='html'>Things I cannot talk about... upcoming products.  Things I can talk about... what I need to do to get said products started!&lt;br /&gt;&lt;br /&gt;So far have started set up the development environment:&lt;br /&gt;&lt;br /&gt;- Snow Leopard Server running network services (catbert)&lt;br /&gt;- Ubuntu server running subversion and other devtools (dilbert)&lt;br /&gt;- CentOS server running as the test environment (ratbert).&lt;br /&gt;&lt;br /&gt;(look Ma no Windows :-)&lt;br /&gt;&lt;br /&gt;The obvious question would be what sort of applications?  Well that is a secret for now - but they will be coming to a smart phone near you soon!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8386036339756925674-4391906497941957113?l=tofubeer.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://tofubeer.blogspot.com/feeds/4391906497941957113/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://tofubeer.blogspot.com/2010/01/saucerful-of-secrets.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8386036339756925674/posts/default/4391906497941957113'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8386036339756925674/posts/default/4391906497941957113'/><link rel='alternate' type='text/html' href='http://tofubeer.blogspot.com/2010/01/saucerful-of-secrets.html' title='A Saucerful of Secrets (Startup)'/><author><name>TofuBeer</name><uri>http://www.blogger.com/profile/17555313388131451916</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://1.bp.blogspot.com/_x_xRpNcK438/Sz_AD0IUa5I/AAAAAAAAAAM/Xq9ClBTP-fE/S220/duke.png'/></author><thr:total>1</thr:total></entry></feed>
