Categories
development ux

Work hard to make things simple

Bowling Alley

“Any intelligent fool can make things bigger, more complex, and more violent. It takes a touch of genius — and a lot of courage to move in the opposite direction.” ERNST F. SCHUMACHER

It’s easy to write software. Ask users what they want (or even better, observe them and discover their problems), find a clean, user-friendly solution, build it and deliver it, for free, with no ads.

And you make a success of it, so you add more features to see off the competition, or to disrupt a new market. Google built Gmail, then added automatic categories, and Smart Replies to make it easier to process your messages. And they also added Wave, Buzz, Google+, Talk and others, to demonstrate other ways to connect and communicate, for places where email doesn’t work so well. So many new features, new things to learn, spinning out from that new core.

And yet Gmail remains popular, the rest, not so much.

It’s easy to add features. With a bit of work, you can even add them seamlessly without adding another menu option that your users will never see.

But what’s your plan to remove options, to streamline your code? How do add a new feature that’s easily discoverable and useful? How can you be smart and subtle?

What is your simplification strategy?

Advertisement
Categories
development

The frustration of confounding expectations

Icons on the microwave : heat water with a spoon in it. There is a glass of water without a spoon with a cross through it.
Spoons in the microwave

After years of being told no metal in microwave, it still feels too weird to follow the instructions on my new microwave to use a spoon when boiling water. There’s a sticker telling me I have to add a spoon when microwaving water but I don’t see myself ever doing that because the “no metal” is so ingrained, and I’ve seen plenty of lightning videos from people who have done it.

A lift control panel with a numeric keypad and the letter C in the display
Abstraction in lift design

This picture is from the lifts at the local hospital. You press a floor number (rather than up/down) and the display responds with a letter telling you which lift to catch. This additional abstraction confuses many users, as I discovered helping people use them as I was taking a coffee break.

I see the same thing on a lot of websites. Those “cool” websites that break scrolling by moving things sideways or zoom in as I scroll down. SPA sites that break the back button. Using outlook web access on a mobile browser is painful. I keep getting the “Are you sure you want to resend?” or the login prompt when I try to go back to my message list from an email.

I’ve never been a great visual web designer, I’m definitely a function-over-form type, but I’ve always started with the principles that came to be known as progressive enhancement. Make it work in the simplest way, and add the bells and whistles on top of a strong, accessible foundation. That foundation has shifted from HTML, to HTML+CSS+JS, to TSX in my latest projects, and from desktop to mobile throughout, but it is always based on the basic principles of text and forms : easy to read, easy to follow, and works the way you expect it to.

If you’re trying hard to stand out by breaking expectations, what are you trying to hide?

Categories
development ux

User Experience : A quick introduction for developers

The following is an internal summary I wrote for a team that no longer exists, summarising a number of references from UXScotland, various book and blog posts. It extends the thoughts from my Pecha Kucha talk. For more details, please refer to the links throughout and the references at the bottom. The context here is consulting and long-term B2B projects, but some of these discussions are more widely relevant.

User Experience : Project considerations

User experience is about making sure we are solving the right problems in the right way. It is the intersection of design, users, and context. Context here is a combination of one or more of the device in use, the user’s location, any social cues such as nearby friends, and anything else that may be available from sensors or historical information.

vennux

In many cases, the requirements we have are assumptions (e.g. what users want is Facebook integration). Where the benefits of a requirement are unclear, we should treat it as an assumption to be tested. Embrace data, and analyse it.

At the requirements stage, we need to make sure we are solving the right problem (pretotyping : “building the right *it*”), and that our chosen design helps the user to solve the problem without frustration (i.e. prototyping the design, rather than the implementation, with wireframes/sketches).

In user testing, particularly in an agile development, we can refine those ideas by seeing how well the implementation solves the problem, by testing with users. We can also test deployed code by analysing heat maps and http logs to see what users are doing to inform further tests and the assumptions that feed into further design cycles.

In a Lean/Agile project, we need to be explicit about our assumptions about the user and test them at every stage of the development to ensure that we always meet user needs.

cycleofux

How does UX fit in our process?

Stakeholders

A system that supports user’s need effectively will need to understand that the user is a Stakeholder in the process. Whilst the users themselves may not be directly involved in the generation or review of design artefacts, there should be a user representative, either a super-user on the customer side, or a 3rd party researcher who has determined user needs, and has authority to verify any proposed solution and high-level requirements against those needs.

Functional Requirements

