Outsourcing

Outsourcing helps your business by allowing it to focus its energies and resources on its core strengths. However, the success of outsourcing depends on a lot of factors, the top of which comes from you, the party that decides on whether outsourcing will actually help you achieve your business goals.

What are the success factors involved in outsourcing? The list can be very long, as it all depends on a company’s goals, size, budget, and the risks it is willing to take. The following are some common ways to make an outsourcing project successful:

  • Identify your business goals. Know why you are outsourcing in the first place. Is it to cut costs? Is it to have more flexibility in growing your manpower? Is it to provide better customer service? The most common reason behind outsourcing is to cut costs. However, this poses a risk in the long run. There are savings that can be made by shipping some business processes to low-wage economies, but make sure that you also get more value for how little you are willing to spend in terms of process improvement, quality, and customer satisfaction.
  • Choose your vendor carefully. Before signing an agreement with a vendor, make sure that you have made ample background checks for its financial stability, management team, flexibility, workforce, and best of all, the methodologies that it implements in the course of your project cycle. Search for reference that will vouch for the capabilities of the vendor. This is the third party that will handle part of your business. No matter the size, each part of your overall operations plays a crucial role in your business success. Choose your vendor well.
  • Engage everyone’s support. Everyone from all levels of the organization should support the involvement of outsourced personnel–or consultants–in the project. Top executives should buy in to the project because they are ultimately responsible for the venture. Regular employees should show not see outsourcing as a threat to their employment.
  • Agree on project management methodologies, and training and communication plans. Depending on the complexity of the project, there is a high learning curve involved at the start of the project. Make sure that prior to the start of the project’s outsourcing, all blueprints are laid out. Communication and training plans, implementations methods, channels and facilities are crucial in the knowledge transfer. And most of all, the project methodologies should be agreed upon in order to keep risks at minimum levels.

Ivy Dependency Manager

Like most of us often hear, “its another framework or dependency management tool”. But what exactly differentiates Ivy from Maven?

Ivy is much easier to use. The library is simpler since it doesn’t do so much. It only focuses on dependency management and use the already famous and powerful ant to build the application. In short, ant and ivy is used side by side.

Why I Choose Ivy?

The main thing I like about Ivy is its simplicity. You can use Ivy with only ant installed on your system (and of course, java). This means that you don’t need to download any Ivy related libraries or when using eclipse, no plug-in is needed. You can run everything using ant, from installing the ivy library to downloading the dependencies.

Ivy is a dependency management tool that can use other repository such as maven repository.

Installing Ivy

Before continuing, I’ll assume that you are using ant version 1.7. You can choose to run the ant script in either console or from inside eclipse (It depends on your preference).

Here is a build.xml file that contains several targets that will be used in this post:

<?xml version="1.0" encoding="UTF-8"?>

<project name="ivytest" basedir="." default="usage" xmlns:ivy="antlib:org.apache.ivy.ant">

<property name="lib.dir" value="lib" />
<property name="build.dir" value="build" />
<property name="src.dir" value="src" />

<path id="lib.path.id">
<fileset dir="${lib.dir}" />
</path>

<path id="run.path.id">
<path refid="lib.path.id" />
<path location="${build.dir}" />
</path>

<property name="ivy.install.version" value="2.0.0-beta1" />
<property name="ivy.jar.dir" value="${basedir}/ivy" />
<property name="ivy.jar.file" value="${ivy.jar.dir}/ivy.jar" />

<target name="usage" description="Displays the command used with this build script">
<echo message="Usage" />
<echo message="-------------------------------------------" />
<echo message="Available targets are:" />
<echo message="download-ivy --> Download ivy library" />
<echo message="install-ivy --> Install ivy library" />
<echo message="clean-libs --> Delete lib files" />
<echo message="clean-ivy --> Delete the ivy files" />
<echo message="resolve --> Resolve/Download ivy dependencies" />
</target>

<target name="download-ivy" unless="skip.download" description="Download ivy.jar">
<mkdir dir="${ivy.jar.dir}"/>
<echo message="installing ivy..."/>
<get src="http://repo1.maven.org/maven2/org/apache/ivy/ivy/ ${ivy.install.version}/ivy-${ivy.install.version}.jar"
dest="${ivy.jar.file}" usetimestamp="true"/>
</target>

