Showing posts with label design. Show all posts
Showing posts with label design. Show all posts

9/3/12

Wireframe a Mobile Application


When designing a mobile application, one of the first activities should be to wireframe the application first. This allows us to define the application views, navigation and the user interaction.

What is a wireframe?

This is the design process of the application in which you can create rough sketches of how the application should look and behave. This allows us to identify any possible design issues early in the process. The corrections can be made on the sketch which has less impact than to try to correct software already written. The goal should be that all your application requirements should be met and that the user interface should be consistent, intuitive, balanced and readable.

Application Views

These are the pages/screens of your application. The idea is to understand what the application should offer to the user and identify how many views are needed to deliver the feature set. When defining the view, we need to have a plan for the following elements:

Header

The header displays application information like title and icons, and it is displayed in all the views.  It is also used to provide a Back and/or home navigation button to allow the navigation back to the previous page.

Theme

The theme is the combination of color that you want on your application. The colors are used on the different elements like headers, footers, controls, content panels and fonts.

Design/Layout

This determines the look of your application. You may want an application with icons, sliding images or list views on the main page.  You also need to define how you want the layout of the labels, input controls and buttons. Place your elements with enough padding and alignment to create a balanced layout. This is the most difficult aspect of the design. You need to be creative and be able to define something that is appealing and intuitive to the users. The key is to also be consistent with your design in all the views. Maintain the same look and feel in all the views. 

Fonts

Make sure the fonts that you select are clearly visible and with enough padding between other elements to provide a balance and easy to read interface.

Footer

The footer is also displayed in all the views. It is used to provide quick actions to the users like a toolbar. It is also often used to show promotional or copyright information to the user. The footer is a context driven element. It may display controls or information that is just relevant to the current view.


Navigation

This is very important on any application. You need to provide users with the ability to know where they are in the application and how they can get to another location in a very intuitive way. The user should be able know how to get back to previous views without much effort or just click back to the main page. The transitions between views should have the same effect in the entire application. You should select sliding, popup or any other effect that lets the user know that a new view is in transition. The key is to be consistent and maintain the same effect. 

User Interaction

First minute of usage is important. If the user finds your application easy to use, he will probably explore more and navigate to other pages to see what other features are available.  The application should load quickly, so the user is not left waiting for too long. Here we need to make sure that we choose user interface elements that are intuitive for the user to interact with.


Conclusion

There are several tools on the internet that can let you create a wireframe for free. Just search for one in one of your favorite search engines. If you like, you can also just use a pencil and paper and then scan your sketches.

I hope I was able to provide some ideas on what to consider when building wireframes for your next mobile applications. If you follow these tips, I am sure you will find that your next design will adjust easy to changes.

7/20/12

Fluent Interface to Simplify an API

The mail goal of an API is to facilitate the use of commands and attributes to achieve certain functionality.  Over time, an API may have evolved and become somewhat obscure on its usage which reduces its usability and increases the implementation time.

To clean/simplify an API you can apply a fluent interface to it. This allows you to modify the API with a more descriptive interface which improves its usability. At the same time, this preserves the current API interface and eliminates the risk of introducing bugs to code that is already implemented.  To get a better understanding, let‘s take a look at an order system. To create an order, an API often uses the following code:

//customer and order detail
Customer cust = new Customer() { CustomerId = 12900 };
OrderItem item1 = new OrderItem { Name = "Pen", PricePerUnit = .99, Quantity = 10, Sku = "1675" };
OrderItem item2 = new OrderItem { Name = "Notepad", PricePerUnit = 2.99, Quantity = 10, Sku = "5456" };
OrderItem item3 = new OrderItem { Name = "Marker", PricePerUnit = 1.99, Quantity = 10, Sku = "9836" };

//standard API to create the order
OrderHeader oh = new OrderHeader();
oh.Customer = cust;
oh.AddItem(item1);
oh.AddItem(item2);
oh.AddItem(item3);
oh.Complete();
oh.Send();

