Tuesday 26 November 2013

Characteristics of a productive development team

In Agile Fluency article, Diana Larsen and James Shore have mentioned that Agile teams develop through four distinct stages of fluency. They have defined one star, two star, three star and four star team based on the team Agile fluency. It is an interesting article. If you take all the attributes of one, two and three star team (I will not include four star as it is bit difficult to find a four star team) then you will see that they are the characteristics of a productive development team.
A good and productive development team needs to follow some kind of Agile methods. It may be Scrum or Kanban. Ideally they have a product backlog. They use retrospectives to find out what has gone well and also what hasn't gone well in last iteration. They should keep on doing what has gone well and at same time try to avoid what hasn't gone well. They should write good user stories. A good user story solves many misunderstandings since it involves you to interact with different stackholders of your organization.
Practicing Scrum or Kanban without test-driven development (TDD) is rubbish. Martin Fowler calls it FlaccidScrum. One of the characteristics of a productive team is that they write self testing code. It helps them to reduce their technical debt. Now many teams are also practicing behavior driven development (BDD) along with TDD, which is really good. Main point is, a good team should focus on values and qualities. It is about collective ownership or shared responsibilities.
A productive team simply just don't stop here. They automate their build process. They follow practices that are required to do continuous integration effectively.
Another interesting attribute of a productive team is frequent release. They release as frequently as possible. It helps them to get rapid feedback on new features they have added. These feedbacks are important to build the right product.

Sunday 10 November 2013

Media Types

Contracts define how different parts of a distributed system should interact and media types play an important part in contracts.

 A media type is a combination of formats, processing model, and hypermedia controls.

We can use many standardized media type specifications or create new media types to fit our domain.
Standardized media types (e.g., XHTML or Atom) are well-defined and widely understood. Since many systems support these standardized media types, interoperability between them can be easily achieved by using them.
Custom media types help us to add application specific semantics on the top of generic media types handlers. Jim Webber mentioned a nice example in his blog about custom media type:
"For example, if you get an Atom representation, then you automatically understand (globally) how to interpret the atom:link links within; with a custom hypermedia type (... application/restbucks+xml) you automatically understand (within the Restbucks context) how to interpret links; but for application/xml you have no idea how to extract hypermedia controls unless you have some prior knowledge of the schema."
Reference: REST in Practice - Jim Webber, Savas Parastatidis and Ian Robinson

Saturday 19 October 2013

Characteristics of different levels in Richardson Maturity Model

Recently I am involved in building a Campaign Management System based on Richardson's Level 3 service definition. It's a new thing for my team and we are enjoying it. Leonard Richardson proposed a classification of RESTful web services in his talk. He mentioned four levels in his classification. Richardson evaluated service maturity based on three core technologies: URI, HTTP and Hypermedia. Each layer builds on the concepts and technologies of layers below.




So what are characteristics of these levels?
Level 0 Services
  • HTTP is used as a transport system to tunnel requests and responses.
  • A single URI.
  • Use a single HTTP method (typically POST), ignore the rest of the HTTP verbs.
  • Examples: SOAP, XML-RPC and POX (Plain Old XML).
Level 1 Services
  • Introduce Resource concept.
  • Employ many URIs and each URI acts as an entry point to a specific resource.
  • Still a single HTTP verb is used.
Level 2 Services
  • At this level services host many URI-addressable resources and also support several of the HTTP verbs on each exposed resources.
  • The use of GET for requesting resource is important. HTTP defines GET as safe and idempotent operation. This property of GET help us to optimize the services. When a consumer of a resource uses GET, we know he does not want to modify it. We can use caching to store responses closer to our consumer. Subsequent requests will be served from the caches and that helps in improving the overall quality of the service.
  • Another important characteristic is the use of status codes. Services use different status codes to respond. When a resource is created, services respond with a 201 Created whereas 409 Conflict is used to tell that something has gone wrong.
Level 3 Services
  • Support HATEOAS (Hypermedia As The Engine Of Application State)
  • Now the representations contain URI links. These links may point to other resources (may be interesting to the consumers) or they may represent a transition to a possible future state of the current resource. One important thing to notice here - service tells the consumer what to do next through these links.
  • Here the consumer submits an initial request to the entry point of the service. The service handles the request and responds with a resource representation populated with links. The consumer chooses one of these links to transition to the next step in the interaction. Over the course of several such interactions, the consumer progresses toward its goal. In this way the distributed application's state gets changed.
  • Consumers in a hypermedia system cause state transitions by visiting and manipulating resource state.
References:

Saturday 22 June 2013

Self Encapsulation

What is Self Encapsulation?

Martin Fowler mentioned this in his bliki :

