Jeeni - Java Software Development

Defining Great Requirements

 This is a link

Managing software development is a hard ballancing act where one approach does not suite all. Here, we willl look at how you manage the requirements engineering phase of any project wheather your using interations, Agile, or whether you have outsourced your development or are developing in-house.

Whichever appraoch you have taken the most important thing to remember is to take an engineering approach. This includes the ininital definition of the software, including the business case, prior to developing the software itself.

If your project is developed in-house (the best way), then you can take a Agile approach. This will give you software which is sufficent for the job for the best possible price.

If you have outsourced your software, or need to define all your requirements up-front,  then you need to define your acceptance criteria before you start buring significant resources on development costs.

So before we get into the two different approaches of when we defined the requirements lets first say something about how we record them.

Product Backlog

Requirements should alway be recored in a product backlog which is nothing more than collection of requirements specified as stories or use-cases or goals of the system. Sounds a bit wishy-washy? Well you would be right.

The requireents in the Product Backlog should not be so vague (single sentance), that you don't understand what the implications of these requirements are nor that you can't anticipate the nuances of their impact on the overall system. No-one can build a great system from the requirement "Creat Address Lookup Module". What the hell does that mean? But more on this latter.

Equally, you don't want to spend so much time thinking about the requirements that you over emphasie and over antcipate what the end product will be exactly like. This just leads to lots of guess work, costs, and you tie yourself into a corner that latter on you find a bit unconfitable.

So a great requiement is at the right level. So write down what you know at the time you know it, and don't spend too much time predicting the future. Basically, make sure the requirement can be read within about 3 minutes - about 1/2 a page Arial at font size 10. Use a diagram or picture if it helps convay meaning.

Developing Requiremets - Defining a Story

I'm going to stick with the idea of defining requirments by using Stories because it is a pritty effective way for requirements definition. Using Functional Requirements list is not. If you want to use list of functional requirements then please don't insult this web site any more and please move on.

So how do you define a story? In the begining days of Object-Oriented Analsys and Design, we used to define use cases (stories) as having a Main Flow (which was the most common usage), and then Alternative Flows (which were things such as when errors happened, or event occured that diviated from the Main Flow). The problem with this approach was that it was very documentation intensive and pritty much boring as hell. Here is an example of a Main Flow for entring an address:

  1. The user will enter their postcode.
  2. The system will validate the postcode and display a list of matching addresses.
  3. The user will select the address that matches where they live.
  4. The system will record the address.

Naturally, from this there can be lots of Alternative Flows, the postcode not being valid, not finding any maching addresses, the user's address not being in the list, the user selecting the wrong address, and so on and on. The good side of this is that it did make you think about the system in some detail. However, its boring to read and boring to write, and when you've got tonns of documents that describe all these little steps in the system all you want to do is have a labotomy and become a project manager.

But the good news is, if you're a Supplyer company and you've managed to get your customer to agree to be responsible for defineing the requirements and not working in a agile way, then you'll have no problem finding holes in loads of these Use Case documents and hitting the customer with lots of Change Requests - ching ching.

Describing a Story

So the best way to describe a story is not to think about it too hard (afterall Developers wages have been going down for the last few years, so our workload should be going down too), and to define them in a way that is accreate but not too clunky.

So for example, how about:

The user will enter their address using a postcode lookup system. The system must be able to cope with invalid postcodes, no found matches,  the user selecting the wrong address, and none of the returned addresses being anywhere where the user lives.

Hows that? Isn't that enough for anyone to develop from and any stakeholder to understand what is meant.

In reallty, your stories in a much larger than this, but the essence is to keep it simple, understanable and not to confusing. Also make sure it can be demonstrated. If you want, you may even specify what you would like to see demonstrated - there may be a particular part of the system that is particullary important. So you'll want to see it in the demo.

So this brings us to another key point:

  • The purpose of a story is that it is demonstrable once it is developed.

If your story is about a user interaction with the system then this is easy enough, but if it is a techical story about some interaction with an external system then you may have to demonstrate this via a test harness and log statements. Either way, each story has to be demonstrable.

So now we have an understanding of that how to create a Product Backlog lets look what happends if you have to define all your requirements up front.

Defining All Requirements First

The point of defining all requirements up front is that it gives you a fixed baseline from which to start development. This means that costs can be predictable and thus it's a technique suited to outsourcing or fixed price contracts. It is very difficult to price a system when you don't know what it will be.