<target name="install-ivy" depends="download-ivy" description="Install ivy library">
<path id="ivy.lib.path">
<fileset dir="${ivy.jar.dir}" includes="*.jar"/>
</path>
<taskdef resource="org/apache/ivy/ant/antlib.xml" uri="antlib:org.apache.ivy.ant" classpathref="ivy.lib.path"/>
</target>

<target name="clean-libs" description="Delete all libraries/dependencies">
<echo message="Deleting ${lib.dir}" />
<delete dir="${lib.dir}" />
</target>

<target name="clean-ivy" depends="clean-libs" description="Delete the all folders/files that was generated by ivy">
<echo message="Deleting ${ivy.jar.dir}" />
<delete dir="${ivy.jar.dir}" />
</target>

<target name="resolve" depends="install-ivy" description="Resolve the dependencies">
<ivy:retrieve/>
</target>

<target name="run" depends="resolve" description="Compile and run the project">
<mkdir dir="${build.dir}" />
<javac srcdir="${src.dir}" destdir="${build.dir}" classpathref="lib.path.id" />
<java classpathref="run.path.id" classname="Main"/>
</target>

</project>

Invoke “ant install-ivy” and the ivy jars will be downloaded. A new folder named “ivy” will be created with the ivy.jar in it.

Dowloading Dependencies

By default ivy uses maven 2 repository but you can certainly define other repository (It will be covered on later post).

The build.xml above contains a target named “resolve”. Running the target will cause the Ivy to download defined dependencies on ivy.xml (ivy.xml is needed since all the dependencies are defined on that file). Here is an example of ivy.xml:

<?xml version="1.0" encoding="UTF-8"?>

<ivy-module version="2.0">
<info organisation="ideyatech" module="ivytest"/>
<dependencies>
<dependency org="log4j" name="log4j" rev="1.2.8"/>
</dependencies>
</ivy-module>

The code above downloads the log4j and its dependencies from the defined repository (in our case, maven repo). I chose to use log4j because in the next section, I’ll be demonstrating to compile a simple java class that uses a Ivy managed library. Invoke “ant resolve” now and you will see a message saying that the library is being downloaded.

Compiling The Application

Main.java:

import org.apache.log4j.Logger;
public class Main {
    private static final Logger log = Logger.getLogger(Main.class);
    public static void main(String[] args) {
        System.out.println(”Printed using system.out.println”);
        log.info(”Printed using log4j logger”);
     }
}

The sample java file won’t really print the message being logged. The purpose of this example is to test compiling the application with the Ivy libraries being referenced. The idea is to simply add the “lib” dir to the classpath on compilation.

Try invoking “ant run” and the application will be compiled and executed. Note that invoking the “ant clean-libs” and removing the “resolve” dependency on run target will cause the compilation to throw some error.

References:

http://ant.apache.org/ivy/index.html

Note:

  • Ivy logo is property of Apache Ivy and is not connected with Ideyatech.



We’ve been using Continuum for quite some time now. While Continuum does seem to do a good job managing our builds, its limited support for JUnit Test reports made us evaluate an alternative, Hudson. Hudson is the new guy on the block, aside from cool icons and more intuitive interface, this tool seems to be quite competitive and feature-packed.

So, I’m listing down a head-to-head comparison between Continuum and Hudson as we’ve used them and based on features we are looking for:

Build Management:

Continuum seems to perform better in this area. It allows multiple jobs/script configured on a single project. Projects can also be logically grouped. Hudson only supports one job per workspace, which I find very limiting. This means that if we need 3 jobs (e.g. build-war, deploy, run-test), each job needs its own workspace, which doesn’t make sense because all these job share the same source code.

User Management:

I prefer Hudson a little over Continuum because I like simplicity over flexibility. Considering our small team size, there is no point of grouping people with several permissions across multiple projects. All we need is the ability to restrict the developer’s access within their projects. Hudson has a simple, easy-to-use permission system–I was able to setup user access rights within 30 minutes. Continuum seems to be a little over-complicated on this. Continuum also has a strict password policy which makes it more difficult to manage.

Scheduling:

Once again, Hudson is better due to its simplicity. To configure a schedule, simply add “@daily” on schedule option and you’re all set. While Continuum’s scheduling isn’t complex, there’s more clicking involved. Again, Simplicity over Flexibility.

Email Alerts/Notification:

Although both tools provide email support, Hudson has a more detailed email report. Hudson allows the tracking of JUnit test reports for every test, while Continuum only provides notifications on failed or successful builds.