"Self Encapsulation is designing your classes so that all access to data, even from within the same class, goes through accessor methods."

This is also called Self Delegation. Take this simple Email example:

public final class Email implements Serializable { private static final long serialVersionUID = 1L; private String emailAddress; public Email(String anEmailAddress) { super(); this.setEmailAddress(anEmailAddress); } public Email(Email anEmail) { this(anEmail.getEmailAddress()); } public String getEmailAddress() { return this.emailAddress; } private void setEmailAddress(String anEmailAddress) { if(anEmailAddress == null) { throw new IllegalArgumentException ("Email address must not be null."); } if(anEmailAddress.length() == 0) { throw new IllegalArgumentException ("Email address is required."); } if(!java.util.regex.Pattern.matches( "\\w+([-+.']\\w+)*@\\w+([-.]\\w+)*\\.\\w+([-.]\\w+)*", anEmailAddress)){ throw new IllegalArgumentException ("Email address format is invalid."); this.emailAddress = anEmailAddress; } }

In above example, constructor is delegating instance variable, emailAddress assignment to its own internal property setter. Here the setter method is not only setting the email address, but also performing an important assertion. It is providing a guard against invalid data. The self-encapsulation enables the setter method to determine the appropriate contractual condition for setting the email address. This is the advantage of using Self Encapsulation.



References
1. http://martinfowler.com/bliki/SelfEncapsulation.html
2. Implementing Domain-Driven Design - Vaughn Vernon

Saturday 8 June 2013

Template I follow in writing user story

User story one of the important item in your agile toolkit. A good user story will drive you to solve the right problem. I like writing user story. For me it is a discovery phase. Many unknown small but important requirements I have found when writing user story (some of my aha moments!!). Here is the template I follow when I write user story:

User Story:

Title: (one line describing the story)

As a {role} I want to {action} so that {benefit}

Notes (or Scopes):

Add any relevant background information, specific algorithms or formulas, conversation etc.

Acceptance Criteria:

Given {context/system status}
when I {input/action}
then I should {result}

When I write the user story I think about the benefit or business value that I am going to add by implementing this feature. Even when my product owner writes the user story, I discuss the benefit of the feature with him. It gives me an opportunity to get a good understanding of the requirement. It also helps to find out the required definition of done.

Role helps me to find out my primary user. Sometimes I find it easily just by discussing with product owner, sometimes I talk to different stackholders to find it out. You may face the similar situation, just take time in your finding.

Action outlines the main flow of interaction which needs to be addressed.

Notes or scopes are optional for me. I may not need them always. When I work on a complex problem that requires further discussion. In these discussions I may come across many important information and references. I write them under this section for future references.

Acceptance criteria is another important part in my user story. In this section I write down the expected behaviour and corner cases. I review them with the product owner and tester. Acceptance criteria help me to reduce the ambiguity and at the same time I get the sense of done once I complete coding that meets the criteria. I write them in BDD (Given-When-Then) format. One thing to remember here, you may not have all accept criteria when implementation starts and also do not expect them to remain static. They may change and so adjust them accordingly.

Wednesday 5 June 2013

DDD Note: Domain

Domain is a sphere of knowledge or activity. For instance, you go to your favourite superstore to buy some products. Superstore buys these products from different sources and sells them to its customer. This superstore has its own unique business knowledge and way of doing things. This understanding and its methods for carrying out its activities or operations is its Domain. If this superstore requests you to develop a software for them, then you will be working in its domain.

It is rare to find a business that has only one functionality. There are different functions that make a business successful. It is always good to think about each of those business functions separately as a Subdomain. So a domain consists of multiple subdomains. In our superstore example, we can say that it has four subdomains: Product Catelog, Orders, Invoicing, and Shipping.

Some subdomains can be labeled as core domains. A Core Domain is a part of the business domain that is most important. The success of the business mainly depends on it. It deserves most of your attention and resources.

There are two other types of subdomains: Supporting Subdomain and Generic Subdomain. In many occasions you will find that there are services created or acquired to support the business. If it models some aspect of the business that is essential, yet not Core, it is a Supporting Subdomain. Supporting subdomains provide specialized functionality, whereas Generic Subdomain captures those activities that are not special but are required for the overall business solution.

Remember Supporting and Generic subdomains are not unimportant and they also deserve attention from you. But there is no need for the business to excel in these areas. It is the Core Domain that will provide distinct advantages to the business, hence it requires excellence in implementation.


References:
  1. Domain-Driven Design - By Eric Evans
  2. Implementing Domain-Driven Design - By Vaughn Vernon

Friday 31 May 2013

7 tips to make your tests readable

If you want to make your TDD sustainable, then please give importance to the readability of your tests. When a programmer reads your test, he or she needs to understand the purpose of test. No developer likes to stop and puzzle through a test to figure out what it does. You can reduce the cognitive load of your reader by making your tests readable. Here are some tips that you can use to improve the readability of your tests. I hope you will find them useful.

Tip 1: Give importance to test name

By choosing a right name for your test you are giving the first clue to your reader about the intention your test and how the target object is supposed to behave. Try to select a name that says something about the scenario and the expected behaviour.

Tip 2: Structure your unit test

Try to follow "Arrange, Act, Assert" pattern to structure your unit test. "Arrange, Act, Assert" basically means that you want to organize your tests such that you first arrange the objects used in the test, then trigger the action and make assertions about the outcome last. You can add whitespace in between these three segments to help others to understand your tests more easily. For example:

@Test public void shouldFindCustomerByUsername(){ //Arrange when(customerDaoMock.findByUsername("jonsmi")) .thenReturn(getFakeCustomer()); //Act Customer customer = customerService .findCustomerByUsername("jonsmi"); //Assert assertThat(customer.getId(), is(101L)); assertThat(customer.getUsername(), is("jonsmi")); }

Tip 3: Put emphasize on "what" over "how"

Try to give importance on "what" over "how" even for your test code. Move out the unnecessary implementation details from your test code. This details create noise, which makes harder for your reader to understand what is important in your test. Also try to use Hamcrest matcher utilities such as assertThat, is, anything, notNullValue, hasItem etc. JUnit currently ships with Hamcrest. These utilities help you express your intent clearly and reduce verbosity from your tests. For instance, instead of doing this:

assertTrue(activities.contains("PLAY")); assertTrue(activities.contains("READING")); assertTrue(activities.contains("WRITING"));
You can do this:
assertThat(activities, hasItems("PLAY", "READING", "WRITING"));

Tip 4: Extract common features into methods that can be shared

Many times we write the same thing again and again in our test methods. Remember DRY (Don't Repeat Yourself) principle. Extract common or nonessential features into private helpers and setup methods. But be careful not to make your tests so abstract that future readers do not understand what tests do.

Tip 5: A test should only check one thing and check it well

When you put multiple tests in a single test method, you are going to confuse others. If you have a big test method, split it into smaller test methods. Each test should focus on single fixture. By doing this, you will improve readability significantly. Another additional benefit you will get, when a test fails you need to look into smaller portion of code to find the reason. So it improves maintainability as well.

Tip 6: Try to avoid magic numbers

I think every programmer agrees that magic numbers are bad and should be avoided. Replace them with constants or variables that give them desired meaning, making code easier to read.

Tip 7: Simplify your setup method

Do not dump everything in your setup method (annotated with @Before or @BeforeClass). By doing this, you are making setup method over complicated. It is also an indication of design problem that forces the test to do so much work to put an object under test. Extract all the nonessential details from the setup into private methods. Give appropriate and descriptive names to variables and methods used in setup method.


References:
  1. Growing Object-Oriented Software, Guided By Tests - Steve Freeman, Nat Pryce
  2. Effective Unit Testing - Lasse Koskela
  3. Hamcrest
  4. JUnit
  5. TestNG

Sunday 31 March 2013

Things to remember when REST-ing

There are many good blogs and books written on designing and developing RESTful system. I have read some of them. In this post I am sharing some notes that I have taken during that time. Please let me know if I miss anything important (as it is a huge subject). I will update this post accordingly. 

Resource Identification

Every important resource in a RESTful system must have an identifier. Resource identification is very important step in developing RESTful system. We can use URI to identify a resource. A URI uniquely identifies a resource. A resource's URI distinguishes it from any other resources. URI can identify a single resource or a collection of resources. For example:

http://myschool.com/courses/123    [identify course no 123]
http://mystore.com/orders/2013/03  [identify all orders of Mar, 2013]

A resource can have more than one URI, i.e. a resource can be identified in more than one way, but a URI always identifies one resource. Try to use simple URI. Simple URI is always good, no matter whether the resource will be comprehended by human or processed by machine and it is easy to remember.

Resource Representation

Support one or more representations of a resource. What is representation?

A representation is a transformation or a view of a resource's state at an instant in time.

Each resource's identifier (for example: URI) is associated with one or more representations. We can use XHTML, Atom, XML, JSON, plain text, CSV, MP3, or JPEG to achieve this. These are called transferable or representation formats. In web, different systems exchange representations. They do not access the underlying resource directly. URIs relate, connect, and associate representations with their resources on the web.

Try not to give any indication to the consumers to terminate URIs with .json or .xml to get a resource representation in preferred format, rather use content negotiation. Consumers can use content negotiation to negotiate for specific representation formats from a service. They will use HTTP Accept request header with a list of media types they're prepared to process. But careful, service does not have to oblige the consumer's request. Service may send resource representation in xml even though consumer has requested in json format. So check the content type in response.

Utilize Link

Utilize links to drive application state. It is the core of HATEOAS (Hypermedia as the engine of application state). In a hypermedia system, application states are communicated through representations of uniquely identifiable resources. The client submits an initial request to the entry point of the service. The service handles the request and responds with a resource representation populated with links. The client chooses one of these links to transition to the next step in the interaction. The client progresses toward its goal by making several such interactions. In this process, application's state changes. So we can say, the change of application's state depends on the service, client, exchange of hypermedia-enabled resource representations, and the advertisement and selections of links. Link approach is beautiful because links help us to point to a resource provided by a different application or may be by a different company.

Resource state is not same as Application state

Roy Fielding mentioned this (in comment section) in one of his blog:

Don't confuse application state (the state of the user's application of computing to a given task) with resource state (the state of the world as exposed by a given service). They are not the same thing.

Resource state and application state are two different things. They should not be confused. When the service and consumer interact, they exchange representations of resource state, not application state. Application state is defined by a representation that is handed to a consumer by the service. When a consumer makes a request, it gets a small subset of the overall server state and certain transitions (represented as link) to other application states that are offered by the service. Please see another comment by Roy here in this regard.

Do not ignore or misuse HTTP status codes

When a client makes a request to the server, server returns an HTTP status code in response to the request. This status code is important because it provides information about the status of the request. There are five categories of these status codes: 1XX range for informational, 2XX range for success, 3XX range for redirection, 4XX range for client error and 5XX range for server error. It is not good to mix them up because they are helpful to deal with different scenarios. For example: it is not good to send 200 status code and an error message in the response body in case of an error happens. If these codes are used properly, they increase re-usability, better interoperability, and loose coupling.

Use caching

Caching helps us to increase the scalability of a RESTful system by storing copies of frequently accessed data in several places along the request-response path. There are benefits of using caching. It reduces bandwidth, latency, load on servers and helps to hide network failure. Using HTTP headers, an origin server indicates whether a response can be cached, and if so, by whom, and how long. Caches along the response path can take a copy of a response (provided that caching metadata allows it). The caches can then use these copies to satisfy subsequent requests.

There are two main HTTP response headers that can be used to control the caching behaviour:

Expires: The Expires HTTP header specifies an absolute expiry time for a cached representation. After that time, a cached representation is considered stale and must be revalidated with the origin server. A service can indicate that a representation has already expired by including an Expires value equal to Date header or a value to 0. To indicate that a representation never expires, a service can include a time up to one year in the future.

Cache-Control: The Cache-Control header can be used in both requests and responses to control the caching behaviour of the response. The header value comprises one or more comma-separated directives, that are used to determine whether a response is cacheable, by whom, and for how long.

Cacheable responses (GET/POST) should also include a validator either an ETag or a Last-Modified header:

ETag: ETag is useful to validate the freshness of cached representation of a resource. An ETag value is an opaque string token that a server associates with a resource to uniquely identify the state of the resource over its lifetime. When the resource changes, the ETag changes accordingly.

Last-Modified: Last-Modified header indicates when the associated resource last changed. The Last-Modified value cannot be later than the Date value.

If a consumer wants to revalidate a response, it should include a Cache-Control: no-cache directive in its request. This ensures that the conditional request travels all the way to the origin server, rather than being satisfied by a cache.

When doing validation, use conditional GETs. A conditional GET only sends and receives just HTTP headers rather than headers and entities bodies. It only exchanges entity bodies when a cached resource representation is out of date. Conditional GETs are useful only when the client making the request has previously fetched and held a copy of a resource representation along with ETag or Last-Modified value. Consumer or cache uses a previously received ETag value with an If-None-Match header, or a previously supplied Last-Modified value with an If-Modified-Since header. If the resource hasn't changed (that means its ETag or Last-Modified value is the same as the one supplied by the consumer), the service replies with 304 Not Modified (plus any ETag or Location headers). If the resource has changed, the service sends back a full representation with a 200 OK status code.

Consumers can also influence cache behaviour by sending Cache-Control directives in requests: max-age, max-stale, min-fresh, only-if-cached, no-cache, no-store.

Other things to consider:
  • Use a hypermedia-aware media type such as HTML, XHTML, SVG, Atom
  • Do not tunnel updates through GET
  • Use self-descriptive message
  • Try to ignore chattiness with many round trips
  • Try to accept and support compression as defined by the HTTP 1.1 specification
  • Try to render relative links where possible
  • Try to implement paged representation where applicable
  • Do not misuse cookies
  • Think about security

References: