0

CQRS à la Greg Young

Posted by Mark Nijhof on Nov 11, 2009 in Dotnet  | View Original Article
 

This post was originally posted on my previous blog: blog.fohjin.com.

I have had the pleasure of spending a 2 day course and many geek beers with Greg Young talking about Domain-Driven Design specifically focused on the Command and Query Responsibility Segregation (CQRS) pattern. Greg has taken Domain-Driven Design from how Eric Evans describes it in his book and has adapted mostly the technical implementation of it. Command Query Separation (CQS) was originally thought of by Bertrand Meyer and is applied at object level.

CQS: “every method should either be a command that performs an action, or a query that returns data to the caller, but not both. In other words, asking a question should not change the answer”

-Bertrand Meyer

Greg however takes this same principle but he applies it to the whole architecture of a system, clearly separating the write side (Commands) from the read side (Queries) of the system. The write side is what we already know as the domain, containing all the behavior which is what makes the system valuable. The read side is specialized towards the specific reporting needs, think for example about the application screens that enables the users to execute domain behavior, but also any traditional reporting needs are provided by the read database.

So lets take a quick look at the overall architecture before we dive into the details:

Command and Query Responsibility Segregation (CQRS) - Overview Command and Query Responsibility Segregation (CQRS) – Overview

You have to excuse me for not using Visio to make this drawing, but I really didn’t feel like tackling yet an other layer of complexity tonight. At least I did the labels in typed text, so it is readable. I will discuss this architecture in 4 phases, the order I choose is what I believe is the natural way your would think about this. In the end you will see that the whole principle is rather simple. Really.

Command and Query Responsibility Segregation (CQRS) - Division Command and Query Responsibility Segregation (CQRS) – Division

  1. Queries
  2. Commands
  3. Internal Events
  4. External Events (Publishing)

In order to understand this type of architecture better I decided to build an example application; I will use this example in this post to demonstrate the different aspects of the architecture to you. The example has already been released in the wild (ok I meant the DDD group on Yahoo) and can be found here:http://github.com/MarkNijhof/Fohjin

Queries (reporting)

The first part I would like to discuss is the reporting needs of a system, Greg defines any need for data from the system as a reporting need; this includes the various application screens which the user uses to base his decisions on. This seemed like a strange statement at first, but the more I think about it the more sense it makes. This data is purely used to inform the user (or other systems) about the current state of the system in the specific context of the user so that they can make certain decisions and execute domain behavior.

These reports will never be updated directly by the consumer of these reports, the data represents the state of the domain, so the domain is responsible for updating it. So all we really do on this side is report the current state of the system to who or what ever needs it.
When an application is requesting data for an specific screen than this should be done in one single call to the Query layer and in return it will get one single DTO containing all the needed data. Now because of this specific use of the data it makes sense to order and group it in such a way that is determined by the needs of the system. So we de-normalizing the data trying to make a single table reflect a single screen or usage in the client application. The reason for this is that data is normally queried many times more than domain behavior is being executed, so by optimizing this you will enhance the perceived performance of the system.

Here you may choose to use an ORM like NHibernate to facilitate the reading from the database, but considering that you would only be using a very small percentage of the capabilities of a proper ORM you may not need to go that way at all. Maybe going for Linq2Sql of even as Greg suggested using reflection to assemble the SQL statements directly from the DTO’s (using reflection and Convention over Configuration makes this rather simple) is perhaps a better solution for the problem. This will be up to you and probably depends on specific scenario and what you feel comfortable with.

In the example that I created to demonstrate this type of architecture I choose for using reflection of the DTO’s because I wanted to put the emphasis on the CQRS implementation and not on the ORM implementation.

The more traditional reporting needs will also get its own database schema and the data there will be optimized for that need as well, so in the end we will end up with quite a bit of duplication of the data, but that is all right. The process that is responsible for updating the data in the different databases will make sure that this happens in the correct way, we will go over this in a later part of this post.

Commands (executing behavior on the domain)

Lets first consider what would normally happen after receiving a DTO; the user would make changes to the data and save this back on the DTO. This DTO then gets shipped back to the back-end, converted into an entity and the ORM will make sure that the changes are persisted into the database.

This would result in loosing some very valuable information; the Why did this change happen? You completely loose the intent the user had when he changed the data, and this is one of the things Greg’s implementation of CQRS is solving.

CQRS as the name indicates uses Commands, these commands are created on the client application and then send to the Domain layer. Lets take an example: A customer from a bank comes in the office and tells the person behind the desk that he needs to change his address. And instead of just getting the customer information and making the changes directly in the address fields, the bank employee firsts asks the question; Why would you want to change your address? The most likely response would be because the customer has moved, but it could also be because there is an error in his address and that all his mail ends up with his downstairs neighbor. Now these are two completely different reasons to update a customer address. Why could this be important? Well granted the example is rather silly, but lets assume the bank wants to know how many customers go to a competitor after moving? How loyal are our customers, should we keep sending them specific information after they have moved x miles away? Right this information is completely lost in our original way of working, but when using commands and events (more on events later) we maintain the original intent of the action. So after asking the question the customer answers that he has indeed moved and the bank employee selects the “Customer has moved" in the application and gets the ability to change only the address. When clicking save a CustomerMovedCommand will be created with only the changed address and is send to the domain.

We also get one other great benefit from using these commands and that is that these commands are easy to communicate with our client while building or working on the system. Because our clients would most likely use these types of behavior when explaining what they want to accomplish. Al do Greg thinks times have changed, “Our grand failure", but it should really be the case that our clients talk their own domain language. When using these commands we can start talking the same language even in the code.