Personas / Typical Users

A persona is an abstraction of a system user. In a simple system, there may be only one type of user, but more sophisticated systems will typically have users and administrators, and may have multiple classes of each. A persona is defined to encapsulate the types of tasks a specific user may wish to perform, and any limitations that may be imposed (for example, administrators may be able to install specific browsers or client software, but members of the public using the system must be supported across multiple browsers at multiple screen sizes).

User Journeys

Each persona will have one or more tasks they wish to perform in the system. A User Journey describes the tasks as a series of steps that a specific persona will follow in order to achieve that task.

Consider the tasks that a user wants to perform. See also BDD – design from user in.

E.g.

User wants to process a case:

  • User logs in to the system
  • User selects case from their task list
  • User reviews latest document
  • User finds agent for case, and calls to discuss
  • User adds comments to case
  • User saves case and returns to their task list

This process may identify a new use case (“Display task list”), and specific actions that need to be defined within a use case (“Display latest document” and “Display agent contact details”)

The User Journeys provide the context between the Stakeholders (and User Types therein) and the Use Cases. Each User Journey will link to one or more Use Cases, but some Use Cases may not have an associated User Journey (nightly payment processing, for example).

User feedback

If the solution is replacing or improving an existing system, the best source of information on the current system are the users. The requirements capture process should take into account both the tasks that the users perform and gather feedback on any areas of frustration. The prioritization exercise should consider these improvements as well as new functionality.

Testing

As well as testing the Use Cases for functional acceptance, the FAT/UAT process should also test that the final system supports the User Journeys defined up front.

On-going support

Where projects have regular support meetings, the input of users has been valuable in identifying problems areas and possible changes. When on-going service delivery contracts are defined, SDMs should consider whether ongoing user feedback is appropriate as part of the planning and scoping of releases within that framework.

Questions to ask

  • Have the requirements been tested on users? If not, why not? (Are these the right requirements?)
  • Will users be given the opportunity to provide feedback on these through the development? (And if so, how, when and where?)
  • What user outcomes are we trying to achieve with the release? These may not be requirements that we put a cost on, but an expectation that we can measure against to show improvement – we would need to communicate this appropriately.
    • E.g. minimise clicks to access the 5 main functions
    • E.g. reduce time-to-complete for function x, y and z by 10%
    • E.g. Align existing UI with iOS and Android norms
    • E.g. Increase usage of function z by 5%
    • E.g. 99% AAA compliance
  • Who represents users on the project team?
    • How many user types do we need?
    • Can normal users and administrators share UX, or are their goals divergent? – different apps, different ASP Areas, different branding, …
  • What platforms and form factors need to be supported/tested?
    • Does each platform need a native UX? If native app, probably yes, if web app, maybe.
    • If mobile, do we need to adapt to context : location/orientation/communication with nearby devices/…
    • If social, do we need to adapt to context : can I approve my own work?/who’s online/recommendations/who’s nearby/…
  • Do we, as developers, have any input to the UI design? If not, why not?
  • Have the designs been tested on users? If not, why not? (Does the UI fit user expectations?)
  • Do we have appropriate guidelines for the appropriate platform, and are they listed in the requirements and estimates?

Potentially useful resources

 

Categories
development

Sugar coated icebergs

Prototypes are great. They let the user see and feel what the final product will look like, either in printed or in online form.

They suck when the customer wants it next week because “it’s just a bit of wiring up to get it working”

And they can be dangerous. Ship that button without properly tested, or incomplete, code behind it and your software could crash and sink without trace.

If you want to always be finished, you need everything that the user can interact with to meet your quality standards. No unguarded exceptions, no raw data, no untested code. And if that means leaving that button out until it’s ready, do it. Or put in a bulletproof, well tested placeholder, like an email subscription to find your beta testers.

The user doesn’t know or care about all the mass under the surface that they can’t see, so don’t expose them to it. Keep the interface clean, simple and error free. Build up behind the scenes, behind feature toggles, and off production until you’re sure it’s safe.

The one thing worse than a missing feature is a horribly broken one. A user missing a feature may come back when the feature is ready. A user who’s experienced a broken feature won’t come back until they trust it.

Don’t lose your users’ trust.

Categories
code development programming

Your API sucks : foolish inconsistency

There are many ways that an API can be inconsistent. Different methods can follow different conventions, one method may have different results, or maybe a change introduces inconsistency between versions.

Spatial Inconsistency