In the end, we decided to switch to Hudson because it is easier to use and it includes the Junit test reporting feature.

Note: The Continuum and Hudson logos are properties of Apache Continuum and Hudson, respectively.

As recommended by Yahoo on YSlow - tip #1: Make fewer HTTP request and tip #10: Minify javascript- we aim to implement these tips on all our projects with minimal head-ache. While these recommendations are truly useful, implementing them can be quite tedious and challenging. Consider having to maintain multiple min versions of the javascript and the files that links to them! So to alleviate the problem, we created a tool called low-tides (as part of open-tides) that helps automate the merging and minification of css and js files.

So what is the rationale behind the the tool?

  • Maintenance of minified js and css is a nightmare. Keeping separate js and css files for development and production can be very confusing. Some developers might change the production version without syncing with the development version. So eventually, changes to different files becomes a mess — Which one has the latest code?
  • Maintenance of html files that links to proper javascript and css is another problem. Since minified versions are likely to have different filename (e.g. basic-min.js), html codes that reference the scripts need to be changed. This leads to having multiple copies of html files… again.
  • Versioning of html, css, and js files introduce a whole new set of configuration items. Imagine bullets #1 and #2 getting multiplied across a number of version releases!
  • At the time of this writing, there are no tools available that can merge multiple javascripts. The development version of javascript needs to be logically separated while the production version needs to be merged (for lesser http request). Moreover, merging javascript is not straightforward. Some javascripts need to be pre-loaded while others can be postponed.

I suppose by now you get the picture. The solution we propose to this configuration problem is simple:  Always change from the development version and have a deployment script automatically create the production version. As such, files are always maintained from the development version - but the key to this approach is to ensure that the script for creating production versions is quick and easy-to-use.

Now here comes Low-tides. Low-tides is a Java-based program that automatically analyzes html files for javascript and css includes. It will merge includes that are in sequence into a single file and minify it. In summary, it automatically solves all the problems mentioned above.

You can download it here: http://code.google.com/p/open-tides/downloads/list

Usage instructions are available here: http://code.google.com/p/open-tides/wiki/LowTides

As defined in Wikipedia:

Agile Software Development is a conceptual framework for software development that promotes development iterations, open collaboration, and adaptability throughout the life-cycle of the project.

True to its meaning, Agile is a concept that can be implemented in several ways. So, there is no correct way of getting it right… Nevertheless, here are some tips we’d like to share based on our experience:

Ideyatech agile

  1. Agile team members must be matured and responsible. Team members must be pro-active and have the drive/determination to take charge of the task at hand. Self-organizing teams are hard to develop, especially for junior programmers. It takes some level of maturity and experience for a team member to identify the tasks and execute them.
  2. Agile projects must be contracted as “Time and Material” rather than as “Fix Cost”. This is because agile practice is susceptible to “scope creeps”. The concept of being able to adjust/change requirements during each release indicates that scope must be flexible. As such, contracting on “fix cost” will either limit scope changes or lead to tedious change control processes.
  3. Pair programming should be limited. It is effective only on certain circumstance such as “master-apprentice” pairing or critical components. Otherwise, it will lead to inefficiency where two people are producing half the value of their time.
  4. Tools are essential for unit testing and continuous integration. It is almost impossible to implement unit tests and continuous integration without the proper tools to support the build and test process. It is important that the tool is able to run builds on pre-determined schedules and send configurable alerts. Moreover, choose a tool that can understand the unit test results and do notifications as necessary.
  5. Take the Agile Manifesto with a grain of salt. Not everything in Agile works… it varies on the organization, software and project type. For organizations that are new to this concept, start by shortening your iteration release - at least to monthly. This can take you a long way going agile…

Elegance in Approach

Another form of art in programming is the approach or architectural design. This topic requires strong technical background and experience, but still, designing your architecture requires artistic skills. There are many ways to skin a cat, so is there to design an architecture. Although design patterns help standardize approaches in software programming, decisions have to be made on which patterns to use, more so, to mix and match. Some patterns have similar purpose and overlaps, so choosing the best pattern requires some craftsmanship.

One major factor that affects architecture is the system requirements a.k.a. non-functional requirements, such as reliability, performance, maintainability and others. Having said that, I’m assuming that the functional requirements is already being taken care of and you are aware of what functionalities need to be supported… you’re now asking yourself how it should be supported.