That is what Domain-Driven Design is all about, instead of doing something technical like update client, it is actually describing the process that the user uses into the code like; the client has moved.

Command

    1 namespace Fohjin.DDD.Commands
    2 {
    3     [Serializable]
    4     public class ClientIsMovingCommand : Command
    5     {
    6         public string Street { get; private set; }
    7         public string StreetNumber { get; private set; }
    8         public string PostalCode { get; private set; }
    9         public string City { get; private set; }
   10 
   11         public ClientIsMovingCommand(Guid id, string street, string streetNumber, string postalCode, string city) : base(id)
   12         {
   13             Street = street;
   14             StreetNumber = streetNumber;
   15             PostalCode = postalCode;
   16             City = city;
   17         }
   18     }
   19 }

All these commands will be send to the Command Bus which will delegate each command to the command handler or command handlers. This also effectively means that there is only one entry point into the domain and that is via the Bus. The responsibility of these command handlers is to execute the appropriate behavior on the domain. Close to all of these command handlers will have the repository injected to provide the ability to load needed the Aggregate Root on which then the appropriate behavior will be executed. Usually only one Aggregate Root will be needed in a single command handler. Later we will also take a closer look at the repository as it is different from your ordinary DDD repository.

Command Handler

    1 namespace Fohjin.DDD.CommandHandlers
    2 {
    3     public class ClientIsMovingCommandHandler : ICommandHandler<ClientIsMovingCommand>
    4     {
    5         private readonly IDomainRepository _repository;
    6 
    7         public ClientIsMovingCommandHandler(IDomainRepository repository)
    8         {
    9             _repository = repository;
   10         }
   11 
   12         public void Execute(ClientIsMovingCommand compensatingCommand)
   13         {
   14             var client = _repository.GetById<Client>(compensatingCommand.Id);
   15 
   16             client.ClientMoved(new Address(compensatingCommand.Street, compensatingCommand.StreetNumber, compensatingCommand.PostalCode, compensatingCommand.City));
   17         }
   18     }
   19 }

As you can see a command handler has only one responsibility and that is to handle the one particular command by executing the appropriate domain behavior. The command handler should not be doing any domain logic itself. If there is a need for this than that logic should be moved into a service of its own. An example of this is in my example code is an incoming money transfer, more about that later.

Internal Events (capturing intent)

So finally we have arrived at the actual domain, the client has requested a certain view of our domain, has received the appropriate report DTO and has made a decision which resulted into a command being published. The appropriate command handler has then loaded the correct Aggregate Root and executed the appropriate domain behavior. So now what?

Now we are going to separate the domain behavior from the state changes resulting from this domain behavior including the triggering of external behavior. This would not be much different from how you would do this now, first verify the normal guards, do what you have to do, but don’t set any internal state, and don’t trigger any external behavior (Ok the last part is more an optional thing to consider, state is the key here). Instead of writing these state changes directly to the internal variables you create an event and fire it internally. This event as well as the method name of the behavior should be descriptive in the Ubiquitous Language of the domain. Then the event will be handled inside the domain Aggregate Root which will set the internal state to the correct values. Remember that the event handler should not be doing any logic other then setting the state, the logic should be in the domain method.

Domain Behavior

    1 public void ClientMoved(Address newAddress)
    2 {
    3     IsClientCreated();
    4 
    5     Apply(new ClientMovedEvent(newAddress.Street, newAddress.StreetNumber, newAddress.PostalCode, newAddress.City));
    6 }
    7 
    8 private void IsClientCreated()
    9 {
   10     if (Id == Guid.Empty)
   11         throw new NonExistingClientException("The Client is not created and no opperations can be executed on it");
   12 }

Domain Event

    1 namespace Fohjin.DDD.Events.Client
    2 {
    3     [Serializable]
    4     public class ClientMovedEvent : DomainEvent
    5     {
    6         public string Street { get; private set; }
    7         public string StreetNumber { get; private set; }
    8         public string PostalCode { get; private set; }
    9         public string City { get; private set; }
   10 
   11         public ClientMovedEvent(string street, string streetNumber, string postalCode, string city)
   12         {
   13             Street = street;
   14             StreetNumber = streetNumber;
   15             PostalCode = postalCode;
   16             City = city;
   17         }
   18     }
   19 }

Internal Domain Event Handler

    1 private void onNewClientMoved(ClientMovedEvent clientMovedEvent)
    2 {
    3     _address = new Address(clientMovedEvent.Street, clientMovedEvent.StreetNumber, clientMovedEvent.PostalCode, clientMovedEvent.City);
    4 }

The reason why we want these events is because they now become part of our persistence strategy, meaning that the only information we will be persisting of an Aggregate Root are the generated events. So if every state change is triggered by an event, and an internal event handler has no other logic then setting the correct state (and that means not even deriving other information from the data in the event), then what we can do then is load all historical events and have the Aggregate Root replay them all internally bringing back the original state of the Aggregate Root in exactly the same way it got there in the first place. It really is the same as replaying a tape.

One thing to note is that these events are write only, you will never add, alter or remove an event. So if you suddenly end up with a bug in your system which is generating wrong events, then the only way for you to correct this is to generate a new compensating event correcting the results of the bug. Of course you want to fix the bug as well. This way you have also tracked when the bug was fixed and when the effects of the bug where corrected.