When calling 2 different methods in what appear to be related domains require 2 very different calls and get 2 very different results.

GET /cat

{ Name : “Garfield” }

GET /food/index.php/fooditem/1

                    🍌

Random Inconsistency

When calling the same method multiple times can lead to a result with a significantly different format.

GET /cat

{ Name : “Garfield” }

GET /cat

{ Name : “Jatt” }

GET /cat

{ Name : “Lion-o” }

GET /cat

🍌

Temporal Inconsistency

When versioning an API breaks existing clients without warning. Speak to Seb Lambla if you want to do it without versioning, or Troy Hunt if you want to version it right, in all the wrong ways.

Today:

http://www.example.com/api/getAddress?postcode=EH28%208PL

Tomorrow:

HTTP POST
 http://www.example.com/api/getAddress
 X-www-form-urlencoded
  API-version: “v1.1”
  Search-type: “postcode-lookup”
  Input: “EH28 8PL”
Categories
ux

Smart is subtle

In the spirit of bad interface design, there’s an overall principle worth bearing in mind. For all your smartphones and smart cards, and smart things, I sometimes feel very dumb trying to work them. They make me think too much. I used to have a Honda Civic, and when I chose that, I also looked at a Hyundai and a Ford Focus Titanium. One of the things that stood out for me was that the Titanium was overloaded with flashing lights and dials, and the Hyundai had lots of buttons. The Civic was just a nice car to drive, with a dashboard that wasn’t distracting. There are lots of smarts in the car, from auto-stop, to a hill-start clutch, but most of the smarts are in the background. Not just hidden, but working behind the scenes so I don’t have to think about them.

Remove the flashy lights, and the buttons no-one presses,and the options that you can automate. And simplify the rest. Boot by hiding complexity but by managing it.

Categories
code development programming

Why can’t the IT industry deliver large, faultless projects quickly as in other industries?

Glasgow Tower
Glasgow Tower

The title and inspiration of this post is an old question on StackOverflow : Why can’t the IT industry deliver large, faultless projects quickly as in other industries? – Programmers

There is a continuing question of why IT consistently fails to deliver large projects, when other industries such as construction, civil engineering, and aircraft companies consistently deliver on time and to budget, and never have any problems in their first few years. Just ask anyone in Edinburgh about the trams.

However, there are a few things that make software projects more likely to fail, as I see it, throughout the process, and the successful methodologies recognise and address these problems directly.

The first key difference I see is best demonstrated looking at architecture vs IT. I’ve seen a few design competitions for key projects, and the bidding always involves paper or 3D-rendered models of the final structure, with lots of trees, and several people milling about, looking happy. It’s been very rare for me to see that in a software bid, and that’s probably a good thing. Aside from some rough sketches of UIs, what really matters is the relationship between the developers and the customer, because software changes dramatically according to use, especially after first use when the users start to see what’s possible rather than just talking about it.

The buildings we see are not version 1. Before the models in the bidding stage, there may be sketches, and after the models may come prototypes, scale models, physics simulations, walkthrough renderings, and many other versions iterating towards the final design that actually involves tonnes of steel and concrete driven into big holes in the ground.

Software is version 1, or maybe version 2. The design is executable, and malleable. Code can be used to simulate itself via test frameworks. Software is the best model for software, after all simulations such as paper prototypes are doomed to succeed, because they won’t have real world data with apostrophes in names, they won’t have anyone living in Llanfairpwllgwyngyllgogerychwyrndrobwllllantysiliogogogoch, and all network interactions will be instantaneous.

Every model and sketch built before a building is a level of abstraction that considers a subset of the details of the finished product. In software, everything is done at the same level of abstraction, the production code, the unit tests, the integration tests, the behaviour driven tests, the factory testing, are all done on the same business logic, and often in the same language, so the design is the product, and if the design is wrong, the product is wrong, and often the only way to test the design is to deliver the product. Users are not going to care about curly braces and angle brackets. They care that hitting that button does the right magic to send that email. If the design is wrong, then the magic is wrong, and the user is disappointed. So we iterate, we gather feedback, and we improve, step by step, polishing the magic until the experience shines.

And that’s what other industries do, whether we admit it to ourselves or not. Walls in buildings are knocked down, offices are reconfigured, and the Boeing and Airbus planes are improved in iterations. Carriers are offered new seat styles, and get offered stacking accommodation, flight navigation systems are removed and upgraded, and so on. Improvements are made around an expensively tested and maintained core, which improves at a slower pace, because the gap between design and implementation is large, and the feedback cycle is very long, although it’s getting better, at least for architects.