However, if you want to define all your requirements up-front then you have to do so by starting from where you want to end-up rather than starting from where you are at the start.

  • Start from the finish line, not the starting line

The downside is that you will only get about 65% 80% return on your investment (ROI). This is because the Devil is in the detail and the product you specify up front will not be what you want when it gets developed. Consiquently you will have change requests to deal with, and each one of those change requests was time waisted in the orgianal requirements engineering phase, and also has the added overhead of administering the change request system.

BTW. If you are outsourcing development to large companies, it is via the Change Request mechanism that they make most of their money. Many of the large projects I have worked on, particullary goverment projects, the client gets screwed because the supplier purposfully defines loose or slack requirements knowing that they will need to be clarified or frimed-up latter. And that, my friends, is an opertunity for a Change Request.

  • Define Stories through Prototypes, Screenshots, and Mockups

The most important thing about defining requirements up front is not to document them - prototype them. So develop working screen mockups of your entire system, or at least as much as you can. Don't bother writting any documents because if you're going to define all your requiremnts up-front then no-one will read them, and certainly not good engeneers. Good software is visible and therefor should be expressed visually. And eveyone knowns detailed text based requirements are not worth the diskspace they're stored on.

When Not to Define All Your Requirements Up-Front

There are some circumstances where even if you're outsourcing and you want to define all those requiremnets up front, you shouldn't. This when the project is very large and will be going on for some years.

  • Do not define All requirements for very large projects

If your project is larger or will be ongoing for years then it would be a big mistake to defined all your requirements upfront and you'll need to defined them sub-system by sub-system. This will also make sure that you supplier can deilver.

Sure, you will still need a good understanding of at least the general direction you want you software to go in. But even this should be flexible. There are plenty of examples of software designed for one thing (search), and then ended up being usedfor something else (selling addvertising). So don't think that today you know what you software will be used for and look like in 3 years time.

The longer out your project is going to run for the more flexibility you have to build into your development plan. Fortunetly, this isn't too dificult as all it means is we take one step at a time and look to the near future whilest keeping an eye on the far future.

Protypes and Mockups

Prototype or mockup everything.

If you have interfaces to third party systems then you define your side of the interface, and let the third party provide the translation layer between what you want and what they provide. If this is not possible because they simply would not do it, then you should still defined the interface that you want and then write the integration code to make it work.

Desiging you requirements visually also enables you to test your assumptions around the scope, workflow and usability of those requirements. It also enables developers to write Selinimum tests which can run against the prototype which should also run against the finished product. Thus proving you've got what you asked for.

Here are the rules for a good requirements prototype/mockup.

  1. It does not have to be fully functional, but more functional the better.
  2. It should not be styled. Styling can be added latter - don't waist your time doing something that will hopefully change as the understanding of needs change.
  3. It should be quick and easy to develop. Don't get bogged down in details about what font should go where etc.
  4. The focus should be on general layout, placement of text and widgets, and thats about it.
  5. Do it in a browser, not in Word/Photoshop/Visio etc. I've seen projects where the screen mocks were presented in Word documents, and when the screens were developed for the computer screen they look real bad. Why? Because word presents documents in portrate, while most screens are in landscape.

Point 2 above hints at a very important aspect of developing a prototype during requiriements engineering. The prototype is not there to proove the requirements (at least in the early and middle phases), it's there to uncover and deeper understand requirements. So you should look to your prototype as a tool of change not as an end in itself. The more you're protoype changes the better you discovery of requirements. If you find that that your prototype is not changing very much then that is not a signe that you are on the way to having developed the most perfect of perfect products, but that you are not communicating good enought.

Sure, sooner or latter you're going to have to stop delving deeper and deeper into the nuannces of requiremnts, but thats when you've had enough and decided that the prototype is good enough to get the job done and act as a goal post for knowing when development is complete.

Incremental Requirements Definition

  • This is the most efficent and effect way for defining requirements - upto 95% ROI.

The Agile way for specifying requirements is to generally use a spreadsheet. This is fine, but does not reflect the way requirements need to be firmed up as you get closer to writing code against them.

For defining requirements the Agile way the best thing to do is to define them using as much knowledge as you have to hand at the time that you are defining them. This was outlined above when I was talking about Product backlogs.

Initially the purpose is to define as much scope as you can. So requirements do not have to be detailed, but they do have to be understandable. Again, see above.

So create your Product Backlog and some requirements may be single liners, and some will be a page of detail. Just write down what you know, and don't write down what you don't. Unless, of course, you know what it is that you don't know (encrption needed for personal data, but not decided how).