By having this architecture we now basically solved the problem of loosing original intent, because we keep all events that have ever happened and these evens are intent revealing. An other very interesting thing is that now you have an audit log for free, because nothing will ever change state without an event and the events are stored and used in building up the Aggregate Roots they are guaranteed in sync with each other.

The Domain Repository

I mentioned before that the Domain Repository would be completely different from one that is normally the result of practicing DDD. Normally you would end up with very specific repositories allowing the request of all kinds of different information from the domain. But when using Greg’s implementation of CQRS your domain is completely write only, so the repository only has to be able to Get an Aggregate Root by its Id and it must be able to save the generated events. You also completely get rid of any impedance mismatch between the domain and the persistence layer.

Domain Repository Contract

    1 namespace Fohjin.DDD.EventStore
    2 {
    3     public interface IDomainRepository 
    4     {
    5         TAggregate GetById<TAggregate>(Guid id)
    6             where TAggregate : class, IOrginator, IAggregateRootEventProvider, new();
    7 
    8         void Add<TAggregate>(TAggregate aggregateRoot)
    9             where TAggregate : class, IOrginator, IAggregateRootEventProvider, new();
   10     }
   11 }

The reporting repositories on the other hand would probably look much more like the traditional repositories from DDD.

So what happens when you have 100.000 events that need to be replayed every-time you load the Aggregate Root, that will slow down your system immensely. So to counter this effect you would use the Memento pattern to take a snapshot from the internal state of the Aggregate root every x number of events. Then the repository will first request the snapshot, load that in the Aggregate Root and then request all the events that have occurred after the snapshot, bringing it back to the original state. This is only an optimization technique you would not delete events that happened before the snapshot, that would pretty much defeat the purpose of this architecture.

Data Mining

One other really interesting fact about storing all the events is that you can replay these events at a later date and retrieve important business information from them. And you get this information from the start of the system, instead having to build-in some extra logging and wait a few months for reliable data.

External Events (publishing, letting others know)

Finally we are getting to the fourth part of this explanation (and I am saying this more for my own sake, pfff). So what happens here, looking back at what we have so far, we can read domain state and we can execute behavior and update the internal state of the domain. The obvious thing that is missing is a way to bring the reporting database in sync with the current state of the domain. The way we will be doing this is by publishing the internal domain events outside the domain. Then there are event handlers that pick up on those events and bring the reporting database in sync. This is a place where you could use an ORM, but in fact it is very easy to just generate the needed SQL statements and execute them.

Greg actually mentioned a really nice way of caching these SQL statements, he would batch them in a single batch and execute the batch if it gets older then x seconds, or (and this is the interesting part) whenever a read request came in. So when a read request comes in this SQL statement is appended to the batch and the whole thing is executed, ensuring that the read request will always have the latest data available to that part of the system. More on this below here.

The domain repository is responsible for publishing the events, this would normally be inside a single transaction together with storing the events in the event store.

Events are also used to communicate between different Aggregate Roots, I my example I am using a transaction from one account to an other account. Here I generate an event that money is being transferred to an other account, this event will reduce the balance of the current account. Later an event handler will make the same change in the reporting database. An other event handler will actually forward the transaction to a service which checks if the target account is a local account, else forwards a money transfer to a different bank (in my example the different bank is actually the same, but via a different route). But lets assume that the money transfer goes to an internal account, in that case the service will publish a money transfer received command in the command bus and the whole process continues in a different Aggregate Root. So in this case the command is not triggered from a GUI but from a different part in the system.

There is an other interesting fact in the scenario when money is received from an other bank, because a money transfer only has the account number to identify the target account and not the Aggregate Root Id (you can’t expect foreign systems to know this, yes I know you can make this a natural Id as well) the money received service first needs to do a query to the reporting database requesting an account DTO where the account number is the same as the target account. When this is successful it will use the Id from the account DTO and put that in the command to be published.

But it doesn’t stop there, as I mentioned before you could also have events that don’t have any state change information but for example indicate that a message (Email, SMS or what ever, depends on the event handler) needs to be send to an user. And because you are using Domain Events for all this, everything will be stored in the Event Store, so you keep your history.

Eventual Consistency

Normally when beginning to implement CQRS you would start with a direct publishing mechanism so that storing the events and updating the reporting database happen in the same thread. When using this approach you have no problems with eventual consistency.

But when you system starts to grow you might get some performance problems and then you could start by implementing a bus disconnecting the publishing of the events and handling of these events. This means that it is possible and likely that your event store and reporting database are not completely in sync with each other, they are eventual consistent. Which means that it is possible that the user sees old data on his screens.

Depending on how critical this really is you can have different counter measures for this, which I will be going into in a different post as this is also not something the example provides.

Specifications

The specifications that you can write using this architecture is something that I really like, what you would do is talk to your client and ask him things about how he wants his process to work. So a possible scenario could be:

Withdrawing money from an account