Is software uniquely complex? Are software projects too large? No. But the nature of software puts us in a much tighter feedback cycle between design and code. That’s what the agile manifesto cuts to at its core. We want to test our designs, but the best way to do that is to implement them and get them in front of users, and then refine them. Upfront design doesn’t work because users understand products, not requirements.

Software can deliver large, faultless projects, but it’s much easier to deliver many smaller, faultless iterations, and take more risks whilst you’re doing so, because losing 1 weeks’ work is a lot less painful that losing a year’s work.

Categories
code data development programming security

Personal Identity in a digital world

In the light of more data breaches, especially highly personal data of the form held by a certain affair website, I wanted to revisit the 4th Rule of network security. If you don’t trust encryption, you store as little as possible which implies YAGNI for data storage. There’s a few other benefits you get as well, in simplifying your storage. In this post I want to focus on the simplest and most obvious personal identifier, your name. And I’ll assume you’ve all read Falsehoods Developers Believe About Names, so if you haven’t yet, read it now.

What’s in a name, or a person?

At its basic level, a name is a poor identifier. Going by Google and some misplaced emails, I know of at least 3 other people in Scotland, 1 in Australia and 2 in USA who share my name. So my name is not sufficient to uniquely identify me, which is why I have a number of tracking references for the NHS, National Insurance (for Americans, think Social Security Number), my employer and others, and why it’s hard to get my name on social networks or email providers unless I get in early.

Do you need to know anyone at all? Is a tracking id enough?

Given that your name is not sufficient to uniquely identify you (and therefore is also harder to verify), is it even necessary? For many sites, and apps, not even a login is necessary or desirable to users, so advertisers, content providers and others often just use a tracking cookie or similar to identify you again the next time they see you.

If they need a login is a username and password enough?

OK, but your software needs to verify users and store data about them. You’ve got a good authorisation and authentication story to allow users access to their own stuff and no one else’s, without permission.

Do you still need their name? If you are a music site tracking my favourite videos, why do you care who I am? And if you’re built on a shoestring budget, why would you want the hassle of securing password when you can grab an OAuth library and not have to worry about it at all. Some of them will give you a name, some won’t. What purpose does storing a name, real or otherwise, serve?

Do you actually need to split names into first and last?

OK, so you actually need someone’s name, how are you going to store it? A name, a first and last name, middle names? If you are splitting a name and then littering your code (or at least your CPU time, if you’re resharing code) with contractions to display those names, then you may be doing it wrong. And who’s to say that all your users have a first and a last name? (see common misconceptions about names)

What about titles?

So you need a name, and you are sure you can split it. What else do you need? Do you need a title? Does it matter if your drop-down asks for Mr or Mrs or Miss? And by the way, what about Ms and Dr, and Prof, and can you handle Mx now, or do you discriminate? And by the way, how easy is it for the user to change those fields, as required by law?

What other details are you doing that you don’t need? Addresses? Country? Phone number? Email address? Credit Card number? Mother’s maiden name? Name of first pet?

Why does free train WiFi need my gender and age?

Or any website? And Why are those fields mandatory?

As a user, what is my motivation for giving you those details? The more information I give you, the more I have to trust you. And if I don’t trust you, you don’t get my data. If I know why you need it, there’s more chance of you getting my data. If I don’t know why you need it, I will assume you’re selling it, and I may think that even if I know why you need it.

Don’t ask me to trust you, and you won’t be disappointed.

What are you storing because you can, rather than because you need to?

Is your data a security risk, a performance risk, a trust risk? Or can you justify everything, and point to the requirement that details that justification?

If you lost your data to hackers, what would your users be most concerned about being disclosed? Can you stop storing that data?

Categories
code programming quickfix

I don’t trust change

Everything changes
Everything changes

I don’t trust change. I know change is what we do, it’s why people need new software to do things they couldn’t do before, to sweep away the cobwebs and start everything anew. To change. For the better.

The better what? Faster, more efficient, more user friendly. “Just better”. “An improvement”. “The new shiny”. “Make it cool”.

Great, can you write me a requirement for that, or some acceptance criteria?

“We’ll know it when we see it.”

But how will we know?

“It doesn’t matter. We’ll know.”

And when you come back and say it doesn’t have enough “zing” or “pizazz” or isn’t “cool” or “new” enough?

“Well then, it shows you didn’t listen to us.”

