tag:blogger.com,1999:blog-116964522024-03-12T20:51:09.243-07:00codecraft blogby john troxel. code, software architecture, and rapid developmentUnknownnoreply@blogger.comBlogger39125tag:blogger.com,1999:blog-11696452.post-14827684638614989112022-02-24T07:54:00.007-08:002023-02-27T19:06:30.651-08:00In Search of "Code Design"<h2 style="text-align: left;"><span style="background-color: white; color: #292929; font-family: charter, Georgia, Cambria, "Times New Roman", Times, serif; font-size: 20px; letter-spacing: -0.06px;">I’m an “agent" now? I must be important...</span> </h2><p><span color="rgba(0, 0, 0, 0.9)" face="-apple-system, system-ui, "system-ui", "Segoe UI", Roboto, "Helvetica Neue", "Fira Sans", Ubuntu, Oxygen, "Oxygen Sans", Cantarell, "Droid Sans", "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Lucida Grande", Helvetica, Arial, sans-serif" style="background-color: white; font-size: 16px; white-space: pre-wrap;">I forgot to cross-post here... I wrote a thing about "code design," it's a little snarky but hopefully not too much so: </span></p><h4 style="text-align: left;"><span color="rgba(0, 0, 0, 0.9)" face="-apple-system, system-ui, "system-ui", "Segoe UI", Roboto, "Helvetica Neue", "Fira Sans", Ubuntu, Oxygen, "Oxygen Sans", Cantarell, "Droid Sans", "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Lucida Grande", Helvetica, Arial, sans-serif" style="background-color: white; font-size: 16px; white-space: pre-wrap;"><a href="https://medium.com/@johntrox/in-search-of-software-design-79d06ad4ceed">"In Search of: Code Design"</a></span></h4><p><span color="rgba(0, 0, 0, 0.9)" face="-apple-system, system-ui, "system-ui", "Segoe UI", Roboto, "Helvetica Neue", "Fira Sans", Ubuntu, Oxygen, "Oxygen Sans", Cantarell, "Droid Sans", "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Lucida Grande", Helvetica, Arial, sans-serif" style="background-color: white; font-size: 16px; white-space: pre-wrap;"><br /></span></p>Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-11696452.post-60618221790164958802015-07-10T16:17:00.001-07:002022-02-24T07:42:45.604-08:00Advanced Memcached at Flickr<h1 class="entry-title" style="background-color: white; border: 0px; clear: both; font-family: Arial, sans-serif; font-size: 36px; line-height: 48px; margin: 0px; outline: 0px; padding: 15px 0px 0px; vertical-align: baseline;">Optimizing Caching: Twemproxy and Memcached at Flickr</h1>... a post I wrote about some work I did at Flickr: <a href="https://code.flickr.net/2015/07/10/optimizing-caching-twemproxy-and-memcached-at-flickr/">code.flickr.net</a>. TLDR; I delivered a couple key infrastructure pieces providing a more resilient caching infrastructure, propagation of cache clears across data centers, and reduced user latency across the board.<div><div class="separator" style="clear: both; text-align: center;"><a href="https://code.flickr.net/2015/07/10/optimizing-caching-twemproxy-and-memcached-at-flickr/" style="margin-left: 1em; margin-right: 1em;"><img alt="" data-original-height="291" data-original-width="596" height="223" src="https://blogger.googleusercontent.com/img/a/AVvXsEg9M6oVw7i7evuXLVXWmRH4Wbsu_yvIUvW_5vMFT8j2NcBc8PYmJU-atlWcZW9d7VyAKmL3WbmFF0rMQbqP8CwWoa-pvm6UV20aXOJXpCfkQRFm9XYCP08iKNg48Roz6VpS0qOLahsMGLLlQg_XhZiUOOw-68GYqce9OuhR0BWWhSqUnFE7sg=w457-h223" width="457" /></a></div><br /><br />
<div class="separator" style="clear: both; text-align: center;"><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/a/AVvXsEg-xNsJYru9S4djJ54o6B9KO53zGiIWS7FXHK6W8XGAEigRmeiMCMoSN5N2i2xAVLIAWvhniZZUnNTHXzYTSGMDNZsQf9fPfwCfb4lASabXQMcjQLumGFJlNF1-ctbE7ZesVzRnchHDnJD9Vo_hyBFnqr4LooIfO5QLQk27nnQatAgTs8q-pQ" style="margin-left: 1em; margin-right: 1em;"><img alt="" data-original-height="561" data-original-width="1092" height="306" src="https://blogger.googleusercontent.com/img/a/AVvXsEg-xNsJYru9S4djJ54o6B9KO53zGiIWS7FXHK6W8XGAEigRmeiMCMoSN5N2i2xAVLIAWvhniZZUnNTHXzYTSGMDNZsQf9fPfwCfb4lASabXQMcjQLumGFJlNF1-ctbE7ZesVzRnchHDnJD9Vo_hyBFnqr4LooIfO5QLQk27nnQatAgTs8q-pQ=w595-h306" width="595" /></a></div><br /><br /></div>
<br />
<br /></div>Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-11696452.post-87169574102596494052015-03-16T19:36:00.001-07:002015-03-17T19:32:55.640-07:00Javascript and Rails, together at last (on Vert.x)<h3>
Vert.x: Catching My Attention</h3>
I recently attended an awesome <a href="http://www.meetup.com/DenverJavaUsersGroup/events/214551062/">talk</a> by <a href="https://www.linkedin.com/in/thesteve0">Steve Pousty</a> on Vert.x, and I found this technology so intriguing, I had to dig deeper myself. This post summarizes why I think Vert.x is so promising, and takes a look at my own exploration of the technology.<br />
<br />
<a href="http://vertx.io/">Vert.x</a> is a non-blocking "application platform for the JVM that's designed for modern mobile, web, and enterprise applications." The platform combines the ability to run code in many JVM languages like JavaScript (via Rhino or DynJS), Jython, Jruby, and more; combined with a built-in event bus. What came to mind for me, almost immediately, was the possibility of using JavaScript for the front end code, sending work to Ruby (or other) application components. I'll explain why I think this is so powerful shortly, but first let's talk more about Vert.x and look at the <a href="https://github.com/jtroxel/mystack">demo</a> that I wrote.<br />
<h3>
More About Vert.X</h3>
<div>
I think Vert.x has a really cool combination of features for or creating application servers. I will focus on the two aspects I find most powerful. First are the APIs that "enable you to write non-blocking network enabled applications." Vert.x is a productive abstraction over netty.io, with an API that makes it easy to set up servers. This feature lets one build servers in JS (or whatever), very similar to node.js. There are even projects for running <a href="https://github.com/nodyn/nodyn">node.js</a> and <a href="https://github.com/isaiah/jubilee">Rack</a> applications on Vert.x, but that is a topic for another day.</div>
<div>
<br /></div>
<div>
The second feature of Vert.x that I find so compelling is the built-in, distributed event bus, combined with an actor-like processing model. This allows developers to write clean back-end logic, in whatever language makes sense, and capitalize on concurrent <i>and</i> parallel processing, shielded from the gory details. A flexible deployment model allows you to distribute the pieces how you see fit.</div>
<div>
<br /></div>
<div>
If the potential of these features is still not grabbing you, let's look at the demo, and then I will try to drive it home at the end.</div>
<h3>
</h3>
<h3>
Creating a JavaScript Frontend</h3>
<div>
For my simple demo, I set up a dead-simple server that handles a few routes and responds with ugly plain text. There is not much to it, just a tiny sketch of how a restaurant site with ratings might work. The whole demo is on <a href="https://github.com/jtroxel/mystack">GitHub</a>.<br />
<br /></div>
<script src="https://gist.github.com/jtroxel/5950f90b5fddd11871ab.js"></script>
<br />
<div>
In the previous gist, line 2, we add a route to a routeMatcher object, then proceed to pull out the params in the handler. Later on, we set up a server that handles all the routes:<br />
<script src="https://gist.github.com/jtroxel/a4cdbe296aff372281df.js"></script>
</div>
<h3>
</h3>
<h3>
Adding a Rails Backend</h3>
Back to the route handler in server.js, the following is how we interact with the business logic:
<script src="https://gist.github.com/jtroxel/2598fcfcfdab979cb155.js"></script>
The code above sets up a simple JSON structure and uses the Vert.x send method to put it on the manage-restaurants event bus for a single worker to handle. The worker code is in Ruby, not JavaScript, even though (for this demo deployment model) they are running in the <b>same process</b>. The worker uses Rails ActiveRecord to interact with the database. Here's basically the whole thing:
<script src="https://gist.github.com/jtroxel/f05c1d8466bc29148f7c.js"></script>
This code handles manage-restaurant events, mutating the db for these business events as necessary.
<br />
<h3>
</h3>
<h3>
What's the Big Deal?</h3>
<h4>
... and Future Considerations</h4>
As I teased earlier, I hope that seeing the interaction of the JavaScript UI code and the Ruby back-end would grab your interest. If not, I will try now to underscore why this is so bad-ass.<br />
<br />
I really like the concept of using JavaScript for all UI development: from the client-side MVW logic to the server-side logic that translates between application interfaces and UI semantics. But I also like using Rails (and/or Java) application logic, because of the richness and maturity of the respective ecosystems for building serious stuff. Now it is pretty common to build a node.js front-end and create a RESTful API for application logic, and that is not a bad way to go. However Vert.x provides a model for interop that is both simpler than setting up RESTful service, and also allows the back-end logic to run in the same process. This lets one set up a super simple, single-process application for development and nascent applications, and also scale* rather easily later on.<br />
<br />
In addition to the single-process simplicity afforded by Vert.x, one can also deploy Verticles as separate nodes, and the distributed capability of the event bus will handle the interprocess communication, effectively turning a concurrent application into a parallel one. And changing deployment models should entail little or no change to core logic. I think this is awesome because one can develop quickly as a monolithic-style app, and then deploy as more of a microservices architecture--scalability options are there from the beginning.<br />
<br />
In the future, I want to dig deeper into building application architectures on top of Vert.x (with suitable abstraction of the framework of course). I envision a JS presentation layer where some POJO logic is shared between the client and the server-side, with lightweight TCP communication between them. For the backend logic I want to explore how a <a href="http://blog.8thlight.com/uncle-bob/2012/08/13/the-clean-architecture.html">clean</a> or <a href="http://alistair.cockburn.us/Hexagonal+architecture">hexagonal</a> application layer would look combined with a message bus API. Putting it all together, I have a foggy notion of a new stack that ultimately might have some frameworks or tooling around it. In my head I've been calling it "mystack." Stay tuned for further developments if you like where this is headed.<br />
<br />
*Note: I have not experimented with the scalability of the distributed event bus, but I give Vert.x the benefit of the doubt for now.Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-11696452.post-79299611939823490242014-10-03T11:55:00.000-07:002015-03-17T10:49:02.925-07:00A Rails Enthusiast’s take on MEAN.js<h3>
<span style="background-color: white; font-family: HelveticaNeue-Light, 'Helvetica Neue Light', 'Helvetica Neue', Helvetica, Arial, 'Lucida Grande', sans-serif; font-size: 16px; font-weight: normal;"><a href="http://www.infoq.com/articles/rails-to-mean-js">Is MEAN.js Node's answer to Rails? Following the famous blog demo creation using the MEAN.js stack.</a></span></h3>
<div>
<span style="background-color: white; font-family: HelveticaNeue-Light, 'Helvetica Neue Light', 'Helvetica Neue', Helvetica, Arial, 'Lucida Grande', sans-serif; font-size: 16px; font-weight: normal;">How does developing with MEAN compare to that first Rails app? Pretty fairly, as I found out.</span></div>
<div>
<span style="background-color: white; font-family: HelveticaNeue-Light, 'Helvetica Neue Light', 'Helvetica Neue', Helvetica, Arial, 'Lucida Grande', sans-serif; font-size: 16px; font-weight: normal;"><br /></span></div>
<div>
<span style="background-color: white; font-family: HelveticaNeue-Light, 'Helvetica Neue Light', 'Helvetica Neue', Helvetica, Arial, 'Lucida Grande', sans-serif; font-size: 16px; font-weight: normal;">This is an article I wrote for InfoQ: </span><span style="font-family: HelveticaNeue-Light, Helvetica Neue Light, Helvetica Neue, Helvetica, Arial, Lucida Grande, sans-serif;"><a href="http://www.infoq.com/articles/rails-to-mean-js">http://www.infoq.com/articles/rails-to-mean-js</a></span></div>
Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-11696452.post-35170914504686120202014-02-10T14:30:00.001-08:002014-03-04T10:51:27.564-08:00How to get good software from contractors<h3>
<span style="color: #b45f06;">
OR <i>Working with codecraft (me)</i></span></h3>
<div>
I think I have said before, the <b>purpose</b> of software development is to <b>produce good enough software as quickly and efficiently as possible</b>. Everything I do at codecraft is driven by that principle. But why just "good enough," and what does it mean exactly?</div>
<h4>
Good Enough Software</h4>
<div>
The software created by a project should only be good enough, not more. That sounds crazy, I know. <u>But,</u> if we are trying to get to market quickly and make strategic use of our investments, any bit of extra quality or premature scalability or speculative functionality costs money, money we could spend elsewhere. One has to be serious about how time and money are spent or the competition will clobber you.<br />
<br />
Good enough, then, means finding the balance between present and future costs and benefits. Good enough means investing in what you need most right now, while being conscious of future concerns. Good enough means getting something inperfect in front of users quickly, and worrying about scale and perfection when the system is viable.<br />
<br />
So how do I go about delivering Good Enough, quickly and efficiently? It is all about providing rich, <b>continuous</b> feedback.</div>
<h3>
What I Do</h3>
<div>
<div id="yui_3_7_2_1_1360172738657_21206" style="font-family: arial, helvetica, sans-serif; font-size: 13px;">
<span style="font-style: italic;">Continuous Planning</span></div>
<div id="yui_3_7_2_1_1360172738657_21242" style="font-family: arial, helvetica, sans-serif; font-size: 13px;">
<span id="yui_3_7_2_1_1360172738657_21241">Every day, the plan will change to respond to where we are and what is the most strategic use of time. I usually like to keep a prioritized "feature inventory" in a shared document of tracking system. The client picks priority features, with some elaboration and discussion as necessary, and defines "Stories," pieces of the feature that make reasonable units of work. Stories move from a Ready state to In-Process with further discussion as necessary, and using the principles of Kanban the in-process work at any time is limited to hone productivity. Completed code for a story is captured in the shared repository when finished.</span></div>
<div id="yui_3_7_2_1_1360172738657_21239" style="font-family: arial, helvetica, sans-serif; font-size: 13px;">
<div id="yui_3_7_2_1_1360172738657_21236">
<span id="yui_3_7_2_1_1360172738657_21238"><span id="yui_3_7_2_1_1360172738657_21237"><br /></span></span></div>
<span id="yui_3_7_2_1_1360172738657_21238"><span id="yui_3_7_2_1_1360172738657_21237">
</span></span></div>
<div id="yui_3_7_2_1_1360172738657_21235" style="font-family: arial, helvetica, sans-serif; font-size: 13px;">
<span id="yui_3_7_2_1_1360172738657_21234" style="font-style: italic;">Continuous Communication</span></div>
<div id="yui_3_7_2_1_1360172738657_21219" style="font-family: arial, helvetica, sans-serif; font-size: 13px;">
<div id="yui_3_7_2_1_1360172738657_21218">
<span id="yui_3_7_2_1_1360172738657_21217">Using a tool like Campfire or Flowdock, the entire team can share and recall group communications. Developers will be available continuously (during certain time frames) in this environment.</span></div>
<div id="yui_3_7_2_1_1360172738657_21220">
<br /></div>
</div>
<div id="yui_3_7_2_1_1360172738657_21233" style="font-family: arial, helvetica, sans-serif; font-size: 13px;">
<span id="yui_3_7_2_1_1360172738657_21232" style="font-style: italic;">Continuous Quality</span></div>
<div id="yui_3_7_2_1_1360172738657_21222" style="font-family: arial, helvetica, sans-serif; font-size: 13px;">
<span id="yui_3_7_2_1_1360172738657_21221">All business logic modules will be supported by automated unit tests and shared with the client as desired. The user interface will be supported by a reasonable suite of integration tests. The full test suite should be run before every commit.</span></div>
<div id="yui_3_7_2_1_1360172738657_21223" style="font-family: arial, helvetica, sans-serif; font-size: 13px;">
<br /></div>
<div id="yui_3_7_2_1_1360172738657_21227" style="font-family: arial, helvetica, sans-serif; font-size: 13px;">
<div id="yui_3_7_2_1_1360172738657_21226">
<span id="yui_3_7_2_1_1360172738657_21225"><span id="yui_3_7_2_1_1360172738657_21224" style="font-style: italic;">Continuous Delivery</span></span></div>
<div id="yui_3_7_2_1_1360172738657_21230">
<div id="yui_3_7_2_1_1360172738657_21229">
<span id="yui_3_7_2_1_1360172738657_21228">All completed source code is kept in a shared repository like GitHub and available at any time to the Client. </span><span id="yui_3_7_2_1_1360172738657_21243">I would suggest we use a cloud or PaaS like Heroku or Digital Ocean to host a couple environments, "staging" and the ultimate live site. As soon as possible, the running application will be available in staging. Every bit that is committed into the shared repository will immediately be installed into the staging environment for review. Code is often delivered several times a day.</span></div>
<div id="yui_3_7_2_1_1360172738657_21229">
<br /></div>
<h3>
What I Don't Do</h3>
<div>
I don't tell you what you want to hear. I don't pretend to see the future and act like I know what the optimal solution for the client will look like, months from now, much less how much effort it will take. After all, <a href="http://pragprog.com/magazines/2013-02/estimation-is-evil">Estimation is Evil</a>.</div>
<div>
Rather than basing the relationship on a contract that gives clients a false sense of security about getting what they need, I prefer to set up a relationship based on trust. Trust at a personal level, but more importantly a trust in the practices that we will set up together to ensure the best possible use of time and resources.</div>
</div>
</div>
</div>
Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-11696452.post-15672632587721215222012-10-31T07:50:00.001-07:002013-04-16T10:48:19.902-07:00Using a module to share common association logic in RailsUPDATE: If I did this again, I would consider packaging the code as a Concern<br />
<br />
I recently wanted to DRY up some repetitive Rails association code, similar associations used in multiple models. This gave me the opportunity to figure out a few tricks, like creating a module Class method and using metaprogramming to add dynamically named accessors.<br />
<br />
Anyway, here is the Module:<br />
<script src="https://gist.github.com/3984528.js?file=category_group.rb"></script><br />
...and the client model...<br />
<script src="https://gist.github.com/3984535.js?file=product.rb"></script>Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-11696452.post-24741340153128231702012-08-28T06:22:00.003-07:002023-02-27T19:08:30.609-08:00An old crack at a stream processing framework. WAS: Building procedures with composition<br />
Often developers need to model a multi-step process. Also common is the need to reuse pieces of the process: maybe the steps are the same but the execution of the steps vary for different contexts, or maybe the step flow changes slightly in some cases but the logic of the steps is largely reused.<br />
<br />
One common way developers address this situation is to implement a Template Method pattern. For example, an insurance system might have several similar flows for processing feeds from different sources--partner EDI, consumer web site, provider applications--where many of the steps involved are largely reusable.<br />
<br />
A Template Method basically uses inheritance to share common logic, while varying the implementation of steps by overriding methods representing particular steps. However as the GOF posited and leading developers believe today, one should "favor composition over inheritance." Inheritance abuse is a common and natural side effect of trying too hard to reuse logic the OO-way, but we can do better.<br />
<br />
The essential problem with using inheritance with the Template Method is that the class tree can get pretty ugly if one needs to vary the implementation of steps AND the flow of steps. Also, more often than not, the is-a relationship between common and specialized processors is restrictive and faulty. For example if a processor implementation wanted to extend something else like ActiveRecord.<br />
<br />
What if, rather than using a template method, one could compose flows of steps, where the steps are pluggable members? Another way to build processes that can be reused and extended is with the Strategy pattern, where the algorithm (or steps thereof) are pluggable. Using this approach, the developer creates the structure of the flow in one class but delegates the execution of steps to collaborators.<br />
<br />
Now what if there was a fluent interface for building flows of plugable steps, as well as machinery and conventions for coordinating between steps? Well, that is the idea of Flo: <a href="https://github.com/jtroxel/flo">https://github.com/jtroxel/flo</a><br />
Some of the ideas from Spring Batch and Apache Camel have also inspired my thinking here, but Flo is much simpler and less specialized. I was also motivated by the Unix programming model, little tools that do one thing well, strung together with pipes.<br />
<br />
Note that Flo is a work in progress, awaiting her first real application.<br />
<div>
<br /></div>
Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-11696452.post-11559479659965786332012-06-18T09:04:00.000-07:002013-01-17T09:15:54.196-08:00Controlling Rails mass-assignment with whitelists and :asRails 3.2 has some flexible features for controlling mass-assignment. A little Gist I put together demonstrates:<br />
<script src="https://gist.github.com/2948700.js"></script><br />
<a href="https://gist.github.com/2948700">whitelisting and roles: https://gist.github.com/2948700</a>Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-11696452.post-3284227023350115892012-06-12T06:44:00.000-07:002012-06-12T06:47:08.951-07:00Objects in Practice - Testing ObjectsTest Doubles in Ruby and Groovy: <a href="https://github.com/jtroxel/Objects-In-Practice/blob/master/test-objects/readme.md">https://github.com/jtroxel/Objects-In-Practice/blob/master/test-objects/readme.md</a>Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-11696452.post-53403992457721411242011-11-29T08:47:00.000-08:002012-06-12T06:46:19.718-07:00Search as Data StoreA while back I came across <a href="http://blog.sematext.com/2011/09/09/the-state-of-solandra-summer-2011/">Solandra</a>, and began wondering about using it as a general purpose store for a typical content-heavy webapp. The idea was based on a pretty vague notion that combining search with NoSQL would be powerful. What Solandra does is bolts the <a href="http://lucene.apache.org/solr/">SOLR</a> search engine onto <a href="http://cassandra.apache.org/">Cassandra</a> instances, resulting in a distributed search with all the data persisted in a NoSQL store.<br />
<br />
In poking around, I've found that it is not unheard of to use SOLR as a web backend. Perhaps the most prominent example would be The Guardian's use of <a href="http://www.lucidimagination.com/blog/2010/04/29/for-the-guardian-solr-is-the-new-database/">SOLR for their "Content API."</a> There was also supposedly a <a href="http://sparse.ly/">twitter-like example</a> that <a href="http://blog.sematext.com/2010/02/09/lucandra-a-cassandra-based-lucene-backend/">"uses the Lucandra store exclusively and does not use any sort of relational or other type of database"</a>, though the link did not work as I wrote this (Lucandra is the predecessor to Solandra).<br />
<br />
Why not just stuff everything into SOLR? It is effectively a document store with powerful and fast queries. Sure it does not support transactions and the data is not normalized in a relational sense. But do you need those things for content? What I mean by content is dynamic stuff that might be edited by humans or updated by feeds: articles, comments, tags, product descriptions, locations; data that is viewed a lot but edited infrequently, not super structured or requiring crazy integrity. With the Cassandra backing, you should at least get durability and eventual consistency on the data that you shove into SOLR (Solandra).<br />
<br />
I guess now I will have to give it a try, see where the trade-offs are in practice between search, NoSQL, and Relational stores on a real content project. Who's got one for me? :)Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-11696452.post-4267118807915900382011-11-15T15:57:00.000-08:002011-12-15T15:36:25.901-08:00Objects in practice: class basics in Java and RubyThis post looks at basic class and inheritance mechanisms in both Java and Ruby. I might to decide to expand this into a series, illustrating basic programming building blocks using Java, Ruby, and Scala; we'll see how it goes.<br />
<br />
For this post, we are modeling employees of a software company, something like:<br />
<div class="separator" style="clear: both; text-align: center;"></div><div class="separator" style="clear: both; text-align: center;"><a href="http://yuml.me/diagram/scruffy/class/%5BManager%5D%3C%3E-reports%5BEmployee%5D,%20%5BEmployee%5D%5E-%5BManager%5D,%20%5BEmployee%5D%5E-%5BDeveloper%5D" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" height="152" src="http://yuml.me/diagram/scruffy/class/[Manager]%3C%3E-reports[Employee],%20[Employee]%5E-[Manager],%20[Employee]%5E-[Developer]" width="392" /></a></div>(via YUML: <br />
<a href="http://yuml.me/diagram/scruffy/class/edit/%5BManager%5D%3C%3E-reports%5BEmployee%5D,%20%5BEmployee%5D%5E-%5BManager%5D,%20%5BEmployee%5D%5E-%5BDeveloper%5D">edit</a>)<br />
<br />
<br />
<b>NOTE: </b>This is NOT a good design--doesn't allow employees to fulfill multiple roles, doesn't account for changes over time--but I'll show better designs in later Howtos.<br />
<br />
So, the general idea is that we want to reuse some behavior and also provide some specialized behavior. Probably the most simplistic way to do this in OO languages is to set up concrete inheritance and leverage polymorphism. I'll show how this is done in Java and Ruby, and the complete code can be found at <a href="https://github.com/jtroxel/Polyglot-Howto">github</a><br />
<br />
<b>JAVA</b><br />
<br />
A simple parent class, provides startDate member and monthsOnJob to subclasses: <br />
<pre class="prettyprint"><code class="language-java">
public class Employee {
private Date startDate;
public Integer monthsOnJob() {
Integer months = 0;
// Do the math
return months;
}
public String jobDescription() {
return "New employee"; // Default description, will be overriden by subclasses
}
}
</code></pre>A simple subclass, adding behavior to the super and overriding the description<br />
<pre class="prettyprint"><code class="language-java">
public class Developer extends Employee {
@Override
public String jobDescription() {
return "Developer: " + listTechnicalSkills();
}
private String listTechnicalSkills() {
String skillStr = "";
// TODO get skills from getTechnicalSkills and build string
return skillStr;
}
private Collection technicalSkills;
public Collection getTechnicalSkills() {
return technicalSkills;
}
public void setTechnicalSkills(Collection technicalSkills) {
this.technicalSkills = technicalSkills;
}
}
</code></pre>Another specialization, Manager has Employees as reports<br />
<pre class="prettyprint"><code class="language-java">
public class Manager extends Employee {
Collection<employee> reports;
@Override
public String jobDescription() {
return "Suit";
}
public Collection<Employee> getReports() {
return reports;
}
}
</code></pre><br />
<b>Ruby</b><br />
Now the parent class in Ruby<br />
<pre class="prettyprint"><code class="language-java">
class Employee
attr_accessor :start_date # method that creates accessors
def initialize(start)
@start_date = start
end
def months_on_job
# Math is easy
(Date.today.year*12 + Date.today.month) - (@start_date.year*12 + @start_date.month)
end
def job_description
"New employee"
end
end
</code></pre>A Ruby Developer class<br />
<pre class="prettyprint"><code class="language-java">
class Developer < Employee
attr_accessor :technical_skills
def initialize(start)
super(start)
@technical_skills = []
end
def job_description
ret = "Developer: "
@technical_skills.each {|skill| ret << " ${skill"}
end
end
</code></pre>The Manager<br />
<pre class="prettyprint"><code class="language-java">
class Manager < Employee
attr_accessor :reports # accessor
def initialize(start)
super(start)
@reports = []
end
def job_description
"Suit"
end
end
</code></pre>Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-11696452.post-27849423482119102312011-10-24T19:59:00.000-07:002011-10-24T20:01:13.619-07:00John's Independent Forray v3.0After 3.5 years with Rearden, I decided to go back to freelancing, for the 3rd time.<br />
<br />
This time around I am going by codecraft solutions. I am presently subing with <a href="http://haughtcodeworks.com/">Marty Haught</a> and intend to continue for some time. Eventually though I intend to run my own projects too.<br />
<br />
That's the plan, stay tuned.Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-11696452.post-1158811574846184982006-09-20T21:05:00.000-07:002006-11-08T08:38:51.583-08:00What's So Great About Rails?OK, so now I guess I am becoming a "Rails Guy." At least, I have been doing some Ruby on Rails programming lately and am generally very impressed.<br /><br />It is still Web programming, there are no major paradigm shifts here. However, Ruby on Rails is an example of how a lot of little things done right can really add up. Ruby is a fine scripting language, improving upon popular languages like Perl and Python. And Rails is an example of getting the little details of Web programming right. Rails is optimized (as I see it) for (1) Productivity and (2) Maintainability. The following are what I really like:<br /><ul><li>The clean, simple ActiveRecord ORM layer.</li><li>A full-fledged yet simple MVC that is easy to comprehend and get around in.</li><li>Sensible defaults and very little configur-bation; "convention over configuration."</li><li>A good job of making the most common tasks simple; the 80/20 rule.</li><li>"rake migrate" is the coolest way to manage schemas that I have seen.</li></ul>So, is Rails the answer to everything? Of course not, you won't find sweeping generalizations here. As always, it depends on *specific* requirements. Ruby and Rails are geared toward fast and simple development and maintenance. Java and JEE technologies generally have not prioritize these factors as highly as Enterprise requirements, e.g. massive scalability, security, etc. And I am not saying that one or the other stack is incapable of solving a kind of problem, rather that it is a matter or priorities, focus, and fit.<br /><br />So I do like Rails a lot, I think it is probably the best solution for many small-medium sized webapps. But it is not necessarily a replacement for Java, especially in the enterprise. The trick is for decision-makers to weight their needs for big E Enterprise requirements against speed and simplicity.Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-11696452.post-1158725643481309472006-09-19T20:59:00.000-07:002006-09-19T21:39:57.843-07:00Productive Editing and EclipseI went to a great presentation by Neal Ford last week at the DJUG, entitled the <a href="http://www.nealford.com/downloads/conferences/2006_nfjs_canonical/Neal_Ford-The_Productive_Programmer-slides.pdf">Productive Programmer</a>. Neal is a sharp guy, a good speaker, and a solid thinker on improving productivity. Go ahead and CRTL-Enter nealford in your address bar to check out his site (you'll see what I mean).<br /><br />The talk was a bit of a wake-up for me. His premise is that the rise of the IDE has made programmers, well, lazy (my words, I don't think he went so far). I realized that I have let some old but valuable skills languish in the past few years. So Neal's talk has inspired me to sharpen the saw back up. For example, I have made the decision that Ruby will be my scripting power tool moving forward (used to be Perl), and I will not shy away from opportunities to explore automation (even if it is initially just exercise).<br /><br />Another point that resonated with me was the idea of the "perfect" editor. I do think that I am now as productive over all in Eclipse as I used to be in Emacs (with a side trip through NetBeans). But Neal hit on two things that <span style="font-weight: bold;">are</span> missing: Multiple cut/paste buffers (kill-loop in Emacs) and editor scripting. Though I am intrigued by the lightweight JEdit, I am determined to stay in Eclipse and make the best of it. I think that surely these two deficiencies can be addressed.<br /><br />On the multiple buffers front, I quickly came up with an answer that works for me: <a href="http://www.nakka.com/soft/clcl/index_eng.html">CLCL</a>. This tool is actually a utility that caches your Windows clipboard. So CRTL-C still works like normal, but you can also reach back in time and paste something from 30 cuts ago. Sounds trivial, but it can change the way you edit.<br /><br />As for the scripting integration, I haven't looked very far. <a href="http://www.jroller.com/page/prane">Prashant Rane's blog</a> led me to <a href="http://www.eclipse.org/dash/monkey-help.php?key=installing">Eclipse Monkey</a>, which looks interesting--it's Javascript, which I can defnitely code. I might keep looking, though, for something that provides editor hooks for Ruby, Groovy, or BeanShell. I'll post again if I find the silver bullet.Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-11696452.post-1146163073255522952006-04-27T11:36:00.000-07:002006-09-12T19:47:46.916-07:00Shameless Promotion 4: Rapid, Affordable Application Development<span style="font-family:verdana;">I am available to help Clients develop applications cheaply and quickly, applications that help them to reach more customers and reduce costs. I can help clients use the Web to make breakthroughs in marketing, sales, and operations.<br /><br />I have built dozens of successful applications for the Web and other environments. I can provide hands-on expertise across the software development lifecycle: from strategy and requirements to architecture and design to development and testing. </span><span style="font-family:verdana;">I also provide project management and "general contractor" services, so I can bring the right talent to the table for most any web development project.</span><br /><span style="font-family:verdana;"><br />The following is a quick summary of the skills and capabilities I provide to help you achieve robust solutions quickly and at affordable rates:<br /></span><ul><li><span style="font-family:verdana;">Experience in online communication, eCommerce, and improving efficiencies.</span></li><li><span style="font-family:verdana;">Technical lead, architect, and developer experience on dozens of projects, including complex applications for Sheraton Hotels, Travelocity, Budget Rent-A-Car, and the Veteran's Administration.</span></li><li><span style="font-family:verdana;">Programming experience in Java (5+ years), C (3), VB/ASP (3), Perl (2), and lately Ruby.</span></li><li><span style="font-family:verdana;">Effective, hands-on skills as a software engineer, architect, and business/systems analyst.</span></li><li><span style="font-family:verdana;">MBA and a Bachelor's in Computer Science.</span></li><li><span style="font-family:verdana;">Extensive network of software and Design professionals for general contracting services.</span></li><li><span style="font-family:verdana;">Very competitive rates, for myself and subcontractors.</span></li></ul><p><span style="font-family:verdana;">My </span><a href="http://architechie.blogspot.com/2005/08/shameless-promotion-2-johns-resume.html"><span style="font-family:verdana;">Resume</span></a><span style="font-family:verdana;"> describes my skills in much more detail. I'd love to make your development project a huge success, drop me a line if you are interested.</span></p><p><span style="font-family:verdana;">- John</span></p><p><a href="mailto:jtroxel@yahoo.com"><span style="font-family:verdana;">jtroxel@yahoo.com</span></a></p>Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-11696452.post-1146086384240283652006-04-26T14:00:00.000-07:002007-05-11T05:40:25.666-07:00Software Success Factor #1: Manage for Agility UPDATEDThe ability of an organization to Manage for Agility is one of the most important success factors for modern software development. This factor encompasses the critical role that Management--or the project Client or Sponsor--plays in Iterative Development. In this post, I will attempt to address what this factor entails and how it is accomplished. I will also briefly recap why this management style is superior. I have yet to complete the <a href="http://architechie.blogspot.com/2006/04/software-success-reference-model.html">Overview of the Reference Model</a>, but Agile Management is so important that I wanted to flesh out this success factor first.<br /><br /><strong><span style="font-size:130%;">What</span></strong><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://bp1.blogger.com/_BfzztH3i2hI/RkRjkTHOg6I/AAAAAAAAAAc/HbuZFSUdLvo/s1600-h/AgileManagementOverview.jpg"><img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer;" src="http://bp1.blogger.com/_BfzztH3i2hI/RkRjkTHOg6I/AAAAAAAAAAc/HbuZFSUdLvo/s400/AgileManagementOverview.jpg" alt="" id="BLOGGER_PHOTO_ID_5063281356328305570" border="0" /></a><br />Iterative development is perhaps the key attribute of modern software success, but without management support it is impossible. To manage for agility, leaders must go against many traditional management styles and ingrained practices. It is a natural for successful business people to try to avoid future change through detailed planning and up-front analysis, but changes are inevitable. Trusting the team and the process to produce the best solution, allowing the scope, the design, and even the process to <em>emerge</em>, is what it means to Manage for Agility.<br /><br /><span style="font-size:130%;"><strong>How</strong></span><br />To manage agile projects, sponsors must resist the desire to plan and design the entire project before starting any development. To be agile, management must instead embrace a flexible model that responds to changing requirements and an evolving understanding of the solution. Management must trust the process and the team to produce top quality software, without a relying on a rigid scope.<br /><br />Often it is the "commercial Model," contracts, SOWS, etc., that most influences the interaction between management and the project team. To manage for agility, the commercial model must provide for evolving scope and design. Put another way, attempting to fix the scope in agreements up-front is simply at odds with an agile style. When using consultants or contractors, a Time-And-Materials approach allows for the most agility, or the agreement can employ separate SOWs created at the start of each iteration. Another approach offered by Kent Beck is the use of "<a href="http://www.plonesolutions.com/about/OptionalScopeContracts.pdf">Optional Scope Contracts</a>."<br />It is also important to understand that agile does not mean that no planning or requirements are done up front. The project still needs a first cut at the inventory of requirements--e.g. a Scrum backlog or a Use-case survey--that is the source from which iteration requirements are selected, refined, and built. An agile project can also develop a detailed, "pro-forma" project plan, but managers should not feel compelled to stick to the original as the team adjusts to accumulating change.<br /><br /><span style="font-size:130%;"><strong>Why</strong></span><br />Why should managers buy into this approach, when traditional project management techniques have worked on all kinds of projects, from construction to aerospace engineering? Because software development is fundamentally different from construction or engineering, and treating it like these disciplines magnifies the risk of failure, raises costs, and produces worse software.<br />Change is unavoidable in Software Development, more so than most any field. <a href="http://www.netobjectives.com/events/download/latest/dpaglenv_ppt.pdf">Alan Shalloway</a> made the claim, at a recent <a href="http://www.agiledenver.org/">Agile Denver</a> meeting, that software development is not like building a bridge; it is more like building the <em>first</em> bridge... or the design phase of a bridge project. An analogy is also often drawn between construction and software development. However, many experts claim that <a href="http://www.flashline.com/Content/re/craftscience1.jsp?sid=1108371751587-3565825807-102#5">software development is essentially <u><strong>all</strong></u> design</a> work, and the only step that is really like construction is the compile/build cycle.<br />The highly successful <a href="http://jeffsutherland.com/scrum/2004/05/early-history-of-scrum-first-scrum.html">Scrum process is based on proven new-product development</a> processes used by Japanese companies. Indeed, the Scrum proponents and many others have claimed, accurately I believe, that software development is very like new product development. If we look at software development as roughly analogous to the design and development of a new kind of car, or a new consumer electronics gadget, it becomes clear that the nature of the process is unpredictable and should be managed accordingly. Agile management uses an <a href="http://www.controlchaos.com/download/Living%20on%20the%20Edge.pdf">empirical</a> process management approach to produce a better product. One need look no further for evidence than the difference between American cars and Japanese, at least until very recently.<br /><a href="http://alistair.cockburn.us/crystal/articles/asdboi/asd1businessofinnovation.htm">Alistair Cockburn expands on the idea</a> of "responding to change over following a plan:"<br /><blockquote><p>...traditional process management—by continuous measurement, error identification, and process refinements—strove to drive variations out of processes. This approach assumes that variations are the result of errors. Today, while process problems certainly cause some errors, external environmental changes cause critical variations. Because we cannot eliminate these changes, driving down the cost of responding to them is the only viable strategy. Rather than eliminating rework, the new strategy is to reduce its cost.</p><p>[NOTE: I think he means <em>code</em> rework--Big Up-Front planning and design <em>will</em> result in more rework of other work products, assuming the effort is not wasted entirely as these products are abandoned.]</p></blockquote><br /><p>Business needs, priorities, understanding of user needs, expertise with the<br />technical platform, market forces, and available technologies... All of these<br />can and usually do change over the life of a project. Agile management rolls<br />with these changes and capitalizes on them to make the best software possible.<br />Smart project sponsors can use agile management to build better software for<br />less money.</p>Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-11696452.post-1145033231444093462006-04-14T09:45:00.000-07:002016-08-19T09:31:48.385-07:00The Software Success Reference Model - OverivewHere, again, is my Reference Model: a 30,000 ft. view of software success. This post will provide an overview of the categories from the model--sort of a <em>taxonomy</em> of success. See my <a href="http://architechie.blogspot.com/2006/03/software-development-success-reference.html">previous post</a> for more information on how I derived this model.<br />
<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
</div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://c4.staticflickr.com/2/1496/25286326299_b73c0993ef_c.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="480" src="https://c4.staticflickr.com/2/1496/25286326299_b73c0993ef_c.jpg" width="640" /></a></div>
<br />
<strong><span style="font-size: 130%;">Groupings</span></strong><br />
<strong><span style="font-size: 130%;"><span style="font-size: 100%;">Organization and Project Management</span></span></strong><br />
Perhaps this should be entitled simply Organization and Management. This grouping deals with factors that are beyond the scope of any project team--organization and management at the highest levels.<br />
<br />
<strong>Project Team</strong><br />
These factors deal more specifically with the project team involved directly with producing the software.<br />
<br />
<strong>Iterative Development</strong><br />
This category contains factors that relate to producing software in an iterative, incremental, adaptive manner.<br />
<br />
<strong>Productive Culture</strong><br />
Factors dealing with the kind of people the Organization employs and how the Organization fosters a culture that promotes productivity.<br />
<br />
<strong>Productive Practices</strong><br />
Specific practices that help the Project Team develop software efficiently.<br />
<br />
<strong>Software Engineering (for Large Projects)</strong><br />
Factors necessary for projects with a large number of developers and/or critical consequences of failure.<br />
<br />
<strong><span style="font-size: 130%;">Factors</span></strong><br />
<span style="font-size: 100%;"><strong>Manage for Agility</strong></span><br />
This factor encompasses the critical role that Management--or the Client--plays in Iterative Development. Leadership must be willing to launch a project without detailed plans or specs, and trust the team and the process. Further, project clients must realize that the agile approach is a Good Thing, allowing the team to respond nimbly to a changing world, and producing more relevant software in less time. <br />
<strong>Deliver Value Quickly & Often</strong><br />
Another aspect of Iterative Development, this factor focuses on the ultimate goal of software development: working software. Teams must focus on producing working software from the very first iteration, and keeping implementation as relevant to the needs as possible by avoiding unnecessary interim work products and long time lags.<br />
<strong>Continuously Learn & Optimize</strong><br />
The final component of Iterative Development is the concept of continuous improvement. Iterations afford the team with the opportunity to exercise all lifecycle activities in short bursts. This means they can reflect, learn, and optimize their process and practices with each cycle.<br />
<strong>Empower the Project Team</strong><br />
Also solely in the Management arena, the client of the project must provide the project team with the tools, resources, and support necessary to succeed. As much as possible, the team must be allowed to organize and direct itself however necessary to deliver the requirements.<br />
<strong>Enable Open Communication</strong><br />
<strong><span style="font-weight: normal;">Software development is inherently a team design activity. Communicating ideas and building a shared mental model of the solution are critical. Organizations must strive to achieve <a href="http://c2.com/cgi/wiki?OsmoticCommunication">"osmotic" communication</a>, provide access to experts, and involve users throughout the process.</span></strong><br />
<span style="font-weight: bold;">Demand Quality</span><br />
<span style="font-weight: bold;"></span>Teams must develop a high standard of quality as a norm, and internalize quality validations within the team, rather than "throwing" code "over the wall."<br />
<span style="font-weight: bold;">Use More Realistic Specification(s)</span><br />
Just as a picture is worth a thousand words, the richer, higher-fidelity one can achieve in software specifications the better. Teams should use mock-ups, prototypes, and visual models as much as possible, while still constraining specification to whatever is "minimally sufficient" for the current increment.<br />
<div style="font-weight: bold;">
Use Automation and Tracking Tools</div>
The value of SCM, task & issue tracking, automated tests, etc. is well established. Just do it.<br />
<span style="font-weight: bold;">TODO: </span>Software Engineering factors<br />
<strong><span style="font-weight: normal;"></span><br /></strong>Unknownnoreply@blogger.com2tag:blogger.com,1999:blog-11696452.post-1141331827635260362006-03-02T11:45:00.000-08:002016-08-19T10:38:06.543-07:00Software Development Success Reference Model - BackgroundWhat does it take to run a successful software development project? Success does not come easy, but it can be done. The industry has many success stories, and software development thought leaders have identified the key principles that lead to success. But what are <em>the</em> critical success factors, and what principles find common ground among the experts?<br />
<br />
About 6 months ago, <a href="http://architechie.blogspot.com/2005/09/main-things-for-software-projects.html">I started trying to create a set of success factors</a> that were synthesized from the experts. I have since completely revamped my thoughts. What I ultimately want, for my own purposes, is a "Reference Model" (e.g. the <a href="http://en.wikipedia.org/wiki/OSI_model#Description_of_OSI_layers">OSI 7-Layer</a> Model) that provides some structure with which I can I can think and talk about the various factors that lead to success--independent of any specific methodologies. I hope to be able to say things like "Reflection Workshops in Crystal are one technique to Continuously Learn and Optimize," or "XP provides a system for Iterative Development and Proven Practices, focused on smaller Project Teams."<br />
<br />
I have now spent some more time thinking, and included some more popular, respected sources. The following slide is my Reference Model, a 30,000 ft. view of software success.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
</div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://c4.staticflickr.com/2/1496/25286326299_b73c0993ef_c.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="300" src="https://c4.staticflickr.com/2/1496/25286326299_b73c0993ef_c.jpg" width="400" /></a></div>
<br />
<br />
In future posts, I will provide more details on the individual success factors and how they relate to the work of industry luminaries. So, how did I arrive at this model? I started by taking the most important, highest-level principles and factors from the following excellent resources:<br />
<ul>
<li>The Standish Group's <a href="http://www.standishgroup.com/chaos/intro2.php">CHAOS study</a> [CH1..9]</li>
<li>The <a href="http://www.amazon.com/gp/product/0201571692/sr=8-1/qid=1141331761/ref=sr_1_1/104-3772356-5388753?%5Fencoding=UTF8">Unified Process</a> or <a href="http://www-128.ibm.com/developerworks/rational/library/content/RationalEdge/jan01/WhatIstheRationalUnifiedProcessJan01.pdf">RUP</a> [RUP-1..6]</li>
<li>The SCRUM meta-process (<a href="http://www.controlchaos.com/">web</a>, <a href="http://www.amazon.com/gp/product/0130676349">book</a>) [SC-1..4]</li>
<li>Alistair Cockburn and Crystal methods (<a href="http://alistair.cockburn.us/">web</a>, <a href="http://www.amazon.com/gp/product/0201699699">book</a>, <a href="http://www.amazon.com/gp/product/0201498340">book</a>) [AC-1..7]</li>
<li>eXtreme Programming (<a href="http://www.extremeprogramming.org/">web</a>, <a href="http://www.xprogramming.com/">web</a>, <a href="http://www.amazon.com/gp/product/0201616416">book</a>) [XP-1..5]</li>
<li>My own experience on dozens of successful projects [JT-1..6]</li>
</ul>
There were several steps between extracting the critical success factors from these sources and defining my "nutshell" view, but the following slide captures the start of my reasoning. This is an "affinity diagram" that attempts to consolidate all the factors into logical groupings.<br />
<br />
<a href="http://static.flickr.com/30/109408444_8a6c21482e_o.gif"><img src="http://static.flickr.com/30/109408444_8a6c21482e_o.gif" height="480" width="640" /></a><br />
<br />
Comments are most welcome.Unknownnoreply@blogger.com3tag:blogger.com,1999:blog-11696452.post-1137004711082331632006-01-11T10:24:00.000-08:002006-02-10T16:57:28.766-08:00New Frontiers of Enterprise Java DevelopmentI've been thinking lately about trends in enterprise software development, especially in the Java world. Overall, what I see is a change in priority for enterprise software projects: from struggling not to fail completely, to actually excelling and <strong>competing. </strong>The latest technology and tools, along with modern "Agile" development methods, enable companies to really compete on quality and functionality, efficiency and productivity. Smart development organizations can not only avoid failure, but deliver better software more efficiently.<br /><br /><span style="font-size:130%;">Background:</span><br />In the mid-90s, the ubiquitous distribution and instant maintenance capabilities of Web-based applications pushed them to the forefront. When applications moved beyond brochure-ware, a significant problem arose: Teams developing Web-apps could not readily achieve the enterprise requirements, or qualities, necessary for success: performance, scalability, security, etc. So, most of the effort and money spent by development teams went to achieving the necessary enterprise qualities.<br /><br />Teams also struggled with process in the 90s, and to a large extent still do. The fast and loose style of early Web development did not work for mission critical apps, and traditional Methodologies did not work for Web teams. Furthermore, I think the frenetic rate of business and technical change finally killed the notion of viability of traditional, waterfall processes, at least for shops that "got it. "<br /><br />By the late 90s, the major Web application platforms, like J2EE and compliant app. Servers, made it <u>practical</u> to address Enterprise requirements--although not easy or efficient. In addition, the effects of Moore's Law have made it much cheaper to throw more hardware at a solution, reducing the effort involved to handle the scale of enterprise apps. At the same time, Agile project management approaches began to gain visibility, blending the engineering-like discipline with the creative nature of software development.<br /><br />In 2006, I contend, the development tools and frameworks for Web development have largely caught up to the platforms. Creating a robust, scalable, enterprise app no longer necessitates an army of J2EE coders rolling EJBs by hand. Looking forward, ISVs and IT shops just don't have to focus as much on addressing enterprise requirements*. Nor do teams need to struggle with heavy Methodologies--there are new mountains to climb. It is time for Web application development to grow up and act like "real" product development.<br /><br /><span style="font-size:130%;">Competing with Agile Project Management:</span><br />Today, I think any manager who doesn't at least vaguely acknowledge the benefits of an Iterative or <a href="http://www.agilealliance.com/intro">Agile</a> project management approach has been hiding under a rock for several years. Some managers even claim to use these approaches, although few really do it right. Just because a team breaks up the coding for a project into increments, doesn't mean that they are Agile.<br /><br />To improve productivity with process, management must get away from the compulsion to scope, define, and plan the entire project up front. Rather, they must accept and embrace two essential facts:<br /><br /><ol><li>Needs and requirements will change constantly during the project; and</li><li>User needs, technological pitfalls, and team capabilities will never be adequately or accurately understood until the team has gone through the complete lifecycle with one or more slices of the working system.</li></ol><p>Yes, it's a catch-22 situation: Managers have to accept that reality. Managers must embrace change, accept the <a href="http://www.controlchaos.com/old-site/debate.htm">empirical</a> nature of the software development process, and stop trying to do all the planning and specification work up-front. Companies still trying to use linear, silo'd, paper-heavy methods for Web-based apps are dead, whether they realize if or not. To increase productivity, and reduce costs and time-to-market, managers must truly understand and utilize Agile management. I personally think that <a href="http://alistair.cockburn.us/">Alistair Cockburn</a>'s work on Agile development is the most comprehensible. <a href="http://www.controlchaos.com/">Scrum</a> is perhaps the best overarching management view, and <a href="http://www.extremeprogramming.org/">XP</a> provides a system of proven team practices.</p>Another project management "move" that can greatly reduce development cycle times is rapid prototyping. Simply put, exploring and defining requirements with documents is a relatively poor way of getting the system right. More productive projects user "richer" media for definition and validation, and <em>the</em> richest vehicle is a working prototype. For example, a team can develop a <a href="http://www.rubyonrails.org/">Ruby on RAILs</a> prototype to quickly and cheaply explore and validate the functional requirements. Another powerful option for rapid prototyping and validation is <a href="http://www.gorillalogic.com/">Gorilla Logic</a>.<br /><br />The working prototype provides much more comprehensible, complete, and unambiguous information than stacks of documentation, which saves a ton of wasted work downstream. If one accepts that an iteration or increment can be thrown away, then prototyping fits very nicely with Agile methods.<br /><br />Though not strictly a project management move, I also think that automation has tremendous potential to make teams more competitive. That will be the subject for another post. For now, I will simply say that I think that <a href="http://xdoclet.sourceforge.net/xdoclet/index.html">XDoclet</a> is definitely a tool that teams should look at using and extending... and <a href="http://www.omg.org/mda/">MDA</a> tools like <a href="http://www.andromda.org/">AndroMDA</a> show some potential as well.<br /><br /><span style="font-size:130%;">Competing with Richer User Interfaces</span><br />Along with the powerful distribution and update benefits of the Web came with a catch: The capabilities of a browser-based interface, though often visually attractive, are weak. Things like tree browsers, master-detail views, and fine control over interface widgets have generally been painful to achieve. Teams did not have time to work around these issues, and the user experience suffered.<br /><br />Now that the technologies are available that help to take care of enterprise issues with much less effort, teams can make there applications better with richer user interfaces. <a href="http://en.wikipedia.org/wiki/Ajax_(programming)">AJAX</a>, a technique for making asynchronous HTTP requests in the javascript for a page, seems to be a very hot technology of late. For applications that require a highly graphical look and feel, along with better usability, <a href="http://www.macromedia.com/software/flex/">Macromedia Flex</a> is strong player. But the next great client platform, I believe, is <a href="http://wiki.eclipse.org/index.php/Rich_Client_Platform">Eclipse RCP</a>.<br /><span style="font-size:130%;"></span><br />*NOTE: I also think that tools Ruby on RAILS, PHP, ColdFusion, etc. might now present a viable challenge to J2EE and .NET in the Enterprise space, with the right hardware.<br /><br />**NOTE: I really don't have a feel for what is going on in the Microsoft/.NET world. However, to their credit, I think Microsoft has <em>always</em> focused more on productivity than on Enterprise requirements (e.g. VB). How successful they have been on this front is a matter of debate.Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-11696452.post-1133454702908675162005-12-01T08:28:00.000-08:002006-01-10T08:27:04.806-08:00Implementing the Value List Page Iterator PatternUPDATE: <a href="http://acn.waw.pl/mtl/resources/DistributedRowSetIterator.pdf">Brad Long's Article is now found here</a>.<br /><br />I have come across a situation that warrants the use of the "Value List Page Iterator" pattern. First off, the official name is the "Value List Handler," previously known as the "Page-by-Page Iterator." The pattern is part of the <a href="http://java.sun.com/blueprints/corej2eepatterns/Patterns/ValueListHandler.html">Core J2EE Patterns from Sun</a>. I have chosen to use the name "Value List Page Iterator" because the other two names miss the main points: <em>iterating</em> over a value list grouped into <em>pages</em>. The context is situations where a query can return more results than can be presented on one screen, the solution is to allow the user to page through results, like with your typical Web search engine.<br /><br />The code part of the pattern is simple enough, and the data access is nothing fancy--as long as the query is pretty quick, and/or it is acceptable for the app to keep all the results in memory. In my case, the query takes minutes and can return potentially millions of results. I need something that "slices" the data from the db into manageable chunks. <a href="http://uqconnect.net/~zzblong/pattern.pdf">Brad Long of Oracle </a>has written up a pretty <a href="http://uqconnect.net/~zzblong/pattern.pdf">comprehensive treatment of database slicing</a> strategies and offers his own variant of the pattern. Brad nails down the best way to do a slicing query, which I have tweaked:<br /><br /><blockquote><p>SELECT *<br />FROM (SELECT ROWNUM RNUM, INLINE_VIEW.* FROM<br /></p><blockquote><p>(</p><blockquote><p><em>your-select</em></p><p><em>your-where</em></p><blockquote><p>and <em>key-or-order-by-field</em> > <em>lower-boundary</em></p></blockquote><p>[order by <em>order-by-field</em>]</p></blockquote><p>) INLINE_VIEW<br /></p></blockquote><p>)<br />WHERE RNUM < <em>max-range</em><br /></p></blockquote><br />My current problem is that the row-limited (sliced) query takes just as long as the full query. So unless I can figure out some way to effectively cache the query in the database, I am still faced with either sticking all of the results in memory, or taking the performance hit of executing the query multiple times. I am also thinking about a hybrid solution, where I guess at the most likely initial pages and get those at once, then re-execute the query if the user navigates outside the initial results.<br /><br />More to come...Unknownnoreply@blogger.com2tag:blogger.com,1999:blog-11696452.post-1129852534033898892005-10-20T16:54:00.000-07:002005-10-21T15:41:57.520-07:00More on Composition versus InheritanceIs there any more basic OO design decision than this? I started off, like many newer OO programmers, writing code with a lot of concrete inheritance. After some painful lessons and more reading, I now lean heavily toward using composition. So OK. How do we nail down exactly when to use which approach?<br /><a href="http://www.javaworld.com/javaworld/jw-11-1998/jw-11-techniques_p.html"><br />Bill Venners writes about this in JavaWorld</a>. The key criteria to consider is whether the relationship is really an “is-a” relationship, and just <em>how strong</em> the is-a <em>is</em>.<br /><br /><blockquote><p>Make sure inheritance models the is-a relationship [...]</p><p>An important question to ask yourself when you think you have an is-a relationship is whether that is-a relationship will be constant throughout the lifetime of the application and, with luck, the lifecycle of the code. For example, you might think that an Employee is-a Person, when really Employee represents a role that a Person plays part of the time. What if the person becomes unemployed? What if the person is both an Employee and a Supervisor? Such impermanent is-a relationships should usually be modeled with composition.<br /></p></blockquote><br />He continues to point out that both code-reuse and polymorphism can be achieved with composition, and should not be a reason to use inheritance without a strong is-a relationship.<br /><br /><a href="http://today.java.net/pub/a/today/2005/10/3/interfaceSQ5.html?page=last">java.net hosts a discussion on the topic</a>. A common approach is to code using interfaces, and use concrete inheritance in the implementations--in other words, use composition (with interfaces) in your design, use inheritance (for re-use or polymorphism) in the implementation. The is-a rule would still apply to the implementations, of course.<br /><p><a href="http://today.java.net/pub/a/today/2005/10/3/interfaceSQ5.html?page=last"></a></p>Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-11696452.post-1129320754969077702005-10-14T12:38:00.000-07:002010-12-06T08:44:35.087-08:00OO Design Principles: a Quick RundownI wanted to collect some good resources on basic OO design principles, with brief summaries of each, so that I have everything in one place. I hope to ultimately distill these into a one-page "crib sheet.'<br /><br />Some of the best wisdom in OO design is captured by the Gang of Four. Artima has an <a href="http://www.artima.com/lejava/articles/designprinciples.html">interview with Erich Gamma</a> where he discusses the core principles from the intro of Design Patterns:<br /><br /><strong>Program to an Interface, not an Implementation</strong><br /><br /><blockquote>Once you depend on interfaces only, you're decoupled from the implementation. That means the implementation can vary, and that's a healthy dependency relationship. </blockquote><br />Rod Johnson expands on this idea in <a href="http://www.theserverside.com/articles/content/RodJohnsonInterview/JohnsonChapter4.pdf">Chapter 4 of the pre-Spring book</a>, and provides some very well-phrased guidelines:<br /><br /><blockquote><p>Program to interfaces, not classes. This decouples interfaces from their implementations. Using loose coupling between objects promotes flexibility. </p><p>...</p><p></p><p>A few of the many advantages of an interface-based approach include: </p><ul><li>The ability to change the implementing class of any application object without affecting calling code. This enables us to parameterize any part of an application without breaking other components.</li><li>Total freedom in implementing interfaces. There's no need to commit to an inheritance hierarchy. However, it's still possible to achieve code reuse by using concrete inheritance in interface implementations.</li><li>The ability to provide simple test implementations and stub implementations...</li></ul></blockquote><br /><p>Turning back to the Gamma interview...</p><p><strong>Favor object composition over class inheritance</strong></p><blockquote>Composition has a nicer property. The coupling is reduced by just having some smaller things you plug into something bigger... In a subclass you can make assumptions about the internal state of the superclass when the method you override is getting called. When you just plug in some behavior, then it's simpler. That's why you should favor composition. <p>Mr. Johnson expands:</p><p>To clarify the distinction, let's consider what we want to achieve by inheritance. Abstract inheritance enables polymorphism: the substitutability of objects with the same interface at run time. This delivers much of the value of object-oriented design... Concrete inheritance enables both polymorphism and more convenient implementation.</p>...Interface inheritance (that is, the implementation of interfaces, rather than inheritance of functionality from concrete classes) is much more flexible than concrete inheritance.</blockquote><br /><p></p><p><a href="http://www.butunclebob.com/ArticleS.UncleBob.PrinciplesOfObjectOrientedDesign">Robert Martin </a>is another thought leader on core principles, has defined several core principles including the following: </p><p><span style="font-size:130%;"><strong>[NOTE: Still under development]</strong></span></p><p><strong>The Single Responsibility Principle (SRP)</strong></p><blockquote><p>There should never be more than a single reason to change a class... Changes to one responsibility may impact other responsibilities.</p></blockquote><p><strong>Open Closed Principle (OCP)</strong></p><blockquote><p>A module should be open for extension but closed for modification</p><p>Should be able to add behavior without modifying common behavior</p></blockquote><p><strong>Liskov Substitution Principle (LSV)</strong></p><blockquote><p>Subclasses should be substitutable for their base classes</p></blockquote><strong>The Interface Segregation Principle (ISP)</strong><blockquote><p>Interfaces shouldn't have stuff that their clients don't need... Factor interfaces so that clients can use just relevant members</p></blockquote><p><strong>The Law of Demeter</strong></p><blockquote><p>Only talk to your friends who share your concerns... Never call a method on an object that you got from another call or on a global object.</p></blockquote><p><a href="http://c2.com/cgi/wiki?LawOfDemeter">http://c2.com/cgi/wiki?LawOfDemeter</a></p><p><a href="http://www.ccs.neu.edu/home/lieber/LoD.html">http://www.ccs.neu.edu/home/lieber/LoD.html</a></p><p><a href="http://c2.com/cgi/wiki?LawOfDemeterRevisited">http://c2.com/cgi/wiki?LawOfDemeterRevisited</a></p><p><strong>The Dependency Inversion Principle</strong></p><blockquote><p>Modules should depend on abstractions, not concrete modules... Details [controllers?] should depend on abstractions, not the other way around.</p></blockquote><p>"Inversion" in contrast to structured, procedural thinking.</p><strong></strong><p></p>Unknownnoreply@blogger.com1tag:blogger.com,1999:blog-11696452.post-1128960171215913902005-10-10T08:58:00.000-07:002005-10-13T13:57:03.953-07:00Garbage Collection is still importantI think in J2EE, it is easy to get away from the basics of solid Java programming, assuming that the container will take care of the hard stuff for us. Understanding how GC works, however, can be crucial for J2EE applications, expecially high volume or long running runs. I don't know about you, but I might need to brush up on this stuff.<br /><br />Simon Roberts delivered a great primer on the topic to the <a href="http://www.denverjug.org/wiki/Wiki.jsp?page=OOASIG">DJUG Architecture SIG</a> last week, we'll try to get <a href="http://www.denverjug.org/meetings/meetings_05.jsp">slides up on the archive </a>soon.Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-11696452.post-1127487911362284022005-09-23T08:03:00.000-07:002005-10-13T14:00:15.536-07:00The Main Things for Software Projects<a href="http://photos1.blogger.com/blogger/5345/959/1600/SWTheMainThing2.gif"><img style="DISPLAY: block; MARGIN: 0px auto 10px; CURSOR: hand; TEXT-ALIGN: center" alt="" src="http://photos1.blogger.com/blogger/5345/959/400/SWTheMainThing1.gif" border="0" /></a><br />The preceding is a summary slide from a deck I am using to clarify my own approach to methodology. It is a synthesis of recommendations from the CHAOS report, Alistair Cockburn, and my own experience.<br />Essentially, I mapped out the lists of "main things," or critical success factors, provided by CHAOS and Mr. Cockburn, and also made my own list. Then I went through an exercise of correlating and consolidating. This is where I ended up.<br />I think this checklist provides a concise, strategic guide for improving a project's chance of success. More useful still would be individual guides that provide tactical guidance for each of these, probably mapped against key project variables (like Alistair's team size and safety). I'll get right on this in my free time.<br />I also think it would be interesting to check this list against other similar lists from other modern methodologies like RUP, XP, etc. <a href="http://www.denverjug.org/meetings/files/200506_Rhythm.ppt">Rhythm</a>, presented to the DJUG by Brian Boelsterli, looks like an interesting framework that might also have similar factors to consider.Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-11696452.post-1126281504864485512005-09-09T08:58:00.000-07:002005-10-13T14:10:05.573-07:00Rapid Prototyping and Development--Options<p>In this post, I continue my analysis of rapid prototyping for Java Web apps. I see a few essential ingredients necessary for rapid prototyping:</p><ol><li>Fast and simple development of pages and page flow: must be able to easily create pages, get parameters from a submission, do business stuff, go to the next page, and present dynamic data--without manually touching 12 different files.</li><li>Automation of basic CRUD activities: Even in complex apps, so much code fits a basic CRUD template. It is extremely helpful to be able to automate the first cut at this, by specifying model information once in the database, the code, or a neutral spec.</li><li>Quick develop/run cycles: If it takes 45 seconds to see a change to the width of a text field, rapid prototyping is in trouble.</li><li>Extensibility: Whatever cool automatic stuff is done for us, we need to be able deviate from the happy path and customize stuff.</li><li>Anything else I am missing?</li></ol><p>Are there Java technologies that allow developers to skip the enterprise stuff initially, and add it in later with a little refactoring?</p><ul><li>JSPs with code in the pages (or Velocity templates w/out the MVC, etc.): Good for 1 & 3, but ignores 2.</li><li>IDE / Graphical tools: E.g. Java Studio Creator (is there a comparable Eclipse plugin?).</li><li>Rife framework:</li><li>Trails framework:</li><li>Model Driven tools: I looked at <a href="http://www.andromda.org/">AndroMDA </a>a while back, and I don't remember it striking me as a tool for rapid prototyping. But it is probably worth another look. Since I started this post, I have come across <a href="http://www.gorillalogic.com/">Gorilla Logic</a>, which looks very intriguing.</li></ul><p>Are non-Java tools, e.g. Ruby/RAILs, that allow for development that is so inexpensive that we are willing to throw the prototype away?</p><ul><li><a href="http://www.rubyonrails.com/">RAILS </a>claims a 10x productivity advantage over J2EE, and judging by their demo it is at least that. So even if Ruby CGI is insufficient for Enterprise requirements, you can create a throw-away that is worth the effort.</li></ul><p>To Be Continued...</p>Unknownnoreply@blogger.com0