Now, let’s go through some examples. When parsing a string for a certain pattern, do you use standard string operators (e.g. indexOf, substr) or regular expressions? Normally, you’d say regular expression will be easier - more readable and easier to maintain. However, there is a major performance degradation in regular expressions. So, if performance is important, you’d reconsider using indexOf. But then the maintaining such codes will be a nightmare. You might end up implementing your own parsing libraries using standard string operators - this will be a balanced between maintainability and performance. Such is a case of choosing the best approach, all solutions will perform the required functionality… but one will be better in some aspects than the other. Knowing which one works best requires some creativity and mastery. Thereby becoming your masterpiece.

There are so many scenarios that will let you weigh and analyze the different approaches, and there might be no perfect answer, only good answer. In any case, deriving the best possible approach requires some intuition, foresight and creativity. With so many factors to consider in choosing a design, you might as well leave it to your artistic skills to decide.

Many conceive that programming is a science of computational logic but that’s only half the truth. Programming is more than science, it’s an art. If you disagree, then you’re as good as someone fresh out of college - brainwashed on algorithms, computational complexity, and neural networks.

Let’s begin by putting things in proper context. Art, as defined in Wikipedia, is “a particular type of creative production generated by human beings” or in simpler terms “products of human creativity”. Such definition may have convinced you to agree, if not, then you’re likely a geek trying to find for the most efficient solution to the traveling salesman problem for the past 10 years.

Let’s cut the chase. So, what’s the art in programming?

Artistic Codes
There are many forms of art that can be expressed by your source code - and I’m referring to art as an aesthetic and visually stimulating piece - just like Picasso’s paintings or poems from Shakespeare.

Think of your source code as a masterpiece. Indention, comments, newlines, variable naming are your tools. All of these components must be balanced, easy to read, and inspiring.

The simplest form of art in your source code is “indention”. Block statements must be consistently indented thereby, making it easier to understand. Indention must also be equal in spaces - most Java programs are indented by 4 characters. Personally, I felt uneasy and can’t think clearly whenever I see misaligned codes. It just needs to get fixed otherwise, I won’t be able to think on the next steps.

“Comments” is another form of art but this requires a bit more creativity. Putting comments is not just rewriting what’s represented in the code, rather it must relate to a specific purpose. There is no need to describe the algorithm since its already shown in the code, instead explain the purpose of the code. Remember, comments are intended for humans to read so don’t write something in machine language. Here’s a classic example:

//loop the ArrayList
for (int i=0;i

instead try something more meaningful,

//let’s sum up all the values in the list
for (int i=0;i

The proportion of source codes to comments is also an art. If you’re writing more comments than the codes, then chances are the code is not readable and not well written. Unless of course you’re trying to write for efficiency. To illustrate:

// let’s get the middle index
mid = (max+min) >> 1;

While the code above can be easily understood using mid = (max+min)/2, you may want to use the shift operator since it takes less CPU time to shift the memory register than do a division.

The third form of art in your source code is “naming”. Choosing the right name can take a lot of thinking time. The worst variable names are generic x and y. Always use something more meaningful to make your codes more readable. More importantly, make sure the names are representative of its purpose.

For example, what variable name would you assign to “number of records per page”?

  • numberRecords. This can be interpreted a total number of records, or record number.
  • recordsPage. This can be interpreted are the page number or a list of records, or something else.
  • numRecordsPerPage. Might work, but probably too long.
  • recordsPerPage. The preferred name.

Again, it’s an art so there are no hard and fast rules how to name variable or method names. But always make sure that the names well represent it’s purpose otherwise, it can get confusing when you start debugging your source codes.

I’ve recently come across unfuddle(http://www.unfuddle.com) which is a project tracking tool and hosted source repository. This site is built on RoR and behaves similar with Basecamp. I’m currently using Basecamp for my projects… it’s pretty good but I find it a little too limited for other things such as defect and issue tracking. Currently, I have a separate service for issue tracking and source control.

Unfuddle

Unfuddle seems to be the all-in-one solution as it provides a number of useful functionalities such as messages, milestones, ticketing, and even source control. With unfuddle, I’m considering giving up basecamp and my VPS-hosted repository. I’ll probably be able to save a few bucks but more importantly, I’ll get a streamlined process of managing projects from source control to issue tracking. Hopefully, unfuddle can get an integrated defect tracking software that allows linking between source code commits and issue resolution and possibly a platform to support continuous integration.
Thanks to the people at Unfuddle for making software development and management fun and exciting!

After setting up Continuum, I find it reasonably good to support continuous integration (for a free/open-source solution).The package for download is ready to run and easy to configure. This supports Agile development, quick-turn around. Initially, I was skeptic setting up this tool considering it may take me 3-5 days to setup. Well, I was wrong… I was able to get it up and running in a few hours and most of the time was actually spent fixing my ant script.

Deploying Continuum is relatively easy, just extract the tar.gz or zip, and execute bin\run… Viola! You now have continuous integration. :) Well of course, this assumes you have the proper ant scripts and JUnit test codes to support it.

Let me outline the steps needed to implement continuous integration:

1.) Create your JUnit test. It is not much useful to setup continuous integration without unit test, part of the process is to ensure stable and working codes at any point in time (more or less) and the easiest way to achieve this is to run automated test scripts. So, create your unit test first.

2.) Setup your build scripts. The scripts will define the rules and parameters to be executed. You can create “build”, “deploy”, “run-test” scripts or whatever goal you desire to achieve. Personally, I find two main goals necessary - “build” and “run-test”. “build” script performs a clean build and creates the war file for deployment. This will be referenced for testing and promotions. “run-test” executes the unit test scripts so that you can schedule this in your CI tool.

