Tuesday, July 29, 2008

Ruby on Rails for Architects #4 - Analysis and Design

Continuation from Ruby on Rails for Architects #3 - Project Setup

So let's talk about the type of system we want to create with out Rails prototype. Being ever so popular, it may be fun to start with a WIKI. Our basic WIKI required the ability to easily create, read and update web pages. We will want a custom look and feel, as well... which will have us diverge from the basic scaffolding of rails, which you will see in a moment. Doing this, you will see how Rails is customizable to meet your individual needs of navigational workflow.

Our WIKI should allow us to create pages, and track the revision history of the page as edits are made. The figure below shows the data model. We will have a table named PAGES which will contain a single record for each page on the WIKI. However the PAGES table will not contain the content of the page. Instead, the content of the page will be stored in a child table named REVISIONS. This is due to the fact that we wish to historically track content as it is edited.


Rails has included with it a mechanism for change control of the database schema known as Migrations. Migrations store meta data about the current schema in the database, allowing for rollback and commit of sql migrations much like you would be expecting of your source code in a repository such as Subversion of CVS.

We will now create the migration for the two tables above. Type in the following command, from the newly expanded rails project you created

ruby script/generate migration wiki

This command fill first create the db/migrate directory, since it does not exist... then it will create a .rb Ruby file in the db/migrate directory with a timestamp, followed by the description we wrote on the command ("wiki").

Inside you will find a class with two methods contained within it. For basics, the self.up method will be the method in which we will be creating the tables, and the self.down is where we will code the functionality which should be executed if this migration was to be undone.

class Wiki < ActiveRecord::Migration

def self.up
create_table :pages do |t|
t.string :name
t.timestamps
end

create_table :revisions do |t|
t.integer :page_id
t.text :content
t.timestamps
end

end

def self.down
drop_table :pages
drop_table :revisions
end

end

The code above creates the two tables described in the database diagram shown above. The t.timestamps command will automatically create the created_at and updated_at columns, and the Rails migrations will automatically create an id column for each table.

Now that we have our database schema coded in our migration file, we can execute the migration to have it applied to the physical database. Since we installed SQLITE in a previous blog entry, our database is already setup and ready to go. Run the migration with the following command in the root of your rails project:

rake db:migrate

While we will wish to customize our Rails application, you will be able to quickly enjoy some fruits of your labor by utilizing the scaffolding functionality built into Rails. The scaffold with create the shell of your application, giving you basic CRUD capabilities.

Scaffold the 'pages' table by performing the following command in your project's root directory:

ruby script/generate scaffold pages name:String

This will create a controller, model, view and test for the 'Page' object, and the views will contain the 'name' parameter for the user to manipulate and store. Run the server:

ruby script/server

And then point your browser to http://localhost:3000/pages to enjoy your working app. In the next portion of this tutorial, we will customize the app into a working WIKI.

Continued in Ruby on Rails for Architects #5 - A Working WIKI

Sunday, July 27, 2008

Ruby on Rails for Architects #3 - Project Setup

Continuation from Ruby on Rails for Architects #2 - Business Case

Now that we have our software installed, it is time to start throwing some code around and creating a project. First we need to determine a project to create... let's create a personal information manager (pim) in Wiki form.

The codename for this project will be 'pim'. Start by initializing the project by running the folowing command:

rails pim

Since Rails was already installed and available on your Classpath from your c:\ruby\bin directory, the rails program just extracted a shell project for you to utilize. Let's take some time to explore and become familiar with our new project's structure.

├───app
│ ├───controllers
│ ├───helpers
│ ├───models
│ └───views
│ └───layouts
├───config
│ ├───environments
│ └───initializers
├───db
├───doc
├───lib
│ └───tasks
├───log
├───public
│ ├───images
│ ├───javascripts
│ └───stylesheets
├───script
│ ├───performance
│ └───process
├───test
│ ├───fixtures
│ ├───functional
│ ├───integration
│ └───unit
├───tmp
│ ├───cache
│ ├───pids
│ ├───sessions
│ └───sockets
└───vendor
└───plugins