So how would that go? Well the clients needs to have opened an account with our bank and he needs to have some money transferred on it in order to be able to withdraw money from it. And when this happens the balance of the account must be lowered to the correct amount. Ok so, given an account was opened, and a cash was deposited, when making a cash withdraw then we get a cash withdrawn event.

    1 namespace Test.Fohjin.DDD.Scenarios.Withdrawing_cash
    2 {
    3     public class When_withdrawing_cash : CommandTestFixture<WithdrawlCashCommand, WithdrawlCashCommandHandler, ActiveAccount>
    4     {
    5         protected override IEnumerable<IDomainEvent> Given()
    6         {
    7             yield return PrepareDomainEvent.Set(new AccountOpenedEvent(Guid.NewGuid(), Guid.NewGuid(), "AccountName", "1234567890")).ToVersion(1);
    8             yield return PrepareDomainEvent.Set(new CashDepositedEvent(20, 20)).ToVersion(1);
    9         }
   10 
   11         protected override WithdrawlCashCommand When()
   12         {
   13             return new WithdrawlCashCommand(Guid.NewGuid(), 5);
   14         }
   15 
   16         [Then]
   17         public void Then_a_cash_withdrawn_event_will_be_published()
   18         {
   19             PublishedEvents.Last().WillBeOfType<CashWithdrawnEvent>();
   20         }
   21 
   22         [Then]
   23         public void Then_the_published_event_will_contain_the_amount_and_new_account_balance()
   24         {
   25             PublishedEvents.Last<CashWithdrawnEvent>().Balance.WillBe(15);
   26             PublishedEvents.Last<CashWithdrawnEvent>().Amount.WillBe(5);
   27         }
   28     }
   29 }

Ok ok, but now we have the same story, only now there is not enough money on the account, then we should give an exception.

    1 namespace Test.Fohjin.DDD.Scenarios.Withdrawing_cash
    2 {
    3     public class When_withdrawling_cash_from_an_account_account_with_to_little_balance : CommandTestFixture<WithdrawlCashCommand, WithdrawlCashCommandHandler, ActiveAccount>
    4     {
    5         protected override IEnumerable<IDomainEvent> Given()
    6         {
    7             yield return PrepareDomainEvent.Set(new AccountOpenedEvent(Guid.NewGuid(), Guid.NewGuid(), "AccountName", "1234567890")).ToVersion(1);
    8         }
    9 
   10         protected override WithdrawlCashCommand When()
   11         {
   12             return new WithdrawlCashCommand(Guid.NewGuid(), 1);
   13         }
   14 
   15         [Then]
   16         public void Then_an_account_balance_to_low_exception_will_be_thrown()
   17         {
   18             CaughtException.WillBeOfType<AccountBalanceToLowException>();
   19         }
   20 
   21         [Then]
   22         public void Then_the_exception_message_will_be()
   23         {
   24             CaughtException.WithMessage(string.Format("The amount {0:C} is larger than your current balance {1:C}", 1, 0));
   25         }
   26     }
   27 }

The cool part here is that the whole domain is seen as a black box, you are bringing it to a certain state exactly the same way as it is used, then you publish a command just like your application would, and after that you verify that the domain publishes the correct events and that their values are correct. This means that you are never testing your domain in a state that it cannot naturally get to, which makes the tests more reliable.

Now imagine a parser that takes all the class names, underneath each class name it would print the events that occurred to get into the current state. Then you print the command that we are testing. and finally you print the method names that test the actual outcome. This would be a very nice readable specification that the client at least can understand.

Some other benefits

One last benefit I would like to highlight from using this type of architecture is how easy it is to split the work load between different team, more specifically between team with different hourly rates. The domain logic is something that needs to be right, this is where you would put your more expensive developers on, the ones that understand the business, understand good coding practices, you know what I mean. But the read side is not as important, sure it needs to be correct as well, but this is not where the value lies, this can be done quickly and in a year or two again. This is something you let the cheaper developers create, it doesn’t require much domain knowledge all that is really important is that they need to know how the GUI needs to work, what commands they can use and what events to expect.

I think this is of great value for the business, something that is easily overlooked.

Finally

As you can see this is all very simple and straightforward. It is a different mindset, but once you enter this mindset you will notice that your applications will be much more behavioral versus CRUD. And hopefully our clients can move back into thinking about their business logic instead of the thinking about the CRUD way we have forced upon them. Also I would like to thank Greg Young for providing me with so much information and putting up with all my weird questions, and thank Jonathan Oliver and Mike Nichols for some improvements on the technical side.

Tags: , ,

 
0

MSN Video is being re-launched in the U.S. as Bing Video powered by Silverlight and Smooth Streaming

Posted by Silverlight Team on Nov 11, 2009 in Miscelleneous  | View Original Article
 

We are excited to announce the re-launch of the MSN Video on www.bing.com/videos/browse.  For the tens of Millions of MSN Video customers, this release delivers a vastly improved viewing experience with the help of Microsoft Silverlight.  Users demand high quality video but also expect performance.  They want videos to load quickly, seek fast, and playback with no buffering.  By adopting Silverlight Smooth Streaming, MSN and Bing can offer users a clean, simple design, and HD Video (when technically possible) that delivers the best short form and long form video experience available.  This release also includes for the first time a large-scale Microsoft Silverlight-based advertising solution that allows simple monetization of video content. The integration with the Bing Video page allows users to access videos from MSN and other favorite video sites and experience those using the best video playback technology on the Web. The solution that launches in the U.S. today (as part of the Bing Video page) will be propagated to 38 global MSN markets in the near future.

msn


Tags:

 
0

Delete a work Item in TFS

Posted by Kirstin Juhl on Nov 11, 2009 in Dotnet  | View Original Article
 

I needed to delete a work item in TFS and found that by design it is not easy to do.

I found that this can be done using the TFS Power Tools via the command line.

tfpt.exe destroywi /server:http:ServerName//:8080 /workitemid:123

You will get a warning:

This action is not recoverable. Are you sure you want to destroy work item(s)123? (Y/N)

Work item is gone.

Tags:

 
0

slideViewerPro: Highly Customizable jQuery Image Slider