Summary

This is step 1 about how to create great software. Fistly you need to think you know what your goals and where you are going. Great software does not come form single line statements in spreadsheets. Great software does not come from details specs. And great software has never come from functional specs.

Great software comes from a starting possition of knowing the best you know at the time, but understanding that as development moves forward requirements may change and you will have to follow.

Greate software, like great Aikido, come from the streath of great flexibility.

Test Artical

Hello

 

Custom <p/> Elements

class is code-block

class is cmd-block

GWT, Gxt and Selenium Testing

If there is one thing I've learned about using Selenium to test gxt applications, is that there's a lot of pain and blood involved.

I've spend the best part of 5 days working out how to use Selenium Java WebDriver, to test a very complicated application. An application that included Dialog windows, ToolBars, Wizard Dialogs, and the usual array of Ajax, forms, grids and tables.

The journey started by having to understand how GXT renders JavaScript into HTML pages. When you are want to set element IDs in your code against most objects (like Button) - guess what, they don't appear on the <button> tag at all.

The next step is getting the Firefox WebDriver to work with the GWT Development Mode plugin for Firefox to work seemlessly.

In this artical I will divaluge all these secretes and provide you with a downloadable Maven project so you can see extactly what I've done.

But, firstly, to give a bit of context, I want to breafly mension the structure of the Selenium tests.

The tests use the java WebDriver and JUnit to simulate user interaction. The structure of the Seleiumn code uses the Page Object Model which means that each part of of the web application to be tested will have a corrisponding Selenium Page Object. So for example the ToolBar of the Gxt application will have a ToolBarPageObject which has methods for interacting with the toolbar (clicking buttons etc).

Buy combining these Page Objects together you can test your application much more effectivly and maintainably than using the Selenium UI to record scripts. This is because if you change something on your web app (say the toolbar for example), then, using Selenium UI your entire script will be busted. Whereas if you used Page Objects you only need to update the page object representing your toolbar - ToolBarPageObject.

This is just a bit of usefull background info for when you look at the source code downloadable at the bottom of this page.

So to start:

How Gxt Renders IDs on HTML <Form> Elements

OK, so the first and possibly the most supprising thing you need to know, is that when you try and put an ID on a form element such as with :

TextField<String> nameField = new TextField<String>();
nameField.setId("MY_ID");

The ID does not, contrary to what you might expect, get put on the corrsponding <input> HTML tag, but gets assigned to a <div> tag which encloses the <input> tag.

Here is the output from gxt:

<div role="presentation" class="x-form-item" tabindex="-1">

    <label style="width:75px;" class="x-form-item-label">First Name:</label>

    <div role="presentation" class="x-form-el-MY_ID" id="x-form-el-MY_ID">

        <div role="presentation" class="...." id="MY_ID" style="...">
            <input type="text" class="..." id="MY_ID-input" style="...">
        </div>

    </div>
    <div class="x-form-clear-left" role="presentation"></div>
</div>

So this is tip No. 1:

  • Just because you specify a ID on a object in gxt does not mean that the ID will render to the most oviouse corrisponding element in the output HTML

However, there is more. As you may have noticed from the highlighted sections above, the ID that does get put on the input tag gets appended with "-input".

Now, I'm not sure why this is but I would guess its probably because the guys at Sencha are not the brightest cookies in the tin, and didn't realise that some people may want to identify certain obvious elements with the ID tag they specified in their code. But there again, I suppose you could argue that people who want to develop web pages via a Java Swing type of framework (e.g. using LayoutManagers), arn't the brightest lights either.

But to be a little bit fair, they do render the TextField object into a nicely formatted label and input field combination. So maybe they just got confused because they were a bit drunk and pulling a late one on Friday night.