You may notice that the project already has a structure which promotes good programming practices. Testing and Documentation are first class citizens, warranting their own directories to assist the development team with these tasks from the moment of project inception.

The app directory is where we will find the majority of the code we will be writing. Rails creates projects which make it easier to follow the MVC patterns out of the box. Our HTML will be placed in app/views. Our model objects will be found in app/models, and our Controllers (equivilent to Struts Actions) can be found in app/controllers.

Rails also comes prepared to use a database known as Sqlite, which a light weight and speedy database. However you can configure the project to point to your favorite database using the config/database.yml configuration file. YML is a YAML file, which you can in your mind equate to XML for those suffering from angle bracket overload.

If you are new to Rails, you may not have a copy of Sqlite on your system. If not, you have one final download to contend with. Jump over to the Sqlite website (http://www.sqlite.org/) and download both the sqlite.exe and sqlite3.dll files. For simplicity sake, just drop these in your c:\ruby\bin directory (assuming, like me, you've installed Ruby in the c:\ruby location)

Rails comes pre-bundled with it's own Web Server known as WEBrick. While it is possible to run Rails apps on other web servers, we'll stick with WEBrick out of simplicity. Despite the lack of code, it is possible now to rub the web server and view the Rails welcome page.

ruby script/server

By default, Rails runs its webserver on port 3000. Fire up your web browser and point to http://localhost:3000. Now that we have all of our infrastructure setup, let's start designing and creating an application.

Continued in: Ruby on Rails for Architects #4 - Analysis and Design

Saturday, July 26, 2008

Ruby on Rails for Architects #2 - Business Case

Continuation from Ruby on Rails for Architects #1

While my last 3 years or so has been exclusively within the web tier delivering high performing scalable Java applications, my roots are in some older languages like C++ and PERL In my company, PERL is still the 800 pound gorilla in the room in which nobody speaks. Countless critical systems count on PERL not only for the scripting support of development and build processes, but as the integration glue due to it's prevalent use as an efficient File I/O manipulator.

Ruby shares much in common with PERL, and I propose that shifting from PERL to Ruby is not as difficult as shifting from PERL to Java. If, like me, your Enterprise still has heavy PERL roots... then Ruby can be perceived as a potential upgrade path without as drastic of impact to the retooling and training of the development and support teams.

If your company shares a similar history, perhaps the developers of your PERL systems also feel adrift and left behind the curve when it comes to the tooling support and framework choices. While there are options of web frameworks and libraries within the PERL communities... The flood of attention is a dim candle compared to the current shining stars of Java and Ruby. This means that PERL developers making the natural shift to Ruby will suddenly find at their fingertips a wealth of tooling that they moments before assumed was available only to Java code slingers. Testing frameworks, Mocking, Web frameworks, and rich IDE support will be open to the team.

While there are quite a few web frameworks available for Ruby, I'm focusing my attention on Rails for these discussions. Rails hit the scene and revolutionized the industry. Dynamic language frameworks like Rails have the tendency of unsettling an entrenched Java web developer.... With concepts like "Convention over Configuration" webapp creation is no longer a painful process of slogging through countless XML configurations. By following a set of standard naming conventions, everything 'just works'. Some may be scared by this concept, but within the Java web space we've been exposed to it before. Struts uses the same concepts in the way their taglibs reference POJOs. Use that bean:write tag to output the 'name' variable on the 'Person' class, and you are really using convention to allow Struts to make calls to person.getName().

Rails was one of the first frameworks to offer more than an API. They offered a platform. Testing, Data Access, Project Organization, Deployment, and Development Lifecycle were all baked in. Gone are the days of the web framework API's.... replaced by web platforms.

Even if something like Rails never makes it within 100 yards of one of your production servers, it can't be denied how easy it is to create web applications which follow the standard Enterprise Application cookie-cutter CRUD (Create/Read/Update/Delete) model. The opportunities to utilize platforms like this for prototyping an application are tremendous, even if it is simply thrown away before your team attempts a build of the 'actual' system. Even those vaguely familiar with Rails can crank out applications which have a plain, but yet still polished look about them.

There are rumors of Rail's inability to scale which are justified due to it's niche market of small user load web applications. But like almost everything, there are strategies for deploying Rails applications in larger environments if you so require. But it is very important to recognize that Rails is not built to house high volume web applications like Google or Amazon. If you do your research, you'll find even J2EE is non performant in these venues.

Sun is backing the execution of Ruby on the JVM with a download known as JRuby. Due to the JVM being mature and vetted, the utilization of the JVM as a execition platform for Ruby has already allowed Ruby to gain the advanteges of the Java infrastructure.... allowing performance to reach levels which in some cases pass Ruby itself. If your company is heavily invested in Java infrastructure, it is worth a look to investigate JRuby.

In the remainder of this series, I will show you how to build a simple Rails application. As a J2EE developer, I am amazed at how little code there is to execute a Rails solution. As an architect, this means that my code can be more compact, and focused more on the business logic rather than the glue and integration fluff.

Continued in Ruby on Rails for Architects #3 - Project Setup

Ruby on Rails for Architects #1 - Configure the environment

I thought it would be worthwhile for me to share with the world some of the prototyping I have been doing with the Ruby language, and Ruby on Rails. As I professed in my blog entry "Seek a wide breadth of knowledge", I am always seeking to expand my practical hands on knowledge... I only hope these articles in turn help you.

Note: I will focus my attention on the Windows platform, as this is the most pervasive in the circles I frequent... and has some nuances within it which cause installation and configuration to be cumbersome. However for non Windows users, sections later in this post, and later in this series will still be of some use to you.

Step #1 - Installing Ruby
As a windows user, you have a handful of options here.
  1. Obtain Ruby source code, compile and deploy
  2. Obtain Ruby binaries, deploy and configure
  3. Leverage the Ruby Windows One-Click Installer
  4. Leverage Instant Rails

On one end of the spectrum, there is the most difficult Option #1. If you wish to employ this method, then you are already at a skill level which far exceeds this blog post. Your best bet is to go somewhere else for information about this, rather than keep reading.

If Option #1 is the most difficult, Option #4 is the most easy. I highly recommend it if you are brand spanking new to the Ruby language and wish to experiment with Rails. With a small amount of clicks, Instant Rails will install a copy of Ruby, a copy of Ruby on Rails, as well as a few other popular gems (libraries in Ruby are known as gems) which will make your life easier. A one stop smorgasbord. Instant Rails actually has some decent documentation on installation procedures, so I'll point you there rather than attempt to duplicate them. If you choose this option, then follow those installation instructions and stop reading this blogpost. Go get a coffee or a beer instead, and when you come back search this site for the next installment of Ruby on Rails for Architects.

If you are a seasoned web developer or architect, it may be a good idea to try Options #2 or #3. While more steps are involved, you will be exposed to more of the inner workings of the installation process and perhaps gain an understanding which may assist you later in your Ruby learnings. If you wish to try Option #2, keep reading. If you wish Option #3 for the One Click Installer, download the installer and follow it's installation instructions, then skip down in this blogpost to 'Step #2 - Installing Ruby on Rails'. One caveat for Option #3 people is that the One Click Installer often ships with an older version of Ruby. As of right now, One-Click offers Ruby 1.8.6, and the binaries are 1.8.7.

For those willing to brave the installation of binaries for Option #2, read on. First, obviously, we must download and unpack the archive for the Ruby binaries from the Ruby website. Place the unpacked directory wherever you wish, I prefer c:\ruby. From this point forward, I will assume this is the directory you will use as well. If not, substitute your personal location whenever you see c:\ruby in this post.

It is helpful to have Ruby available on the Windows PATH, such that it can be executed ubiquitously from anywhere on the computer. You do this perminantly in the Windows system properties (accessed via Control Panel->System, or right clicking on My Computer and selecting properties). Once in the System Properties, click on the Advanced tab, followed by the Environment Variables button. In the bottom table scroll until you find the Path variable, select and click Edit. You want to append c:\ruby\bin on the front or end of the Path. Be sure to separate directories with semi-colons. Therefore if you append on the front, you will be appending c:\ruby\bin;

Now you have Ruby working, sort of. To be fully functioning, there are some Windows .DLL's which must be obtained which assist in utilizing some of the more powerful features of the interpreter. While not required, you should do this now. The One-Click installer handled this for the Option #3 folks but you are stuck doing it by hand.

First is zlib, which can be downloaded from their site (http://www.zlib.net/). Download the .DLL and place it within your ruby bin directory c:\ruby\bin. Remove the version numbers from the file, leaving only a DLL named zlib.dll. Ruby is expecting it in this format.

Second is readline.dll which is required for the IRB interpreter. You can find this in a few locations, such as (http://whytheluckystiff.net/ruby/dist/readline.so-for-1.8.zip). Without this .DLL, you will recieve a "readline.dll not found" error whenever attempting to execute the IRB. I'll explain more about the IRB in another post.

Last is Ruby Gems, which is a addon to Ruby which will allow you to more easily install third party libraries to your copy of the virtual machine. It is a must have in the Ruby community. You can obstain a copy of Ruby Gems here (http://rubyforge.org/projects/rubygems/). Download and Unzip the .zip file and take a peek at the README, which will inform you to run the setup.rb file in archive's root directory. This is a ruby file, and can be executed from the command line by typing ruby setup.rb

Step #2 - Installing Ruby on Rails
Installing Ruby on Rails is quite simple, simply utilize the Ruby Gems package to download and install the library.

A major hitch is found by those living in an Enterprise who has a nasty firewall blocking their computers from the outside Internet. You can get around that by setting a few crafty environment variables. I recommend setting these variables from a command prompt, rather than you System Properties, as they will contain you private logon information (which being a good architect) you will want to keep secure.

From a command prompt:
set HTTP_PROXY http://myproxy.mydomain.com
set HTTP_PROXY_USER myusername
set HTTP_PROXY_PASS mypassword
Now installing rails is a snap, if you are behind a proxy firewall or not. Open a command prompt and install rails using this command

gem install rails

Continued in Ruby on Rails for Architects #2 - Business Case

Friday, July 25, 2008

3 Question Rule - Removing the coldness from cold hard logic

Architects, as with many technical leadership roles, tend to suffer from a stigma of being negative or overly critical. This often stems from the critical thinking that is required, when applied too liberally the person will appear stubborn or belligerent. This is really one of the bad habits which leads to Ivory Tower Architecture.

A leader must always be aware of the shadow they cast, and the perceptions which are had of them. Think of how many enemies you have, and you will most always have detractors that outnumber your list. It is just human nature for folks in the workplace to have a negative opinion about someone, but through passive aggressive tendencies, and political correctness put on a mask of kindness when in their company. If you answered you have zero enemies, then you are either supremely out of touch with your own self expression, or aren't taking enough risks.

Critical thinking causes one to logically and objectively fins holes or flaws in an argument or idea. Great architects are always proficient critical thinkers, however those who don't share this trait can perceive the critical thinking as callous and cold, or stubborn and confrontational, or wishy washy and cruel. The cold hard logic of critical thinking is... well.... cold, and hard. When applying critical thinking one must realize that some people are as passionate about their ideas as they are their own children, and get upset when someone challenges them. Nobody wants their baby to be called ugly or stupid.

A good rule is to not offer critical advice unless it is asked for, or unless it is your personal responsibility to ensure the course of action is sound and just.

If (like me) you have a sense of duty and honor that just can't stand to see others attempt ideas or concepts which you know for certain will fail, and you simply can't keep your mouth shut..... then employ what I refer to as "The Three Question Rule".

The 3 question rule applies most to group settings such as a meeting. When a presenter is giving a talk on a topic, limit your self initiated outburts (be them statements, questions, or helpful anecdotes) to three. While not a hard and fast rule, more than three disruptions of a presenter can be taken as heckeling, derailment, or downright attacking. This may cause the presenter to get defensive, which will lead to the bad perceptions mentioned above. Not only will the presenter insinuate you are on the attack, situations in which one audience member monopolizes the conversation usually causes the audience to clam up as well. Audience members who percieve a speaker being attacked will also walk away with a bad perception of the attacker. In one short meeting, you could leave a lasting bad impression on dozens of people.

I should stress that it is the perception here which is important. You could have had the best intentions in your mind, but your actions were incorrectly percieved as threatening.

Those whom are used to being audience members whom are prolific talkers may be surprised when applying the 3 question, that patiently waiting rather than blurting out questions as they think them causes other audience members speak to speak up and ask the very same questions. This is very good. Never ask one of your questions one you'd know someone else would ask. Save your 3 for juicy questions which you would just die if you didn't have the answers to. By all means take notes during the presentation, jotting down a potential question. When all you have is three to ask, organizing and prioritizing your thoughts becomes more important.

You can become more machievellian if you are aware of the content being presented ahead of time, and are well aware of more than 3 question you wish to ask. In these situations find some friends who will also be attending and see if you could get them to ask some of your extras. Be carefull however, as if the presenter knows you are in league..... you may be considered a group or gang, in which case you technically only have 3 questions spread among 2 people. You will almost certainly be considered a gang if you are witnessed whispering to one another audience member during the talk. If people hate hecklers, they hate gang beatings even more.

Lastly, none of this applies if you have a strong, length, friendly relationship with the speaker. Bad perceptions and impressions which are due to misunderstandings are often born from relationships in which there is little trust and respect.

Wednesday, July 23, 2008

People tend to get in the way


Even the best innovations can be subverted by incompetence. One of the statements from a fellow architect which makes me cringe is one professing that a new language (e.g. Java or Ruby) is required to achieve great architecture design.

Hogwash, I say.

Great designs are achieved through a simplification and organization of complex thoughts. Object orientation is not a requirement for structured and ordered programming. Layered architectures can be achieved in functional programming languages as well. While my current passion is in object oriented distributed web technologies, I've witnessed and learned much from observing the designs of PERL and COBOL applications.

In my experience it is the people, not the technology, which are the biggest barriers to innovative and intuitive architectures and designs. The role of software developer requires a great deal of creativity, and not all developers have the innate knack required to craft beautiful as well as utilitarian software.

Some developers attack software problems like a wreaking ball demolishing a building. They just climb into the machine and start swinging the heavy ball at the walls. Repeat until building is gone. Other developers might not even have nor understand the right tools required for the job, and repeatedly pound their bloody fists against the building wondering why it won't crack. Management sees the lack of progress, and rushes off to get more fists.

Building demolition, like software development (when done properly) is a precision application performed by skilled resources. When destroying a building, one must properly survey the building to determine what kinds of explosive charges are required to bring it down, and they should be placed such that the building falls in a controlled manner without causing collateral damage.

This all being said, it is the lack of discipline and professionalism surrounding the role of the IT worker which causes the most grief. Anyone capable of compiling code is labeled an IT professional, causing a disservice to the profession. I argue even a deep understanding of a programming language isn't enough. That would be like saying a demolition crew need only have a deep understanding of TNT. Some of the best developers I have witnessed have focused their expertise in a related suite of skills which together form solid foundation for creative yet pragmatic software design.

Tuesday, July 22, 2008

Seek a wide breadth of knowledge


Jack of All Trades
An architect must seek to gain a wide breadth of knowledge on a variety of subjects. The proverbial Jack of All Trades, and Master of None. This requires a love and passion for learning. I believe strongly that learning is an acquired skill. There are those whom I have encountered who have not been proficient learners.

Learning is a skill
Strangely, it is difficult to teach the skill of learning. As everyone has their own unique way of acquiring information in the most efficient way possible (e.g. listening, speaking, writing, reading, etc). However, as it relates to the role of an architect, the acquisition of a large variety of info means that one of the most critical nuances of learning is the classification and understanding of what can be forgotten, or ignored completely.

Know what to forget
Data floods us all of the time. Like those word problems we had in school, we are presented with more data than is necessary to solve the problem at hand. Ideas and facts have a way of competing with each other for space in your brain. Attempting to remember all of the details about something has a tendency to smother other knowledge. Instead, know what is reference material that can be found easily within a book or a google search. Stop trying to be an encyclopedia, and instead become an index of knowledge.

Engineers vs Architects
While an Engineer or Developer will hone their craft becoming very deep and proficient at a subset of skills, the architect will cast their net wide. This means that an architect can rarely profess to be as competent in a skill that is a specialty of a developer. Java developers will be walking encyclopedias of arcane knowledge (proud of their ability to spout of JavaDoc specs from rote memory). On the other hand, the architect will know of the class in question.... they will know it's general purpose and use, and know some web links and books where more detailed information can be gained, or engineers who can be contacted for a brief technical discussion.

Buzzwords aren't knowledge
In the 16th century, Galileo Galilei changed the world of astronomy with the telescope. For generations, you were considered a foremost expert in astronomy by your ability to spout off the buzzwords from famous people who died nearly 2,000 years ago (Aristotle and Ptolmey). Galileo changed the game by bringing practical, testable, measurable knowledge to the table. Despite the initial outrage of the buzzword armed 'experts', buzzwords never can win over cold hard pragmatism.
As an architect, ensure that this breadth of knowledge you are gaining is in fact practical hands on roll up your sleaves in the trenches knowledge. Write some code, install some software, if not production code, then prototypes which actually work. I've witness architects fire up a webpage, consult the online demo, and consider themselves knowledgable enough to recomend the software to a development team.... only to find out later that developing in the tool is hard, has little documentation, and has zero traction in the industry to garner troubleshooting support from.

Never stop learning - Invest in yourself
In short, part of the mettle of an architect is to be a voracious learner. There are always new skills to learn and dabble with. Consider the knowledge an investment in your own career. Like stocks and bonds, investment in yourself pays dividends. As with the stocks, the best advise is to diversify. Spread your investment over high risk up and commers (e.g. Ruby, Scala), tried and true workhorses (e.g. Java, .Net), and low yield old timers (e.g. COBOL, LISP). And while my examples pertained to languages, this applies to all skills acquired. Don't frown upon or overlook the dying skillsets such as Mainframe. For the industry has the track record of resurecting ideas from the past.

A good example is Javascript Prior to it's resurrection and rebirth in AJAX, Javascript was frowned and spit upon in the Enterprise. With it's lack of debugging support, it wasn't a first class citizen on most web pages. Now it is difficult to find a website not utilizing Javascript to give a more responsive Web 2.0 experience to the user. This from a language which the industry slapped with a toe tag.

Thursday, July 10, 2008

Architecture Defined

"You keep using that word. I do not think it means what you think it means.” – Indigo Montoya from The Princess Bride

Once upon a time, the new administrative assistant walked into to my cube and asked “Hello, how are you?” I looked up and offered a friendly greeting, to which she replied “What is it you do?” I replied that I was a project architect, to which she retorted “No. I knew that. I meant what do you actually do?” I chuckled and said “You know, sometimes I ask myself that very same question.”

Computer Science’s roots are in mathematics and engineering. It was individuals in these disciplines whom imagined and created the first computers, therefore the software industry has reflexively paralleled these domains. One of these shared concepts has been architecture.

The origins of the word architect derive from the Greek word arkhitekton, which means “master builder”. In software engineering, a vast majority of individuals with ‘architect’ in their title have come through the application development rank and file. They were developers and builders who where field promoted to architect, in order to plan, design and oversee the software development lifecycle.

In the book Software Architecture in Practice, architecture is defined as:
The software architect of a program or computing system is the structure of structures of the system, which comprise software elements, the externally visible properties of those elements, and the relationships among them.


I also believe that one of the fundamentals of software architecture is the behavior exhibited by the elements (or components). By controlling the innate behavior of the solution, the architect can manipulate the software to conform to the various stakeholder's needs.