Posted by W3Avenue Team on Nov 11, 2009 in Javascript  | View Original Article
 

slideViewerPro is a fully customizable jQuery image gallery engine which allows you to create sliding image galleries for your projects and/or interactive galleries that can even work within your blog posts. slideViewerPro supports multiple galleries on a single page, and everything is generated by writing just few lines of simple markup (an unordered list of images).

slideViewerPro is highly customizable, but it does not mean that it is difficult to implement. As mentioned earlier it requires only an unordered list to create your gallery. You don’t even need to specify the width and height of your images, it automatically checks for the size and renders accordingly. Of course if you specify or force your images size, slideViewerPro will use specified image property.

Features

  • Fully customize the look and feel
  • Specify delay and duration
  • Supports Captions
  • Ability to randomly shuffle images
  • Supports auto play
  • Auto generate thumbnails

Developed by Gian Carlo Mingati; slideViewerPro jQuery Plugin is dual licensed under the MIT and GPL licenses.  You can find further information, demos & download on slideViewerPro Website.

Similar Posts:

You can also stay updated by following us on Twitter, becoming a fan on Facebook or by subscribing to our FriendFeed.

Tags: , , , , ,

 
0

WebKit Web Inspector improvements

Posted by Roger Johansson on Nov 11, 2009 in Miscelleneous  | View Original Article
 

The Web Inspector is the web development tool that ships with WebKit-based browsers, doing roughly what Firebug does for Firefox. It does some things better and others not quite as well.

The list of things that it does not do quite as well as Firebug became a bit shorter with the recent Web Inspector Updates. Available in recent WebKit Nightly builds, the Web Inspector has improved or added support for things like:

Read full post

Posted in , .


Tags: ,

 
0

CuteTime jQuery Plugin

Posted by W3Avenue Team on Nov 11, 2009 in Javascript  | View Original Article
 

CuteTime is a customizable jQuery plugin that automatically converts timestamps to formats much cuter (i.e., yesterday, 2 hours ago, last year, in the future, etc). Also has the ability to dynamically re-update and/or automatically update timestamps on a controlled interval.

CuteTime can be used as a function or via selector. If used as a function, returns a string containing a cuteTime version of the provided timestamp. If used by Selector, replaces the text of the provided object with a cuteTime. This makes CuteTime unobtrusive, allowing users to see original timestamp if JavaScript is turned off.

CuteTime Displays

  • the future!
  • just now
  • a few seconds ago
  • a minute ago
  • x minutes ago
  • an hour ago
  • x hours ago
  • yesterday
  • x days ago
  • last month
  • x months ago
  • last year
  • x years ago

You can easily localize or change the setting and display text to mach your own needs. Finally make sure you use timestamps that are fully recognized by the JavaScript Date object’s Parse method in all the IE and FF browser versions you want to support.

Developed by Jeremy Horn; CuteTime jQuery Plugin is dual licensed under the MIT and GPL licenses.  You can find further information, demos & download on CuteTime Website.

Similar Posts:

You can also stay updated by following us on Twitter, becoming a fan on Facebook or by subscribing to our FriendFeed.

Tags: , , , , ,

 
0

“Eager Loading” in Actionscript 3

Posted by Amy Blankenship on Nov 11, 2009 in Flex  | View Original Article
  Last week, I wrote about the Lazy Loading design pattern. There's not much written about its opposite, Eager Loading, in ActionScript 3. The reason for this is simple–true eager loading can't be done in AS3 itself, it has to be...

Tags: , , ,

 
0

British journal of cancer finasteride.

Posted by Finasteride. on Nov 11, 2009 in C#, Dotnet  | View Original Article
 

Finasteride. Finasteride versus beta-sitsterol.

 
0

Slides from ALPN Meeting

Posted by Scott Schimanski on Nov 11, 2009 in Dotnet  | View Original Article
 

On October 29th, I participated in the first ALPN workshop.  I presented on general engineering principles for agile development and had a great time doing it.  There was lots of wonderful group participation and input.  Here are the slides: ALPN_AgileEngineering.pdf

Jason Dean and the ALPN group is leading a series of workshops on Agile practices.  They are designed to proceed from entry level discussions to more advanced.  Look for more information on further workshops.

 

For more information, checkout:

The website: www.agileboise.org

The ALPN Boise Google group: http://groups.google.com/group/apln-boise?hl=en&pli=1

Tags:

 
0

Redesign: When To Relaunch The Site and Best Practices

Posted by Kayla Knight on Nov 11, 2009 in Design & Graphics  | View Original Article
 
Smashing-magazine-advertisement in Redesign: When To Relaunch The Site and Best Practices
 in Redesign: When To Relaunch The Site and Best Practices  in Redesign: When To Relaunch The Site and Best Practices  in Redesign: When To Relaunch The Site and Best Practices

Spacer in Redesign: When To Relaunch The Site and Best Practices

Redesigning a website is a big job (needless to say) and should be handled with care. Many of us with a portfolio, blog or other website have probably thought about a redesign or at least know we need one. For many designers, though, that redesign never comes. As big and important as it is, the job can turn into a hugely daunting task that we put straight on the backburner of our to-do list.

Why is doing a simple redesign so daunting? Why is it so difficult to follow through, even when we’ve decided to do it? How can we work on designing our clients’ websites successfully every day and then perpetually neglect our own?

The problem is both a lack of correct planning and a lack of understanding of the root need for the redesign. Once we’ve identified these elements, we’re set for success. In this article, we’ll discuss how to plan and execute a redesign, and how to find the perfect timing for it.