So Tip No. 2:

  • Just because you specified your ID as ID_ABC does not mean that it will render in HTML (or the DOM if you're being picky), as ID_ABC.

Bonus Tip:

  • If you are going to use GXT then add 40% to your estimates.

So where does your ID go? Well if you specify an ID on a Button object:

Button button = new Button("Click Me!");
button.setId("BUTTON_ID");

It gets put on the enclosing table object! Weird hu?

Here, with the intresting bits in blue, is how GXT renders the Button class to HTML:

<table cellspacing="0" role="presentation" id="BUTTON_ID" class=" x-btn x-component x-btn-noicon ">
    <tbody class="x-btn-small x-btn-icon-small-left">
    <tr>
        <td class="x-btn-tl"><i>&nbsp;</i></td>
        <td class="x-btn-tc"></td>
        <td class="x-btn-tr"><i>&nbsp;</i></td>
    </tr>
    <tr>
        <td class="x-btn-ml"><i>&nbsp;</i></td>
        <td class="x-btn-mc">
          <em class="" unselectable="on">
            <button class="x-btn-text " type="button"
                   style="position: relative; width: 60px; " tabindex="0">
               Click Me!
            </button>

          </em>
        </td>
        <td class="x-btn-mr"><i>&nbsp;</i></td>
    </tr>
    <tr>
        <td class="x-btn-bl"><i>&nbsp;</i></td>
        <td class="x-btn-bc"></td><td class="x-btn-br"><i>&nbsp;</i></td>
    </tr>
    </tbody>
</table>

How to Use the Firefox WebDriver

Firefox is the best browser for running Selenium tests. This seems to be because it's open source so gets the best support.

When GWT runs in development mode, the browser you use to view the app needs the GWT plugin. However, if use just use the FirefoxDriver with Selenium, you will find it starts a copy of vanilla Firefox that does not contain the plugin.

So to get Selenium to work with Firefox must first make sure you have the plugin installed in your Firefox browser and then you must create a Firefox profile. The way to create a Firefox Profile is explaned here. But the short answer is to run:

    firefox.exe -p

from the command line. Then use the dialog box to create a profile. Save the profile to a convenient directory for your tests. The profile will contain all the plugins your copy of Firefox has, and some settings info, so before doing this you should disable or remove any plugins that are not relevent (e.g. Adobe), and disable the automatic updates (otherwise every time you run your tests the browser will tell you it needs to be updated).

So now you can start using the FirefoxDriver to drive your tests:

final File profileDir = new File(FIREFOX_PROFILE_DIR);
final FirefoxProfile firefoxProfile = new FirefoxProfile(profileDir);
final WebDriver driver = new FirefoxDriver(fp)
...

So now you should be able to start runing your tests...

If only it was that easy!

The Gxt Selenium Tests

So as you are probably aware if you have tried to run Selenium tests against Gxt, things are not as easy as they may seem. So here are some tips to get you started.

  • Make sure you use the Page Objects pattern.
  • Whenever you've defined a LayoutContainer that you want to run some tests against, make sure you give it a unique ID.
  • Make sure you give every form, form field, button, menu option etc, a unique ID.
  • Try to avoid using EditorGrid whenever you can. This is because its very hard to get working reliably, but I will show you what I did just incase you are crazy enough to try.

Accessing Form Fields

Buttons:

Gxt Code:

final Button button = new Button("Click Me");

button.setId("click-me-button");

Selenium Code:

@FindBy(id = "click-me-button")
private WebElement clickMeButton;

...

@Test
public void testButton()
{
    clickMeButton.click();
}


TextField, NumberField, etc:

Gxt Code:

final TextField<String> nameField = new TextField<String>();
nameField.setId("name-field");
nameField.setFieldLabel("Name");
...

Selenium Code:

// Note the addition of "-input" which is added by gxt.
@FindBy(id = "name-field-input")
private WebElement nameField;

...

@Test
public void testField()
{
    nameField.click(); // See note below
    nameField.sendKeys("Adam Davies");
}

Note: the click() call is not strictly required, but the user will either click or tab to the text field so its best to do that in your tests just to ensure that any corrisponding javascript events are fired.


ComboBox:

Gxt Code:

// CountryCombo is a subclass of SimpleComboBox<String>
final CountryCombo countryCombo = new CountryCombo();
countryCombo.setId("country-combo"); 
...

Selenium Code:

@FindBy(id = "XXXX")
private WebElement countryCombo;

...

@Test
public void testCountryCombo()
{

}

 

EditorGrid Cells:

For EditorGrid cells is a bit more difficult, but generally you have to get the DIV that the cell relates to, click it, which results in gxt generating a edit field (e.g. a TextField), and then you can get the active Field by the class name x-form-focus. It seems that gxt in all it's wizdom put that class against the <INPUT> element when generating an edit field.

The following code demonstates this techique:

 

Note: The generall format that gxt uses to identify cells in a grid is something like this:

x-grid3-col-name row1-col2 row1-col3
row2-col1 row2-col2 row2-col3
row3-col1 row3-col2 row3-col3

Downloads

 

Abstraction and Modulization

Abstraction and Modulization

Here we are talking about how our code is stuctured within each tier and within each class.

It is key charactoristic of great code that the code's abstractions are strcutrued at the same level of functionality. Lets clear this up with an example. Far to many people write methods that do more than a single thing. So they will write a method that says creates a  Customer, and that method will first check that the data is OK, then go on to log the timestamp of when and which user created the customer object, then it may send of an email to inform some manager that a customer has been added and then write the data to the database and log a sucessful insert to the system log.

So I wont bore you by writing out a complete example because you could find lots of them all over the place.

How such a method should look is like this:

public class CreateCustomerService
{
  public createCustomer(final Customer customer, final User user)
  {
    validate(customer);
    validate(user);

    createAttempLogEntry(customer, user);

    addCustomerToDatabase(customer);

    createSuccessLogEntry(customer, user);

    postEmail(customer);
  }

... implementation of methods above...
}

The important thing to take home form this example is that all the methods operate on the same level of abstraction. Even if the validateUser(user) method is only a couple of lines of code it should still be brought out into it's own method because this maintain sinergy with the level of abstraction we are looking for.

This make the code more readable and more modular because we can obviously reuse many of the method in different circumstances.

To Pass Parameters or to use Object State.

One of the questions the always come up from time to time is, is it better to pass parameters around method-to-method within an class or should you use object state/instance variables and invoke the methods without parameters (such that they operate on the object state).

The most meaningful answer I can give you for this is that if you pass them around then there is no need to rely on state, and thus it is easier to make these methods final static methods which lean themselve better to optimisation. Also passing parameters around clearly shows when reading the code what data the method is working with. This, to my mind, is a good enought reason in itself. The easier code is to read and understand, then the better the code is. It is as simple a test as that.

If however, you are using templating or overriding methods from a parent class, then you may need to use instance variables to data communication.

In general I would say the rule would be to only use object state as a second option. Programes are far more extendable and flexible if code does not rely on state.

 

Debugging and Maintenance

Firstly, lets answer the question; What is code is for? Code is for humans to read, debug, maintain, and understand. This is the key mesure of good code - is it easy to understand what is going on and to maintain.

This is one of the most important measurements of great code verses crap code, and generally under this heading, crap code comes from old C++ developers.

Let me give you two examples of code that does the same thing, and see if you an work out which one is easier to debug:

  LatLog location = LocationUtil.getLatLong(db.getCustomer("ABC")
                           .getAddress()
                           .getGetPostcode());

  LatLog mapCenter = LocationUtil.getLatLong(postcode);
  int mapZoomLevel = 0;

  int zoom = 0;
  if(location == null)
  {
    location = UK_LAT_LONG;
    zoom = 15;
  }

 

final Customer customer = db.getCustomer("ABC");
final Address homeAddress = customer.getAddress();
final Postcode postcode = homeAddress.getPostcode();

LatLog mapCenter = LocationUtil.getLatLong(postcode);
int mapZoomLevel = 0;

if(location == null)
{
    mapCenter = UK_LAT_LONG;
    mapZoomLevel = 15;
}

So egnoring all the obvious bug errors lets look at the major signes of bad coding practice.

Inline Code

The most obvious and most anoying thing about the first code snippet is that the entire getting of the customer's location is done in a single line. If there are any faults with this line (such as a NullPointerException), the debugger or stack trace will only identify the line and not the partcular method. However on the second snippet, because the stacktrace will tell you the line number you will know at which point the problem occured.

Untidy Code

Secondly the second snippit is easier to read simply because it's layed out neat and tidy. The layout of the second snippet gives us the oppertunity to give our variables proper names which indicate what they are for. E.g.:

     Address homeAddress;

Use Features of the Language

Most Java programmer underuse the final keyword. This is used to indicate that the variable will not change its value. So by looking at the second snippet you can instantly see that the only modafiable variables are mapCenter and mapZoomLevel. This is great for debugging because once you are satified that the final variables have been assined correctly you do not have to worry about them getting reassined to some erroneous value latter on. This becomes more obvious and important when you are working with large code bases that someone else wrote. At a minimum, if the coder used the finally keyword consistantly you know that they know what they're doing. When you meet coders who refuse to use the final keyword even after you've explained what the benefits are you can pritty much mark them down as bozos.

Another good use of the final keyword is when it's used to indicate that a class or method can't be extended. This shows that the original developer put some thorough into how his code should be maintained and/or extended over time.

Additionally, there are other benefits to using the final keyword which code optimizers will pickup on and use to optimise the code (for example final methods can be repeated and in-lined everywhere by the optimiser during profiling and compile time because they can't be polymorphic).