That code sample is a simple API order system that is creating an order request with three items. You may argue that the code is really simple to follow, and there is no need to refactor, and I agree with you. However, we should think of a more complex API which may require you to add so many lines of code and call methods that are not that descriptive. With that in mind, let’s look now at how we can make the order creation a bit fluent:

//Fluent API
OrderHeader.CreateOrder()
.WithCustomer(cust)
.WithItems(item1,item2,item3)
.CompleteAndSend();

You can see that the code reads more like a sentence or language than actual method calls. It is descriptive and easier to use which is our main goal.  So how does the code for this look?  Well, let’s see now:
/// <summary>
/// defines a domain specific interface
/// </summary>
interface FluentOrderHeader
{
FluentOrderHeader WithItems(params OrderItem[] item);
FluentOrderHeader WithCustomer(Customer cust);
void CompleteAndSend();

}

/// <summary>
/// partial class to expose fluent api
/// </summary>
partial class OrderHeader : FluentOrderHeader
{
public static FluentOrderHeader CreateOrder()
{
return new OrderHeader();
}

public FluentOrderHeader WithItems(params OrderItem[] items)
{
foreach (OrderItem item in items)
{
   this.AddItem(item);
}
return this;
}

public FluentOrderHeader WithCustomer(Customer cust)
{
this.Customer = cust;
return this;
}

public void CompleteAndSend()
{
this.Complete();
this.Send();
}

}

We first define the interface with the methods that can help our API become fluent.  You should note that each call returns the instance reference. This allows for the chaining of the methods.  The next step is to create a partial class of the OrderHeader that implements our interface. This allows us to isolate the changes to the partial class without making any modifications to the current code. This new class handles the implementation changes using the existent API.

In my opinion, a fluent interface should be used to simplify obscure APIs which are often used in several projects. If the API is only use by one system, the effort to adapt a fluent interface may not be necessary. We need to keep in mind that a fluent implementation requires a bit more thinking, so it can actually provide a descriptive and fluent set of methods which allows any developer to easily follow it. Do not confuse this with just method chaining. The main different between method chaining and fluent interface is that with the latter we are trying to define a domain specific language that tries to target a specific task. Method chaining just facilitates the use of APIs by returning a reference, so it can be used in subsequent calls.


6/14/11

TFS – How to Record Support Hours on an Iteration

In project management, there is always a need to record how much work is being done to troubleshoot and/or identify issues for a particular release.  To address this, we could set up a team project with the following settings:

Area and Iteration Path:
Create an area path specifically for support issues. For example, the area path could read the following:
Area Path
   Description
Support\Stage
Use this for the staging environment
Support\Production
Use this for the production environment

This allows us to track supporting tasks done in either the staging or production environment.
The iteration path should be set to your software iteration. For example, if in stage you are running version 2.13.0, and you need to create a support task to troubleshoot something in stage. You set the area path to stage and the iteration to version 2.13.0. The same can be applied when a task needs to be created on a production release. This allows us to track the number of tasks in each environment and for each release/iteration

Task Detail:
When you create a task, the task should be created with this additional information:
Property
   Value
   Description
Discipline
Analysis
This depends on the template you are using on TFS. You may create another entry that reads Support.
Type
Corrective or Mitigation
On stage you may use Corrective to correct problems before production. On production , you can use Mitigation because you need to minimize the impact of the problem
(Details tab)  Schedule Estimate
hours
The estimated hours
(Details tab)  Schedule Remaining work
hours
The work still remaining. This is important to update because a tasks may not be completed the same day, but you need to report the number of hours left.
(Details tab)  Completed  work
hours
The hours completed in the tasks

 It is important to add the completed work and remaining work to the correct Area and iteration path. This would be the only way that the reports can accurately show how much support effort is being done and in what iteration. This can lead to a better understanding of the development process and identify possible issues.
I hope this is useful.

og-bit.com

3/1/11

Improve Code Maintenance with Visual Studio Code Metrics Analysis