Also consider our previous articles:

What’s All The Fuss About?

Every designer has their own clients and projects. Every day, the designer handles their clients and earns a living for their hard work. When they have spare time on their hands, they may work on side projects that help their personal growth or gain marketing exposure, or both. Sometimes, that side project is to update or maintain their portfolio.

To most, this schedule is all too familiar. The point being: we usually give our side projects a low priority, no matter how much we love them. Although we’d like to develop our website, our time is limited, and clients come first. It’s no wonder that we never find the time or energy to redesign that special side project of ours.

We usually manage to squeeze in time to work on our redesign, usually at the end of the day, in the hope of finishing it a bit at a time. This may seem viable at first, but trying to be productive at the end of a long, stressful day is no way to go about this effectively. We’ll often find ourselves thinking, “I’ll work on it tomorrow.”

Fatigue in Redesign: When To Relaunch The Site and Best Practices

Another reason we don’t follow through is that we can’t articulate why we need a redesign in the first place. What should be included, and what should the process look like? When we finally open Photoshop to get started, we realize we don’t know where to begin. All we know is that, for some reason, we are not satisfied with our current design. This leads us to our only tangible conclusion: the new design has to be better than the last.

And so we are never fully motivated to work on it: we get tired and confused and we put a lot of pressure on ourselves for perfection.

Understanding why we have failed, though, is the first step to success. Let’s look at how to combat all of these obstacles and get that redesign done. Let’s finally cross it off our to-do list, shall we?

Should You Do It At All?

Not every website should be redesigned—at least not at any given time. Being bored with your current design is no reason to change it. In fact, that’s a very poor reason. The purpose of a redesign is to improve usability, update the brand or take the website into a new era.

If you have no good reason for it, a redesign could actually be detrimental. Below are a few reasons why:

  • People love consistency. We love consistency in the websites we visit every day. Whether your website has a large following or not, its design is tightly bound up with its identity and is, in fact, part of your branding. With a complete overhaul, would the website still be recognizable to those people? Would they love it just as much, and would it suit their tastes?
  • Redesigns take time. Planning, designing, trying different things, detailing, development: this is all time taken out of your work day. The redesign may not be a paying job, but it can be worth it if it serves a clear purpose. If it’s needed, take the plunge; if not, why bother? Ultimately, don’t redesign out of boredom.
  • With incorrect or careless planning, you could seriously impair usability or degrade elements. In trying to improve the design, we could very well be making it worse.

We crave a redesigning so much sometimes that we don’t consider its purpose or how a misguided attempt can lead our business astray. If your website could use a bit of cleaning up and not a complete overhaul, consider the option below.

Redesigning vs. Realigning

Cameron Moll wrote a popular article on A List Apart way back in 2005, and it is just as relevant today. Good Designers Redesign, Great Designers Realign compares people who constantly want to redesign their website and people who upgrade or “tweak” their website as necessary.

“…the differences between Redesigners and Realigners might be summarized as follows: The desire to redesign is aesthetic-driven, while the desire to realign is purpose-driven. One approach seeks merely to refresh, the other aims to fully reposition and may or may not include a full refresh.”

Check out the full article to see exactly what he means and for further arguments. Before undertaking a redesign, ask yourself, “Does this website need an entirely new look or just a few tweaks to make things look and function better?”

Realign in Redesign: When To Relaunch The Site and Best Practices

If you’ve decided that a complete redesign is not right for your website, then congratulations: you’ve just saved yourself a lot of time and unproductive work. You may have chosen instead to realign by updating the look of the website, adding interactive elements, improving user-friendliness or something else entirely. You may have chosen to cut things out and minimize the design to highlight the bare necessities.

If you’ve decided that a redesign is still necessary, which it could very well be, then the rest of this article discusses how to make it successful. The first phase is to plan adequately.

Finding The Right Time

Because a redesign will take up so much time, planning ahead for the project’s specifics and timeframe is important. A designer should create a timeline and set a schedule for their own project, just as they would for a client.

Time in Redesign: When To Relaunch The Site and Best Practices

Redesigning Is A Project, Not A Chore

Don’t set up a schedule that allows you the excuse of, “I’ve done enough for today” or “I can do this tomorrow.” If you set aside two hours at 1:00 pm every working day, the redesign will get done. Make it a task of your working day, rather than a chore at the end.

Just as you allocate time for new clients, do the same for this project until it is completed. Once you have set aside time each day for it, be conscious of it and schedule other client projects accordingly. You may need to take on fewer clients during this phase, so be prepared financially as well.

What Time Is Best for the Website?

Finding the right time for the website is just as important as finding the time in your schedule. If you’re redesigning your portfolio, are you in the midst of pursuing any clients. If so, would seeing your website under construction scare them off?

Do you plan on any big changes, upgrades or features that could coincide with the redesign? For example, Smashing Magazine timed its redesign to coincide with the introduction of the Smashing Network, rather than just redesign the blog alone. Redesigning any sooner or later would have been pointless; the new feature made a greater impact by being a part of this other change.

Review your goals for the website and upcoming changes. Planning your redesign around them would probably be most effective.

The Planning Stage

To answer the “Where do I begin” question, we must plan appropriately and in sufficient detail. Without a plan, we’ll run into problems later on, causing us to make many fixes and perhaps give up. Or we might finish the redesign (or come close) and realize that it is not coming together as well as we had envisioned.

So, planning is essential. Below are the elements that need to be planned before starting the redesign or even sketching ideas on paper.