A change for the better?

If you want to change, you should know why. What will the users notice? What pain will it take away? What will it allow you to do that you couldn’t do before?

Those are questions I can pick away at, questions with an answer where I can measure something tangible. I can change the time it takes to do something, I can change a system to do something new, and I can show you exactly what the change looks like.

A change without a diff is a break.

If you don’t know why you’re making a change, the chances are, you’re making the wrong change, and you won’t know when the change is done. Make a small improvement, or a big one, but know why. If you can’t articulate the difference between the present reality and the desired future, all I can tell you is that the change will break. It might be beneficial, it might not, but there will be no way to trace from now to the future, and no way to know if anything has improved.

The best change may be no change

We love writing software, coming up with new ideas, new approaches. We want the new shiny. But that doesn’t mean it will do us, or our customers, any good. Angular.js makes it much easier to write web apps a certain way, but is that the type of web app that most suits your customer, and do they really need a web app at all? Is a web page easier for them?

And maybe what needs to change isn’t the software. Maybe there is a process that people have forgotten that will fix the problems, maybe they’re solving the wrong problem.

Software isn’t always the answer, and neither is change.

When to embrace change.

Change when things cause you pain. Subversion makes branching and merging painful. If that’s a problem for you, try git or mercurial. Manipulating the DOM from a callback is painful. If that’s a problem for you, try Angular or another framework. If they’re not causing you pain, chances are something else is, go change that first.

Change when there’s a functionality gap. When you’re chasing a new regulations, new APIs, new competitors, or new customers. And make sure that functionality does something to help close that gap. You might have a few ideas, so pretotype and prototype them first, make the change as small as possible, and build on it, because a small change is easier to throw away, physically and psychologically.

Embrace change.

But don’t trust it, until you know where you want the change to take you, and you have a way to check you’re on the right path.

Categories
code development programming

QConLondon 2011 : Day 2 review

So, on to day 2 of the QCon London 2001 conference, which for me was about testing, REST, and catching up with the .Net usergroup arguing with Glenn Block in a noisy pub over where hyperlinks should go and how horrible the browser is for a web-connected world.

Keynote : Innovation at Google / Patrick Copeland

In a fascinating overview of creating an innovation culture, Patrick Copeland discussed how everyone at Google is free to develop ideas (the famous 20% time) but that ideas mean nothing without data to back them up. In one case, the usage data led Google to kill Google Wave, which was a good idea, and got a lot of early interest but had no staying power as it struggled to find a killer niche.

The most interesting part of the talk was the discussion of “Pretotypes”, which are a generalisation of something I’ve always known as “Wizard of Oz” trials. The idea of a Pretotype (“pretend-o-type”) is to build a concept prior to the prototype to see if the idea itself stands up. Where a prototype answers “Can I build it?”, the pretotype answers “Should I build it?”

The best pretotype example in the talk was the discussion of IBM’s speech recognition trials. Before they started work on the software, they trialled the system by hooking up a microphone to a typist in another room, who would take dictation in real time for the user to see. They discovered fairly quickly that the interface was poor and canned the project.

I’m also very interested in the new Android Pretotyping app that was announced, called Androgen. It’s designed to help pretotype Android apps, but given the breadth of examples in the talk, I am sure it could apply equally to mobile web and possibly other devices. Definitely one to watch.

Testing for the unexpected / Ulf Wiger

For the first session of the day, Ulf Wiger discussed randomised testing, describing existing test automation as a low water mark, filled with often hard-to-maintain code where the effort to maintain the code grows faster than the complexity of the underlying system. The description of the problems with existing tests took up a fair amount of introduction time before the Erlang QuickCheck meat came in.

The idea of QuickCheck is to add controlled randomness to tests, by defining the input-output space of the system under test, which the framework uses to generate the test cases to try and find weak points in the system. QuickCheck is suitable for TDD – and he described how the requirements team could easily translate grammar in the requirements spec into QuickCheck test suites, which could be run over the code until no failing cases were found. He also mentioned that there were fewer errors in the test cycle than before the introduction of QuickCheck.

The most fascinating part of the talk for me though was the mention of NModel, which is Microsoft’s implementation of the same concept on the .Net platform. One to investigate.

Building a ReSTful architecture on .net with OpenRasta / Seb Lambla & Make yourself comfortable and REST with .NET / Glenn Block