There are several factors that make a code very difficult to maintain. Some of the most common factors are never ending functions that may have hundreds lines of code and functions that have deep nesting if then else statements. Visual Studio comes with a feature call Code Metrics. This is available in the Analyze menu options or by selecting the project you want to analyze and selecting the Calculate Code Metrics context menu option.
Maintainability Index
The main purpose of this utility is to calculate the maintainability index which provides a quick indicator of how difficult it may be to maintain the code. The goal is to get a high value with 100 being the maximum value. There may be an index of 50, but this does not mean the index is a poor one. Instead, there is a rating icon next to the index. This icon represents the category in which the code index falls on. These are the current color codes and ranges:

Green Rating
20-100
Code has good maintainability
Yellow Rating
10-19
Code is moderately maintainable
Red Rating
0-9
Code has poor maintainability

The goal is to achieve a green rating. I have noticed that code with rating below fifty could be easily refactored to improve the index. In your projects, you may want to target anything below 50 or 60.

Cyclomatic Complexity
This measures the number of different paths in the flow of the program. We need to remember that decision paths in a function require more test to get code coverage. A function with no decisions results in a value of one. A function with a value of eight or more should be refactored to improve the maintainability index.  Common problem areas that increase this value are the nesting of if then statements, comparison in a LINQ statement, switch statements.

Depth of Inheritance

This measures how deep classes are located in the inheritance tree. This can sometimes make it more difficult to understand in what parent class certain methods or properties are actually implemented. You should try to keep this value less than five

Class Coupling

This measures the use or coupling of other classes in a class method in the form of parameters, return types, method calls, attribute decoration. High coupling indicates that there is low maintainability because of the interdependencies on other classes that reside in the same assembly or on a different one. Anything over a value of eight should raise a flag, and the code should be reviewed.

Lines of Code

This is the most obvious indicator. Functions over 60 lines of code should be looked and split into more logical functions.

The recommended values I listed on this article should be used only as a suggestion for your projects. To get more accurate results, you should evaluate your projects and create a baseline that works for your goals. The key element here is to not let the code become something that is just too difficult and confusing to maintain.

I hope you find this useful.

og-bit.com

12/22/10

Use Preprocessor Directives to Support Multiple Web Service Versions

When there is a new version of a web service in a different URI, we usually just need to point to that new URl and get the new reference class for that service. A problem may arise when the new service definition does not keep backward compatibility, and your project will no longer compile because a property or method was either renamed, or it no longer exists.
An approach to address this problem is to create an assembly that provides a facade to abstract the object model of the web service.  In this facade, you can use preprocessor directives to indicate what web service namespace to include and what code to compile. This is a simple scenario:

Version 1
Version 2
namespace mydomain.services.version1 {
   
  public partial class myclass {
     public string LName;
     ....
  }
}
namespace mydomain.services.version2 {
   
  public partial class myclass {
     public string LastName;
     ....
  }
}


In this scenario,  the namespace and a property have changed. If you try to compile the code that consumes the web service using version two, there will be compilation errors because the namespace does not exists, and there is no LName property. You will then need to change the code to match the new web service definition, and all should work fine. But, what if you need to support both web service versions for different product releases? In this case, you may want to have the implementation for both versions in the same codebase. To achieve this, you can write the following on the facade class:
#if USE_VERSION2
using mydomain.services.version2;
#else
using mydomain.services.version1;
#endif
On the project conditional compilation symbols,you can add USE_VERSION2 as the symbol to indicate what code segment should be included. In this case, version2 wil be used. If not compilation symbol is added, the default will be version1.
To address class members backward compatibility like in the case of the LastName property change, you write a facade property as follows:
public string LastName
{
#if USE_VERSION2
    get {return service1.LastName;}
#else
    get {return service1.LName;}
#endif        
}
The property provides access to the member of the selected version. In this case, LastName when using version2 or LName as the default.
With this approach, the client that consumes the facade is abtsracted from the web service object model. Support to additional versions is done in the facade thus minimizing the impact to the rest of the application.
I hope you find this useful.


og-bit.com