Content Requirements

At the beginning, many designers will start thinking about navigation placement, visual elements, the “feel” of the website and so on. For whatever reason, we don’t think of content first. But we should.

No matter how cool Web design is, content is still king. Good design helps, and so a good redesign will help, but it won’t keep the website alive. A redesign requires one to think about readability, imagery and detailed typography (e.g. tags such as pre, blockquote, ol, ul, etc.) first and foremost.

Assess the current website’s readability. It may be great, but could it be better? Even if it’s readable, look for weak points:

  • Is there enough contrast?
  • Do the alignment, baseline, line height and so on complement the design?
  • Does the width of the content area help or hinder the readability of the content?
  • If the design is flexible, at what point when it stretches or contracts does the content become illegible?
  • Do style elements such as pre and blockquote serve their purpose and stand out?
  • Is the font suited to the letter spacing you’ve set, and is it appropriate to your audience and industry?
  • Even if readable, could the typography be enhanced by vertical rhythm, a typographic scale or something else?

For more information on many of these matters, check out 8 Simple Ways to Improve Typography In Your Designs.

Get out a notebook and thoroughly analyze the typography of your current design. Get feedback from others (both designers and non-designers) on readability, content placement and overall typographic appeal.

One more thing to consider for the content area is the type and size of your existing content. If images have always been a certain width, the content area’s width will need to be matched accordingly. Likewise, content inside pre tags will not naturally break to the next line or adjust to the new content area’s width (after all, that’s it purpose), so take that into consideration as well. Depending on the website, video, imagery and other multimedia may require a redesign to accommodate the content area’s width and position.

Content in Redesign: When To Relaunch The Site and Best Practices

As a general rule, do not redesign the content area to be narrower than what it was before, otherwise a number of complications could arise. If a wide content area has compromised readability, though, approach the resizing systematically. Resize images and optimize content first, then do the redesign.

Back-End Requirements

This stage applies more to complex websites, websites that have WordPress themes or ones with automated content management. Because many designers have websites that fall into this category or are looking to upgrading their website to a more automated system of maintenance, this step in the plan must be considered.

Many websites have specific technical requirements, as well as features that need to be customized. When we did Webitect’s redesign, we forgot to plan for some such features, leaving us with a much longer conversion process than expected. Our previous theme used WordPress features such as excerpts and custom fields to help manage the content on the front page. By not planning for this, the new theme did not have these features implemented, and we were forced to manually customize each post accordingly. Situations like this need to be taken into consideration with other websites and planned accordingly.

Backend in Redesign: When To Relaunch The Site and Best Practices

Giving specific examples is difficult because each website’s conditions are different. To aid the process, write down a list of special requirements that need to be implemented, so that the conversion to the new design is smooth and no features are forgotten. Taking the time to organize these specifics will save time down the road.

New and Updated Goals

A great redesign should account for how a website has developed since the last design was implemented. To correctly do so, one must analyze exactly how it has developed. What goals of the website have been achieved or expired, and what new goals need to be formulated?

If an new goal for the website is more user interactivity, a number of design elements could be implemented to achieve that result — in addition to all of the technical elements. Perhaps that means a better contact form, a more prominent “call to action” button or a more trustworthy design and color scheme to exude credibility.

With a redesign, we must start over, in a way, taking a fresh look at the website and where it needs to go. Below are a few resources on formulating and achieving your website goals.

It’s About What Visitors Want

During the planning stage, consider what the visitors actually want. Conduct a poll, ask people directly, and especially ask those who have never visited the website before (via forums, community websites, etc.) for their fresh eyes.

Aside from asking visitors directly, you must understand your target audience. Many people do this during the planning phase of the initial design, and probably a few times throughout the course of the website’s life. However, a thorough in-depth analysis needs to be done again, and the redesign should reflect the interests of its users. Even for a website with a small audience, such as a portfolio, what kind of client is it currently attracting, and what kind do you want it to attract? Both questions should be considered to push a website in the right direction.

This is also the time to address any accessibility issues that the old design may have had. Think not only about what users want, but about what they need. Would the redesign benefit from a dark or light background? Would it benefit from larger or resizable text? What about a fixed or fluid design?

Analytics in Redesign: When To Relaunch The Site and Best Practices

Optimizing

As a website evolves, so does its content and keywords and probably your business plan as a whole. A redesign requires a fresh look at optimization. What are people searching for to get to your website? Where are they coming from? Are they finding what they need?

Optimize keywords, content placement and other SEO-related elements. The redesign is a great time to overhaul the website’s optimization systematically, so that the new design enhances it, rather than gets in its way. It’s also a great time to plan for the website’s loading speed. If it was slow before, a good redesign would make it faster.

Redesign aside, this step will also help you better assess your current content and how it can be improved. Better content goes great with a new look.

Check out the resources below if you are unsure where to begin:

Review Competitors

After obtaining this preliminary information, it’s time to start thinking outside the box. A quick review of competitors’ websites can help. Needless to say, don’t copy them, but noting their strengths and deficits is a great way to build your own website.

What design features do these competitor websites use? What is their content like? And what do they highlight? You may want to use similar techniques in your redesign or draw new ideas based on what you’ve seen.

Draw a list of competitors and take proper notes in your research. It will help you better understand your own design style, where they’re lacking and even what their goals are.

Analyze the Current Design

Of course, we’ve been analyzing our current design all along in the steps above, but when you go through it again this time, note any minor details in the design and functionality that could be improved. Also write down random thoughts that you might build on later.