3.) Check-in codes to repo. CI tools retrieve the files from some repository. In case of Continuum, it requires specific SCM URL format to retrieve the source codes for synchronization. This should be pretty simple task as most development environment have some form of repository (SVN, CVS, etc).

4.) Install Continuum. Extract the continuum package and execute the run batch file. You can access it at http:\\localhost:8080\continuum. Considering you have accomplished the tasks above appropriately, getting Continuum to run is quite straightforward as this tool already includes build-in web container(jetty) and database(hsql).

You can read more about continuous integration from Martin Fowler to decide whether this process is a good tool for you.

An important consideration with web site design is navigation. Users and prospective customers who visit your site would want to easily find their way around, or else they leave. If you have an online business, you would want to generate as much traffic to your website as possible and make as many sales. However, this is possible only if users stay in your site long enough to understand what your site is all about and appreciate what you have to offer. Remember that Internet surfers are an impatient bunch and wouldn’t bother to stay in your site if they can’t easily find what they need.

Web Site Design - Navigation Schemes

There are many navigation schemes you can choose from when planning your site’s web site design. Familiarize yourself with these schemes Know the pros and cons so that you have a web site design that works for your intended audience.

The different navigation schemes are text links, image maps, navigation buttons, drop-down menus, and dynamically generated URL’s. Each navigation system has its pros and cons. For example, text links are easily understood and load fast, while graphic images are more attractive, although they load more slowly. Drop-down menus don’t require much space, but drop-down menus created using Javascript or CGI scripts may not work in old browsers. Dynamically generated URL’s that result from the site’s search function allow users to easily find what they need, but search engine spiders will not be able to automatically index these dynamic pages.

It is best to plan your site’s navigation before you actually go into the web site design. Be sure to choose a navigation scheme that will suit your web site design and the web site templates you decide to use.

Web Site Design - Navigation Tips

Your web site design should be such that users can easily understand your interface. The web site design should also be implemented in a way that users will easily identify links. This can be done by using conventions for links such as menus, buttons, underlined text or other effects. When using non-conventional links, the site should provide instructions on what the user can do. The “three click rule” must also be kept in mind when creating the web site design. This means that every page in your web site must be reachable in three clicks, as users will usually not click more than three times to get what they need.

Below are some general tips when incorporating a navigation scheme into your web site design:

  • Your web site design must have a neat and uniform navigation system.
  • Use text links whenever possible, as they are more easily understood.
  • Your web site design should include a site map so users can easily find what they need.
  • Your web site design should be created such that the navigation system is located on the right, as it will be easier for users to go through the navigation system when it’s located near the scroll bar.
  • Your web site design should have a navigation scheme that is flexible enough to allow for the easy addition of links.
  • The main links and other navigational elements should be grouped together, and the important links should be “highlighted”.
  • Short, clear and concise words should be used for the links.

Keep your web site design both appealing and functional. Make the exploration of your web site a pleasant experience for visitors, and you’ll surely be pleased by the results, too!