I’m going to take the next two talks, from Seb Lambla and Glenn Block, together as they demonstrate an Alt.Net and a Microsoft solution to bringing a REST framework to the .Net platform. The Microsoft REST solution, built on WCF, provides a large number of integration points allowing users to mould the framework to their thinking whereas OpenRasta is built on the idea of strongly encouraging developers to do things “the right way” by enforcing a set of defaults that play nicely with the spec and are harder to change. OpenRasta has plenty of extension points too, providing support for multiple view engines, input handlers and HTTP PATCH, but the core is set (a point that I was reminded of during the WebMachine talk on Friday).

Two very useful points from both talks : they were both using Fiddler for demonstrations, and pointed out a way round Windows’ networking shortcut that usually prevents packet sniffing on the local loop. Using “localhost.” or “127.0.0.1.” (note the trailing dot) allows Fiddler to listen in on the local loop packets. I’ll have to see how Fiddler compares to my current tool of choice : WireShark. The other interesting point, that spilled out into the OpenSpaceBeers, was the concept of encoding links in HTTP. Are links to states (the canonical “purchase” link that should be followed after getting an order, for example) part of the HTTP description, and therefore encoded in Link headers, or are they part of the data, and encoded in the response content?

The biggest problem with ReST over HTTP appears to be that the most well known HTTP client, the browser, is a poor HTTP citizen. This doesn’t surprise me, given that browsers also tend to be 3rd class citizens of other protocols such as FTP, Gopher and IRC. Indeed, perhaps they should be called renderers, since they are generally better hosts of HTML, CSS and JavaScript content. Don’t let browsers fool you into thinking that you know HTTP. If you want to know HTTP, read the thesis that gave birth to ReST.

If you want a good ReST client however, .Net does offer some hope, as demonstrated by Glenn Block. The HTTP response and request that have always been part of the server side are now freed to be available for web clients, outside the IIS framework, so that you can now write happy C# web clients using ReST, using the classes you know from the server, but inside a framework that makes them easy to mock.

All in all, a very fascinating pair of talks on the mechanics of implementing a ReST service, which was a perfect setup for a talk about the practice and theory of implementing one…

Getting Things Done with REST / Ian Robinson

For the whole of the ReST track, a stack of REST in Practice books were available for people who gave the best answers. I’m sure having Ian Robinson, one of the authors, in the track, was a factor, and on the strength of his talk, it’s definitely on my post-QCon reading list.

The talk was a worked example of the now-standard GET a cup of coffee RestBucks workflow, but started with the idea that REST is just the latest incarnation of “Warlock of Firetop Mountain” Fighting Fantasy workflows. Read some data, get a list of options, follow a link to perform one of the options.

The talk showed a well-structured set of code that implmented the state machine using XForms as the POST representation of data, and therefore embedding links into the content. The emphasis was on discovery of workflow (after all, when I create a new order, I don’t know in advance what its ID will be, and I won’t know what the options are if I have a loyalty card).

The talk was a great sales pitch for ReST, but don’t take my word for it, read the InfoQ GET a cup of coffee article yourself.

Scaling the Social Graph: Infrastructure at Facebook / Jason Sobel

The scary takaway message from Jason Sobel’s talk was not the 150-200 engineers supporting 500m users. It wasn’t the pushing live several times a day, using flags to keep “in progress” features from being visible live, or the hoops they have to go through to have 2 (soon to be three) data centers in sync (hint – most user operations are read-only). The message that a lot of people went away with was that the front-end is PHP, compiled to a monolithic binary via C++ using HipHop, that weighs in at a single 1.6Gb executable running on every front-end server. Between that, the spaghetti code on the backend that had to be replaced and the use of multiple MySql databases on a single physical server (to make migration easier), I suddenly find myself thinking our legacy code maybe isn’t that bad.

OpenSpaceBeers

A great session from the local .Net group where two on-the-spot discussions were voted on. One was about AppHarbour (Heroku for .Net) that allows you to easily test and deploy your code to a cloud hosting solution, as well as a hush-hush competitor that’s coming soon with VPN support so you can host the database in your own data center (handy for certain organisations that have a stricter limit on data via the Data Protection Act).

The second talk was basically an extension of the ReST track, where Glenn Block did more to convince everyone that Hypermedia is the future and everyone should use ReST (which is fantastic to hear from inside Microsoft, and Glenn did thank Scott Guthrie for helping to foster Microsoft’s new partnership with the development community).

The session worked well, and if we could guarantee enough people, definitely something I’d like to try in Scotland.