This is the brainstorming stage. After writing down as many ideas as possible, organize the list into actionable steps.

1. Updating Your Brand

Our notes are prepared and our research done, and we are now ready to begin the redesign. The first step in this phase is to examine our brand. Having prepared this much, we may find that our logo, color scheme, tag line and other elements need adjustment.

Upgradebrand in Redesign: When To Relaunch The Site and Best Practices

Of course, there is a difference between upgrading and re-doing a brand. Even upgrading a brand too much can do more harm than good. We’ll want to keep much of our brand the same (i.e. the general style, logo and message). But could we update it with any of the following?

  • The logo should stay the same for the most part, but could it use a glossy makeover? If it was made years ago, technology and trends have changed; so while it should remain recognizable, it might benefit from a polishing.
  • Examine your tag line, slogan or “elevator pitch.” Does it still match the purpose of the website today? Did it become outdated when you adjusted the goals of the website?
  • Each website has its own style (e.g. creative, modern, sleek), and some websites mix styles. The design is a part of your brand. Going from a Web 2.0 style to a grunge style obviously wouldn’t make for an effective redesign. Whatever style you decide on will have to be in sync with your branding?
  • Colors play a big role. You may want to cut down on or increase the colors, but your specific colors should stay the same. Perhaps you could introduce a complementary color, while still maintaining your others. Because color has such a big influence on mood and perception, the colors in the redesign should reflect your style and brand.

You’ll want to update your logo, too, including the overall look, the colors, and small details. Brainstorm on these elements, but always keep your updated brand in mind.

2. Wireframing

As designers, we know that wireframing ahead of time can yield better balance, alignment and visual hierarchy; and it is a great way to position everything early on without worrying about the details.

Site Map

At this stage, we can plan the site map. It may or may not be the same as before. As we continue in our steps, we begin to see that redesigning a website is not only about the design, but about usability, functionality and organization as well.

Sitemap in Redesign: When To Relaunch The Site and Best Practices

Begin with the home page, and work down through the primary navigation and on to secondary navigation. Various features will need to be added to certain pages (e.g. RSS link on the front page of the blog), so keep that in mind. Setting up a site map can aid in visualizing your content.

Without a site map, you can easily forget important content as you move to the wireframe, which would create problems down the road when you try to fit a certain element in somewhere.

The Wireframe Itself

Wireframing is definitely an art in itself, and it takes time and practice. It is one of the most important stages in the Web design process, so giving it due attention during the redesign is essential.

Wireframe in Redesign: When To Relaunch The Site and Best Practices

Working from your site map, create an initial wireframe that has everything you need. Then, improve upon a few of the ideas. Asking for second opinions on your wireframes can help as well. Ask your volunteers to point out the sections that stand out the most, the order in which they notice elements and the prominence of key features.

Because wireframing is a lot more involved than we can get into here, consult the list of resources below for assistance:

3. Main Design

Now that we’ve planned and just begun redesigning our brand, we can move on to the exciting part: the actual website. Most of us who have given up our attempts to redesign in the past probably started the process at this stage. We opened Photoshop, chose a pretty color and gave up shortly thereafter.

Now, though, we are much better prepared:

  1. We have researched.
  2. We have worked out our branding, colors and style.
  3. We have laid down a wireframe.

Wow! We’re pretty much done—that is, at least with the boring stuff. At this point, we don’t have to stop the flow of our creativity to worry about technical details or about whether we’re doing it right or need to start over. We have it all planned out, and the plan is solid.

The only things to keep in mind for this phase are what we’ve already gone over. If your research spanned a few days or weeks, review what you’ve prepared. Print out the wireframe and site map and keep them on hand for reference. Start putting everything in place, and then go from there: add the design elements, detailing, alignment, balancing. Make the plan a reality.

4. Development And Testing

Finally, we’ve come to development and testing. Code the design (or outsource it) and make it fully functional. Mind the technical back-end requirements, as well as accessibility issues.

This process is fairly straightforward and needs no further explanation. If you stick to your plan, everything should run smoothly.

Testing and Review

Because we have transferred old content into a new design, we may find errors after we’ve completed the last step. In fact, we likely will. Use a link-checker to double-check all links, and check some manually. Test for speed, and optimize further if necessary. Double-check for validation one more time, and fix any behind-the-scenes errors.

This is also your last chance to ask volunteers to review your working version. You may have overlooked some accessibility issues, forgotten essential content or let some confusing elements slip in. Even with the most detailed planning, mistakes happen, and catching them before you launch is critical.

Your final testing should be thorough. You wouldn’t want to scare off your regular visitors.

Conclusion

As creative types, we constantly feel the need to redesign and improve our Web presence. Often, though, our website is good enough already, and we have to recognize that. The first best practice, then, is to consciously decide whether a redesign is needed at all.

If we decide that a redesign is needed, then we need to follow certain steps to ensure successful results. Without adequate preparation and a thorough analysis, even the best designers wouldn’t be able redesign their website effectively. It takes more than a great designer; it takes determination and organization. With these two characteristics, anyone can carry out the perfect redesign.

Further Resources

You may also be interested in these additional resources:

(al)


© Kayla Knight for Smashing Magazine, 2009. | Permalink | 6 comments | Add to del.icio.us | Digg this | Stumble on StumbleUpon! | Tweet it! | Submit to Reddit | Forum Smashing Magazine
Post tags:

Tags: ,

Copyright © 2010 Answer My Query All rights reserved. Maintained by Orange Brains .