Have you ever thought, while using an application, that it should be doing this work for you? A great example is reload buttons, in particular the pull-down-to-reload UI on many mobile apps. Why should the user need to tell the app when to update its data? The app should know and automatically update its data the instant it changes.
The problem is programmers getting lazy. Programming is hard. Programming problems can be hard. And sometimes... Programmers just push the problem onto the user - they ask the user to press a reload button instead of automatically updating.
This mentality is ubiquitous. Apps everywhere expose the inner problems of the program that are irrelevant to the user. We programmers get lazy and let our undies hang out in public.
SOUP is about Quality
Laziness is not the only cause of SOUP. Real-world budget constraints and the need to get-to-market lead to cutting quality. Hard problems to solve in programming often get pushed off to the user with the conscious or unconscious justification that it's 'easy for the user to do.'
Presenting the user with an amazingly-well-designed app is the key to success, and yet it's easy for us to forget that and let 'real-world' pressures cause us to degrade the user's experience. This destroys the magic and results in a second-rate app that is much more likely to fail.
SOUP is about Culture and Normalization
The other major problem is culture. We become normalized to a certain kind of app working a certain way. We forget to stop and ask if there is a better way for the user to accomplish their task. I think spreadsheets are in this rut. Fundamentally they haven't changed since the original Visicalc. They are great for getting started, but once you have more than a few dozen cells with calculations, they become a bear to use.
Programming tools are always improving. Often something that was hard in the 1970s is now easy in the 2010s. However, many UIs are still written as-if we were using the tools of the '70s, '80s or '90s.
Conscious Programming
The term conscious-blah is used for many things these days: conscious-living, conscious-eating, conscious-parenting, etc. Open up google and type in 'conscious a' or any other letter of the alphabet and you'll see some similar terms show up.
I think all of these mean the same basic thing. We can't be conscious of everything all the time, but we can shine the light of consciousness on as many things as we can think of for a brief time each. It's about creating a practice of revising our assumptions, actions and thought processes periodically to make sure they still hold true. My life motto sums this up nicely: question everything.
I advocate for conscious-programming because there are many unfounded assumptions in programming - many artifacts which distract us from the essence of what we are trying to do. My post on Amazingly Great Design has some ideas on how to effectively focus on the essence of delivering value to users and cut through the jungle of artifacts.
The App Principle: A web page is an application. In order for web pages to remain relevant in an app-driven world, web-apps must be able to do anything native apps can.
CORS breaks this principle. It restricts the information a web-app can fetch from the internet, and even if you are allowed to fetch it, it sometimes restricts what you can do with that information. Native Apps can fetch anything from the internet and do anything with it.
CORS has other problems as well. It isn’t consistently implemented across browsers. Safari 9.x interprets HTMLImage.crossOrigin differently from other browsers. CORS setup is difficult to get right and therefor it’s easy to get it wrong and actually create exactly the vulnerabilities CORS is supposed to prevent. Last, CORS returns extremely opaque errors.
Why Does CORS Exist?
I’ve been trying to understand this question for a year. My best understanding is, before CORS, web-apps were even more restricted. CORS opens up cross-domain access while preventing hacks such as:
Badwebsite.com attempts to fetch your emails from gmail.com; if you are logged in with gmail.com, without cors, it could do this!
CORS “taint” - I just don’t know. Is this a way to appease copyright holders? It doesn’t really prevent anything since Native Apps aren’t restricted in this way. Further, all you have to do is set up a basic web-proxy server and your Web-App could do anything with any image on the web. I have not been able to determine any legitimate reason for the existence of 'taint.'
CORS is the Wrong Answer
Reason #1 above is the main reason for CORS. It is legitimate from a certain perspective. There is a potential vulnerability, but it is the wrong solution. The problem is when “badwebsite.com” attempts to contact “gmail.com” it gets to freely use your cookies authenticated with gmail.com. This is something Native-Apps cannot do, so why should a web-page get to do this? And yet IT CAN - without CORS restrictions. This is insane. It’s like logging into the Gmail Native App on your phone , and then switching to MyMalicousApp and allowing it to send requests to Gmail using your login information from the Gmail app.
Beyond CORS - Sandboxed Cookies
It is relatively easy to solve the CORS problem now that we have separated the essence from the artifacts. We just need a way to allow websites to make external requests without giving them access to all the client’s cookies. The answer is to treat each webpage as a separate, isolated application with its own, sandboxed set of cookies for all the other webpages it communicates with.
I propose we add an option to XMLHttpRequest called ‘useSandboxedCookies’. When true, any web-application for a given domain is now allowed to make any request to any url - just like any native app could. However, all cookies used in those requests are local to that web application. This is exactly how native-apps work.
Example:
Alice logs into Gmail.com directly.
Then she goes to MyWebsite.com, which attempts a GET from Gmail.com
The cookies in the GET request to gmail.com are empty - the GET originated in the sandboxed cookie-space of the MyWebsite.com app.
So, even though Alice is logged into Gmail.com in one tab, in the MyWebsite.com tab, requests to Gmail.com appear to be coming from a new session.
This solution doesn’t actually do anything you can’t already do with CORS. All you need to do is set up a proxy server (example: corsproxy), which returns all the right CORS headers, and any website can fetch data from anywhere on the net, taint-free. However, setting up a proxy is not generally an option because it is costly, inefficient and not library-friendly. We need a client-side solution like the one above.
We should do away with the Taint concept entirely. It doesn't achieve anything useful, but it creates a lot of developer pain. Therefor, Sandboxed-cookie-requests should never return tainted objects.
Safe, Cross-Web-App Communication
My useSandboxedCookies proposal above solves 99% of the CORS problem. Since it could be added to the HTML spec in addition to CORS, we could stop there. However, there is another use-case that my proposal prevents but CORS allows, however poorly.
There are legitimate reasons why MyGoodWebsite might want to access Gmail.com using Alice's logged in credentials, and Gmail.com may want to allow it. For example, Gmail.com may want to offer a ‘log in with Gmail’ feature to third-party web apps. My proposal above prevents this since the only client-side code allowed to access Alice's Gmail.com cookies is Gmail.com’s code itself.
We need a reliable way for two client-side apps to communicate with each other. To do this, we can add a relatively simple extension to the postMessage API: allow postMessage to post a message to a URL. When this happens, the browser fetches data from the specified URL to initialize a headless client-side javascript session. That session can then send and respond to postMessages with other client-side web apps.
In the example above, MyGoodWebsite could postMessage to gmail.com/api.js. Once the gmail app loads, it sends back a postMessage that it is ready. Then MyGoodWebsite can use Gmail’s custom API for authentication. The gmail.com/api.js app can then use the user’s already-authenticated gmail.com cookies to communicate with the gmail.com servers and authenticate the third-party app.
Recap
I've outlined two proposals which superscede CORS and solve its problems:
Sandboxed Cookies: allow a web-app to safely fetch data from anywhere on the web with a simple client-side flag set per request, without any painful 'tainting.' Tainting is depricated.
PostMessage to URL: Allow any web-app to start any other for the purpose of safe communication and safe use of authenticated cookie credentials.
I have wasted way too many hours on CORS over the past few years, and I'm sure I'm not the only one. These proposals are simple to use and implement. They would open the web up to the web itself, instead of just native apps.
Does anyone know how to get the attention of the HTML5 standards committee?
My best guess about the future is eventually we will all be “uploaded into the cloud.” (awkward, but it gets the meaning across)
It’s tempting to say we’ll all be living in a ‘simulation’ at that point. But, I think by that point we will select a new term.
When we say ‘simulation’ we mean something somehow inferior or an approximation to the ‘real thing.’ The problem with that notion is our perception of the ‘real world’ is always an inferior approximation of the real thing.
Therefor experience and perception are always a ‘simulation’ of the ‘real world.’
If we live in the cloud, and we experience a world that is generated for us by algorithms, as long as that experience is AT LEAST as accurate as our ‘real-world’ experiences were, then I don’t think it’s fair to call it a simulation anymore.
It’s something more. It is a ‘chosen reality.’ In some sense it will be inferior since the ‘real world’ will always be more complex and nuanced than our generated ones. But the difference will be beyond our ability to perceive it. Our chosen reality will be superior perceptually. It will be the reality we want, not the one forced on us.
What-You-See-Is-What-You-Get was always an awkward acronym. Say "wizzywig" and people just look at you strangely. There is an amusing anecdote about the origin of the acronym on Wikipedia. I hope it's true:
The phrase "what you see is what you get," from which the acronym derives, was a catchphrase popularized by Flip Wilson's drag persona Geraldine, first appearing in September 1969, then regularly in the early '70s on The Flip Wilson Show. The phrase was a statement demanding acceptance of Geraldine's entire personality and appearance. wikipedia
NINO - Natural-In, Natural-Out
The idea, though, is powerful. Being able to see what the output of your work looks like as you edit is a tremendous relief to the mental burden of creation. It was a hot idea in the '80s and '90s, but it is equally important, and often ignored, today in 2016.
The main problem with WYSIWYG is it is only half the equation. How we put information into an app is equally important as how we get information back out. Just as we shouldn't have to perform mental gymnastics trying to anticipate how our final output will look, we shouldn't have to wade through a bewildering array of options to get our ideas into the app.
The best interfaces are the ones that get out of the way. You know an app is well designed when you completely forget the interface and instead can dedicate 100% of your mental energy towards your creation. These interfaces tend to have two things in common.
They visually get out of the way. There is less screen clutter to distract you.
Their feature-set is restrained. They avoid presenting you with too many options. Instead, they are carefully designed to have the bare minimum essential tools you need to create great stuff.
Comparison: Paper by FiftyThree - a NINO App
As of version 3, Paper by FiftyThree extended its excellent sketching app with note taking features. They introduce a brilliant set of natural gestures for formatting your notes that required zero screen clutter.
Comparison: Microsoft OneNote - a very Un-NINO App
By contrast, consider OneNote. It has a bewildering array of features, buttons, icons, widgets and text. My note in the screenshot below has a short title and one line of text. It is oppressively dominated by the rest of the interface.
Exocranium
Our devices, phones, tablets, computers, watches and more and more becoming extensions of our mind and body. I once heard a description of smart-phones, particularly with notes and productivity apps, as our exocranium. These devices and apps are becoming our brain outside our brain. The better the app, the more natural an extension of our mind and body. The better the app, the more natural its inputs and outputs - the more NINO it is.
Given two solutions to a problem, the one with less code is usually better.
Plite of the Programmer
Our job as programmers is to deliver value to customers. We deliver value by identifying needs, translating them into requirements, and writing code to meet those requirements. The difficulty of the task is compounded by the fact that requirements are constantly, unpredictably changing. Even after we finally ship, the story isn’t over. Code is a living thing that must be maintained, usually well beyond anyone's expectations.
Over the lifetime of a product, we will edit code 10x more than we write code, and we will read code 10x more than we edit it. Each token we add to our code may be read over 100 times. Every token we save could save up to 100 token-thoughts and 10 future edits. The key to our productivity is writing less code.
Why Count Tokens?
Tokens are the smallest meaningful element in code. Tokens are a more objective measure of code size since lines can have any number of tokens. Measuring tokens also ignores white-space and comments. Last, measuring tokens doesn't penalize using clear names. ‘Occupations’ is just as good a name under the token metrics as ‘occus’ or other hard to understand abbreviations.
Don't abbreviate words. Saving keystrokes only saves writing the code. It doesn't save edits or reading. Abriviations make reading harder. Since reading code dominates our time, abbreviations are a losing proposition. Only use shortened words if the shortened version is used at least as commonly in speech.
Measuring tokens is a simple, effective metric that lets us make decisions quickly and get on with solving problems and delivering value.
Why ‘Write Less Code’?
It's a simple concept with depth. Amateurs and masters both can apply and learn from it. A more accurate metric might be refactorability. We spend most of our time refactoring code, not writing it. Refactorability is the code-quality metric. It can be broken down into code size, clarity, and structure. Of the three, size is the only one that can be objectively measured, and while clarity and structure are important, both are usually improved by reducing code size. Refactorability is not something a novice will understand. ‘Write less code’ is an excellent guiding principle for all programmers.
How to Write Less Code
All other good coding practices essentially reduce code size. Two of the most important, and most often violated coding practices for reducing code-size are DRY and ZEN.
Don't. Repeat. Yourself. Don't you dare repeat yourself ;). The most problematic artifacts I've seen, both from novice and expert programmers, is code repetition. The big problem with repetition is it compounds the complexity of refactoring. Not only do we have to fix two or more things instead of one, but we have to understand how they all interact. Plus it bloats the code-base making it hard to understand.
DRY is a subtle art. The first, obvious level is ‘don't copy-paste your code,’ but as we level-up, we start to realize anything gzip might compress potentially violates DRY. The ultimate measure is, as always, refactorability. How many code-points need to change for a common refactor? Is there a way to reduce repetition to reduce the complexity of refactorability?
ZEN
Build it with Zero Extra Nuts (more commonly known as YAGNI). Because it is impossible to
predict future requirements, adding anything to our code that isn't strictly necessary to meet current requirements is not only a waste of time now, but it will haunt us for at least 10x future edits and 100x future reads.
It is fun to add cool features, but the master knows the only thing that matters is delivering value to the customer.
Write Less Code - Formalized
My hypothesis, and my experience, comes down to this:
Given two different functions, modules or programs
that both meet or exceed the problem's requirements, both correctness and performance
the one with less tokens is always better
as long as it doesn't sacrifice clarity.
The Practice of Writing Less Code
As with everything in life, writing less code is a practice. There is no point where we will master it. There is always another layer of deeper understanding. We are always learning how to make our code DRYer and more ZEN. We must constantly be looking for ways to meet requirements with less code.
ZEN - Zero Extra Nuts. ZEN code is minimalist. It is relentlessly focused on solving exactly the requirements and nothing more. (3)
Write only what you need. It’s a profound concept. Engineers can’t help but overbuild things. For some reason this is inherent to being an engineer. In physical engineering, overbuilding is mostly an issue of up-front cost in terms of extra time and material. In software, there is also a substantial ongoing expense. The maintenance cost of code is related to its total size (1).
ZEN vs DRY
ZEN implicitly includes DRY (don't-repeat-yourself). Code repetition is one of the most pernicious forms of "Extra Nuts." Learn more about the subtleties of code repetition here.
ZEN and Frameworks
Minimizing the size of the code-base is an important goal. Using standard abstractions like functions and classes can reduce the total codebase size. This isn’t the same as building a framework.
What is a Framework?
A framework is a module. At their heart, modules are about encapsulation. Modules have an external interface and internal implementation. Better modules have simpler interfaces and more-isolated implementations. Frameworks are different from other modules because they are designed to be used across multiple applications. Frameworks must be the best possible modules. In order to work across multiple applications, a framework must have the simplest possible interface and the most isolated implementation. Frameworks should also have their own codebase and be packaged for easy reuse.
Why Do We Build Frameworks?
If ZEN were the only value, we would never build frameworks. By the time we’ve built a solution to the required specs, we ship. End of story. That’s what ZEN tells us to do. If we only followed ZEN, our applications would include operating systems, drivers, database, compilers and every other part of our dev and runtime stack. In other words, each new application would be enormous and have a fraction of the capabilities we enjoy today. I said above that the maintenance cost of code is relatedtoits total size. When we measure the size of code in an app we do not include frameworks. This is for good reason. The complexity a module adds to an app is proportional to its interface size and leakiness of its implementation. Frameworks are the best of modules. Their leakiness is minimal and their interface refined. A framework with millions of source-tokens may only add a few thousand tokens worth of complexity to a project using it.
Are In-house Frameworks Worthwhile?
Clearly using other people’s frameworks is a big win. You get 100x or more leverage in terms of complexity. You only have to maintain your application’s code base and you get all the framework’s capabilities for a very modest price. Building a framework in-house at first doesn’t seem like a good idea. The total code-size you have to maintain will increase when you take an application and factor it into an in-house framework plus the rest of the app. We talked about how application code-size is properly measured, but we haven’t talked about how that value relates to maintenance. Maintenance costs are proportional to complexity, and complexity’s relationship to code-size is non-linear. If you double the code-size, you will more than double its complexity (2). Realizing that code-complexity is non-linear in code-size reveals why it makes sense to write frameworks even if they only have one app using them. If the application’s code-size is N-tokens before we factor out the framework, and let's assume that we can cut the application code in half by factoring out the framework. There is always some overhead in writing a framework due to interface and abstraction code. We’ll assume that overhead is 10%. After the split, both the framework and app will have (1.1 * N/2) tokens, or (1.1 * N) total. For simplicity, our final assumption is a complexity-to-size factor of O(N2):
Complexity before split: N2
Complexity after split: 0.6 * N2
App: (1.1 * N/2)2
Framework: (1.1 * N/2)2
Total: 2 * (1.1 / 2)2 * N2
That’s a 40% savings! Granted, I made the favorable assumptions, but clearly it is possible to have large savings. Further, you don’t have to limit yourself to making just one framework. There are diminishing returns, but in my experience I've still found improvements with over 10 in-house frameworks. Once you have a good framework, it is possible to re-use it in other apps. Then the savings really start to compound. If we assume just two apps, using the example above, the complexity savings increase to 55%. You also get code-size savings as well - about 18%.
When to use 3rd Party Frameworks
Obviously you should use an existing framework, if one exists, instead of writing your own. Right? Well, when evaluating the merits of a 3rd-party framework, there are a lot of things to consider.
Let's start with technical aspects:
Does it do what you need it to do?
Does it meet your performance goals?
Is the source open?
Can you look at the source code? No matter how good the documentation is, there are always questions it doesn’t answer. If the source is open, you can get definitive answers. If not, you will be flying blind.
Is it OpenSource?
Can you contribute improvements back to the project?
How clear are the maintainers about what sort of contributions are acceptable?
Can you fork the project? This is only a last resort, but it is nice to have as an option. If you expect to fork early, you will be mostly maintaining your own, in-house framework. The problem with this is it is a codebase no-one in your organization knows well. Seriously consider writing your own in-house framework from the start.
How difficult will it be to switch frameworks later?
How much of your code will directly interact with the framework?
If you are picking a UI framework, most of your code will be tied to that framework. Changing frameworks later probably means rewriting the app from scratch.
If you are using an encryption framework, like, say, md5, only a line or two of your app will use it. Changing that framework later is usually trivial.
There are also important non-technical aspects to evaluate:
Momentum. Usually there are multiple options for the same type of framework. Eventually, some die out and some thrive. It’s a good idea to use a tool like Google-Trends to determine which projects are thriving and which are dieing. If a framework dies, you may need to fork it to maintain it, and then you are back to maintaining an in-house framework.
Direction. 3rd party frameworks evolve outside your control. It is important to not only assess the current technical merits of the framework, but also, where is the framework going? What values and goals does the controlling team have? What values and goals does their organization/funding have? If your use-case is not squarely in their target use-cases, seriously consider looking elsewhere.
When to Write an In-House Framework
There are two main questions to ask each time you consider building a framework:
Is it the best of modules?
Is the interface simple?
Will the implementation be well isolated and minimally leaky?
Is there a reasonable chance you’ll reuse the framework on other projects? ZEN argues you should be cautions making assumptions here, but if you think there is a > 90% chance you’ll reuse it even once, this can be a big factor.
If you haven’t written a line of code yet, should you even consider writing a framework yet? You should never write something unless you know for certain you will use it. Don’t build more than you immediately need for current requirements. In this, you should always follow ZEN. However, when looking at current requirements, it is reasonable to ask how you are going to meet them. As you do, you will be considering how to modularize your implementation. If you are doing an agile approach, this design work will happen in code as you go. If not, you may be doing some up-front design. Either way, there will be a point where you have modules. As soon as you start to form modules, you should start thinking about if the modules make sense as a frameworks. If the answer is “yes” to both questions above, then package up the module immediately, put it in its own code-base, and declare it a framework. The sooner you do it, the sooner you can reap the simplification rewards. Once you do, keep following ZEN. Continue to only add functionality as you need it.
Frameworks Clarify Thinking
Frameworks have another benefit beyond reducing complexity. Once you have isolated part of your code in a framework it takes on a life of its own. It has purpose beyond just serving the current app (though it should still be driven by that app's requirements ala ZEN). A framework begs for clarity in its purpose. By drawing a line between your app and your framework you have to start thinking clearly about what belongs where. Don't expect to nail the framework's "purpose" in the first pass. Your framework will evolve as ZEN drives it. Over time, though, clarity will emerge and you will have a new, powerful tool, codified in your framework, but also in your mental toolbox for solving and thinking about programming problems.
Writing Frameworks is Hard - and Worthwhile
I don't want to make this seem easy. Writing the best of all possible modules is hard! However, it is a learnable skill. You are only going to learn a skill be practicing it - a lot. And what about ZEN? Writing frameworks and ZEN are not in conflict. You can write frameworks while observing ZEN. After all, DHH, one of the strongest proponents of ZEN, wrote Ruby on Rails.
Footnotes
I measure codebase size in parse tokens rather than lines of code. Though still only an approximate measure, they are much better than LOC. They are the smallest meaningful unit in code. LOC measures several aspects of code which are ignored by the compiler including comments and whitespace.
Codebase complexity can be understood in terms of graph-theory. Complexity comes from the number of possible interactions within the code. In the worst case, if you have N bits of code (tokens), you can have as many as N * (N - 1) or roughly N2 possible interactions. In practice the relationship between code-size and code-complexity is somewhere between O(Nk>1) < CodeComplexity(N) < O(N2). Modular design is all about reducing the number of interactions a chunk of code has with the rest of the code-base. This is how modules help reduce complexity.
ZEN is roughly the same concept as YAGNI, but unlike the latter, both the word 'zen' and the expansion, 'zero extra nuts' convey meaning. We can say some code needs to be more 'zen,' and others will understand. To say code needs to be more 'yagni' holds no meaning for most people.
Originally, I created this content for a presentation. I then recorded a video, now on YouTube. This post is the third incarnation, the long-form blog. Please read on, or watch the 18 minute video if that's more to your liking.
Design Defined
de·sign (verb) \di-ˈzīn\
to plan something in your mind
Everything built or planned is designed. Putting forethought into something is designing. The difference isn't whether or not something is designed but rather how well designed it is — how much forethought was put into it.
All a watering can needs is a handle, a reservoir and a spout. Ikea manages to surprise and delight with this seemingly simple product. The proof is in the details. more with less — Start with the handle. It is tapered so people with different sized hands can find a comfortable grip. Next, notice how it supports pouring. Its long tapered spout makes it easy to pour precisely. It even excels at the simple task of holding water. Being a single plastic mold it is unlikely to ever spring a leak. The lightweight plastic ensures that even with a small amount of water and a tapered base it is not very tippy. The design also minimizes production costs. It allowing Ikea to sell it for an amazing 99 cents and as a bonus, they stack. emotional — Beyond function, it is beautiful. The lines are graceful. The shape is alluring. It makes you want to pick it up and feel it.
The goal of the Together iPad app from the World Wildlife Foundation is to increase awareness of endangered species and accept donations. The minimal requirements are a list of animals, their current status, and link to a donations webpage. Instead, they developed a deeply emotional experience. compelling first impression — The app starts with a light, playful soundtrack. The screen then folds into an oragami panda. The music chreshendoes as we pans to a whole pack of pandas and the app's welcome screen. Tap "start" and the soundtrack morphs to a softer, pleasent background piece. Up until this point everything has been in black and white. A three second shuffling-card-slideshow of full-color animals transitions you into the app's home-screen. beautiful, pervasive aesthetic — They brought a sense of elegance by integrating the origami theme. The theme is echoed at all levels of the app from the opening sequence to the sharing UI. Even the 3D globe appears to be made out of paper. The app's primary color palette is shades of grey. This makes the color portions of the app, such as the vividly colorful photos of the animals, stand out dramatically. strategic — Charities often fail to clearly communicate why we should care. They are often too pushy, full of doom and gloom and ladened with guilt. This amazingly well designed app has none of those shortcomings. The majority of the app is about praising the majesty of the animals. It is inspiring and uplifting. It is anything but pushy. To even see the donation screen, you have to "unlock" the last animal ensuring the user is deeply engaged before asking for money.
invisible engineering — The Jawbone JAMBOX is an engineering triumph. It packs
an amazing amount of sound in a tiny package, but it
doesn't stop there. The packaging hides the speakers,
and the box shape communicates a promise of
simplicity. It is designed to run totally wireless.
It has excellent battery life and uses bluetooth for
audio. It's built-in microphone allows it to be used
as a speakerphone. Though it targets wire-free use,
the inclusion of a 3.5mm jack supports older devices
and gives you an alternative when bluetooth doesn't
work perfectly. holistic excellence — This is a highly focused product. The goal is
wireless, high-quality sound, simplicity and style.
Individually these are goals any portable sound
system might target, together with Jambox's flawless
execution elevates the product to another level. It
invites everyone to take off their headphones and
share their music.
streamlined — The Balanced iPhone app by Jaidev Soin helps you track your daily goals with minimum distractions. Balance says completing your
goals can be hard, your goal tracking app shouldn't be. Setup is accelerated by providing a catalog of common tasks reducing the number of taps required by over 90%. Logging when you complete a task is a single swipe gesture. Minimizing the most common and critical path makes the app effortless to use. differentiated — Balance uses a unique set of fonts setting it apart from other apps, and the one fancy 3D transition manages to not be distracting and furthers its differentiation.
simple — The last example is the Nest thermostat. Targeting an
industry that has been stagnant for decades, they reduced the number of controls to one
dial. Even more amazing, the dial only does one
thing: it sets the desired temperature. The display
is minimal including only the current temperature,
the desired temperature, a visual of their delta
aligned with the dial and an estimate for how long
the temperature change will take. empathic — The elegance of the interface is a brilliant bit of
design, but the true genius of Nest is what happens
behind the scenes. It tracks every time you set the
temperature and automatically learns your daily
routine. It automatically programs itself and soon it
starts adjusting the temperature for you according to
your past preferences.
Extreme focus takes what used to be a heinously
painful task of programming your thermostat and
transforms it into an effortless and joyful interaction.
Amazingly Great Design Defined
a·maz·ing·ly great de·sign (noun) \əˈmeɪzɪŋl'ē grāt di-ˈzīn\
Design that exceeds expectations down to the last detail.
Three Pillars of Amazingly Great Design
Focus, details and tools are essential for amazingly great design. They can take a lifetime to master, but even a novice can make use of them immediately. With these basic ideas and a lifetime commitment to learning and improving their application, anyone can become a great designer.
First Pillar: Focus
"Focus is about saying no." - Steve Jobs
Time is your most valuable resource. Focus is the ultimate time management tool. Focus means learning how to use every moment of time for only the single most important thing you can do
with it. Say 'no' to everything else.
customer archetype
The first thing to focus on is your customer. Instead of describing the average or most common
customer, I recommend inventing a customer archetype. Your archetype describes a potentially real person.
An archetype is like an average person, but there is
difference. Your average customer may have 2.5
children. The archetype forces you to choose a real
mom with, say, exactly 2 children. With that choice, you can achieve amazingly great
design for moms with 2 children instead of merely
good design for moms of 2 or 3.
use-story archetype
When the customer interacts with your product you are
guiding them down a specific designed path. This path has a story. It has a beginning, middle and
end. In the beginning the customer has a task they want to
accomplish. They must decide to use your product and
take action to begin their journey. In the middle they are working on the task. This is
where they spend the most time with your product. By the end they have accomplished the task. They are
rewarded not only by the desired result, but also some
set of positive emotions. The very best stories have excellent beginnings,
middles and endings. They are just the right length.
You certainly don't want your story to be too long,
but you also don't want it to be too short. Write down the archetypical story for your product,
step by step, with storyboards. This is a single
linear path through time. Think of it as a movie
rather than an interactive product. Focus on this single story exclusively, and making it
the best possible story it can be.
singular focus
This singular focus on one customer and one story
ultimately leads to a better product. A highly focused product is easier to use. The
product itself can communicate to the customer what
it is for and how to use it. The product tells its
own story. Another benefit of a highly focused product involves
human perception. Our minds are tuned to notice
things that stand out. Doing one and only one thing
amazing is better than doing many things merely
"good." An amazing product will be cherished and
remembered. A merely good product will be quickly replaced
and forgotten, even if it does more.
time = features * quality
In the end, Focus is the key to solving this equation. The time required to complete a project is
proportional to the product's features and its
quality. All too often people assume the feature-list is a
hard requirement. If they have to meet a certain
deadline, then quality has to be sacrificed. This
decision always results in a mediocre product. Instead, if you want to make amazingly great
products, then quality must be fixed a maximum. To
meet a deadline, then, it is the feature list which
must be culled. As you practice this methodology of
extreme focus you'll find there are very few features
which are requirements. As Jobs said, focus is about saying "no." To produce
with maximum quality, keep saying "no" to features
until the list is so short every last one of them can
be implemented with excellence. The result will be a
far better product.
Second Pillar: Details
"The details are not the details. They make the design." - Charles Eemes
The question then becomes, what details matter? This is a
question which takes a lifetime to master. The first step
is to learn how to broaden your scope. To inspire you,
I'm going to cover four of the many types of details that
might be important to consider when designing your
product.
environment
Where is the
product used?
Is it loud or quiet, bright or dark?
Who is around?
What time of day will it be used?
product
Assuming the product is some sort of application or
website:
Are all elements aligned exactly?
Is there adequate white-space to make the viewer
comfortable?
What colors are used and are they used consistently?
Is the app perceived to be performant and immediately
responsive?
Do the animations reduce distractions or are they
themselves distracting?
Are the fonts legible? Do they invoke the right
emotional response?
How are errors handled?
customer archetype
What is their day like?
Who are the important figures in their life?
What social groups do they belong to?
What are their hopes and desires?
What will the person be thinking just before they use
the product? Just after?
Will they be thinking about
the product while not using it?
What do we want them to feel when they use the
product?
How will our customer want to be perceived while
using our product publicly?
lifecycle
How will the customer learn about the product?
Where will they first see it?
Where will they first "touch" it?
When is their first real engagement?
What is their daily engagement?
What is their last engagement?
How does the product reoccur in their thoughts after
their last engagement?
What details will help to reengage the user with this or other products?
Third Pillar: Tools
"Nothing is
original. Steal from anywhere that resonates with
inspiration or fuels your imagination. Devour old films,
new films, music, books, paintings, photographs, poems,
dreams, random conversations, architecture, bridges,
street signs, trees, clouds, bodies of water, light and
shadows. Select only things to steal from that speak
directly to your soul. If you do this, your work (and
theft) will be authentic. Authenticity is invaluable;
originality is non-existent. And don’t bother concealing
your thievery - celebrate it if you feel like it." - Jim
Jarmusch
The third and final pillar of great design is your idea toolbox. These are the tools and patterns you use to create the product and exceed expectations in the details. A designer's toolbox is constantly expanding and
evolving. The best designers make a continual effort to
improve it by all means available.
notebook
Keep a design notebook. As you start noticing good and bad design in the
world, start taking notes. This helps you clarify
your thinking on the design and gives you something
concrete to come back to when you need it.
opinion
Develop a well-considered opinion. In order to be a great designer you need to learn to
care deeply about great design. You need to be able
to not only distinguish between good and bad design,
but also articulate why it is so.
Be prepared to offend people. If you don't, then you
aren't pushing the envelope.
play
Constantly experiment with your tools. Free yourself
of the constraints of your real projects and allow
yourself to explore freely to discover great new
possibilities.
inspiration
Creativity is equal parts experimentation and
inspiration. You need to constantly feed your brain
new stimulus from the outside world.
This includes trying out competitors products, but it
also includes getting inspiration from completely
different fields.
Visit great works of art and architecture. Read
voraciously, explore nature, take classes, go to conferences, read blogs and listen to podcasts.
Designer's Amnesia
In addition to the three pillars, I have one important word of caution.
The processes of design and implementation unavoidably leads to the designer
memorizing the design. Any design, good or bad, can become "intuitive" to
anyone who memorizes it. One loses objectivity and empathy for new users the
more one uses a product, and it's worse if you are the designer.
Keep the following questions in mind:
Is your focus the right one?
Are there failures in details you can no longer see because you've memorized them?
Is there a tool that obviously solves a problem better but you can no longer see it?
Explaining what you are working on to someone new is
a good way to expose these shortcomings. It is even
better to give them a prototype and watch them use
it. Video the session and study it in detail for every little success and failure. Often you'll be slapping your forehead in minutes.
Impact of Amazingly Great Design
Many companies are committed to amazingly great design
including Apple, Herman Miller, Blizzard, Jawbone, 53 and
IKEA. Each of these companies have been successful largely
because of their great design.
business
perceived value — Repeatedly exceeding expectations dramatically
increases the customers perception of your product's
value. You can charge more, customers will seek you
out and you will stand out amongst the competition. brand — Great design creates good will towards your
brand. It is one of the most effective ways to show your customers you care about them. They will, in turn, begin to care about your brand and even
come to love it. actual value — Great design adds real,
tangible value for the customer. Historically design
has been considered window dressing - a frivolous
veneer on the product which may sell 10% more.
Thankfully, it is now clear that great design
dramatically increases the value for the customer, and here's why.
customer
time — Great design saves time. Just as time is
the designers ultimate resource, it's also our
customer's most important asset. All great design
takes the customer's time into account and gives them
the most bang-per-second. reduced stress - Great design reduces stress and fatigue.
Rough edges both literally and metaphorically wear us
down and suck our energy. A poorly design product may
get the job done, but we'll be emotionally and
physically exhausted after using it. Instead, an
amazingly designed product could actually energize, excite and slingshotting us to the next task of
the day. beauty and delight - Great design brings beauty and delight to our
lives. Great design goes beyond the veneer of frivolous
window dressing. Its beauty reaches deep
inside the product and impacts us on many levels.
It can inspire, sooth and bring joy. It
can even impact us when we are not using the product. These positive emotions impact the bottom line for
everyone. We are more productive under their
influence and happier in life.
Zen of Amazingly Great Design
Each of the three pillars of great design is a never ending path towards mastery. We are constantly inventing and discovering new tools. There is always the next layer of details to consider, and a good designer is constantly refining their ability to separate the important from the unnecessary. focus — Say "no" to everything but the most important features. Practice deep empathy with the customer to identify those essential features. Reduce the scope of the project until there is enough time to implement every aspect with excellence. Paradoxically, reducing a products features usually results in a better product. details — Train your mind to
be precise and attentive. Learn to see products
from every angle and see every minute flaw. Discovering what
details matter is equal parts science and experience gathered
over a lifetime. tools — As you progress you will learn thousands of tricks, patterns and
solutions you can employ to implement your design. Each time
you finish one design you'll have new and better ideas for
the next one.
Overall, the key to becoming an amazingly great designer is
to be aware of these pillars, follow your own passion and
keep an open mind. Insight can come from the strangest places.