[Dev Rule] 11 Rules All Programmers Should Live By

I am a person who tends to live by rules.

Now granted, they are mostly rules I set for myself—but they are still rules.

I find that creating rules for myself helps me to function better, because I pre-decide things ahead of time instead of making all kinds of decisions on the fly.

Should I go to the gym this morning?

Well, my rule says that on Wednesdays I go to the gym and today is Wednesday, so I am going to the gym—that settles it.

This week, as I was thinking about some of the kinds of rules I impose on myself, I thought it might be a good idea to come up with a set of rules that I think all software developers should live by.

Now, I’ll admit, most of these rules are more of guidelines, but anyway, here they are:

1: Technology is how you get to the solution, it is not THE solution

We can get really carried away with the latest JavaScript framework—ahem, Angular—IoC container, programming language or even operating system, but all of these things are not actually solutions to the problems we are trying to solve as programmers, instead they are simply tools that help us solve the problems.

We have to be very careful not to get too crazy about a particular technology that we happen to like or that happens to be oh so popular right now, lest we run the risk of thinking about every problem as a nail, just because we happen to be holding a shiny hammer we just learned about.

2: Clever is the enemy of clear

When writing code, we should strive to write code that is clear and easy to understand.

Code that clearly communicates its purpose is much more valuable than code that is obscure—no matter how clever it may be.

It’s not always true, but in general, clever is the enemy of clear.

It’s usually true that when we write code that is “clever,” that code isn’t particularly clear.

It’s important to remember this rule whenever we think we are doing something particularly clever.

Sometimes we write clever code that is also clear, but usually that is not the case.

If you’re interested in writing clean code I highly recommend you check out The Clean Coder: A Code of Conduct for Professional Programmers (Robert C. Martin)


3: Only write code if you absolutely have to

This one might seem a little contradictory, after all, isn’t our job as programmers to write code?

Well, yes and no.

Our jobs may involve writing code, but we should still strive to write as little of it as possible to solve the problem we are trying to solve.

This doesn’t mean we should make our code as compact as possible and name all our variables using single letters of the alphabet. What it does mean is that we should try to only write code that is actually necessary to implement the functionality that is required.

Often it is tempting to add all kinds of cool features to our code or to make our code “robust” and “flexible” so that it can handle all different kinds of situations. But, more often than not, when we try to guess about what features would be useful or we try to pave the road to solve for problems that we think might exist in the future, we are wrong.

This extra code may not add any value, but it can still do a lot of harm. The more code there is, the more chances for bugs and the more code that has to be maintained over time.

Good software engineers don’t write code unless it’s absolutely necessary.

Great software engineers delete as much code as possible.

4: Comments are mostly evil

I’m not a big fan of writing comments in code. I’m with Bob Martin, when he says:

“Every time you write a comment, you should grimace and feel the failure of your ability of expression.”

Clean Code: A Handbook of Agile Software Craftmanship

This doesn’t mean that you should never write comments, but for the most part they can be avoided and instead you can focus on doing a better job of naming things.

Comments should only really be written when it’s not possible to clearly communicate the intent of a variable or method by using a name. The comment then serves an actual purpose that could not be easily expressed in the code.

For example, a comment could tell you that this strange order in which some operation was occurring in the code was not a mistake, but was intentional because of a bug in the underlying operating system.

In general though, comments are not only evil because in many cases they are necessary, but also because they lie.

Comments don’t tend to get updated with the rest of the code and this results in the comments actually becoming dangerous, because they very well could steer you in a completely wrong direction.

Do you check every single comment against the code to make sure the code is actually doing what the comment says? If so, what is the point of having the comment? If not, how can you trust that the comment is telling you the truth?

It’s a pickle, so it’s best to avoid it as much as possible.

Ok, haters, go ahead and leave your torrent of “comments” in the comment section below, but I’m not changing my stance on this one.

5: Always know what your code is supposed to do before you start writing it

It seems obvious, but it isn’t.

How many times have you sat down to write code without fully understanding what the code you were writing was actually supposed to do?

I’ve done it more times than I’d like to admit, so this is a rule that I need to read often.

Practicing test driven development (TDD) can help here, because you literally have to know what the code is going to do before you write it, but it still doesn’t stop you from creating the wrong thing, so it’s still important to make sure you absolutely, 100% understand the requirements of the feature or functionality you are building before you build it.

6: Test your sh—code before you ship it

Don’t just toss your code over the wall and have QA pound on it only to send it back to you so that you can waste a bunch of everyone’s time with unnecessary bug reports and resolutions.

Instead, take a few minutes to run through the test scenarios yourself, before you call your code done.

Sure, you won’t catch every bug before you pass your work on to QA, but you’ll at least catch some of the stupid and embarrassing mistakes that we all make from time-to-time.

Too many software developers think that it is only QA’s job to test their stuff. It’s simply not true. Quality is everyone’s responsibility.

Stack of open books

 7: Learn something new every day

If you didn’t learn something new today, you just made backwards progress, because I can guarantee you forgot something.

It doesn’t take a lot of time to learn something new each and every day.

Try spending just 15 minutes or so reading a book—I read a whole lot of books last year, just reading about 45 minutes each day on average.

The little advances you make each and every day add up over time and will greatly shape your future. But, you have to start investing now if you want to reap the rewards later.

Besides, today technology is changing so rapidly that if you aren’t continually improving your skills and learning new ones, you are going to be left behind very quickly.

8: Writing code is fun

That’s right. You probably didn’t get into this profession just because it pays well.

I mean, there is nothing wrong with picking a job that pays well, but doctor or lawyer would have probably been a better choice.

Most likely you became a software developer, because you love writing code. So, don’t forget that you are doing what you love.

Writing code is a lot of fun. I wish I could write more code.

I’m usually too busy keeping this business going to spend much time writing code these days, which is one of the reasons why I so clearly remember how much fun it is.

Perhaps you forgot that writing code is fun. Perhaps it’s time to remember how much fun it is again, by starting a side project or just changing your mindset and realizing that you get to write code and you are even paid for it. (Hopefully)

9: You can’t know it all

As much as you learn, there is still going to be a lot you don’t know.

It’s important to realize this because you can drive yourself nuts trying to know everything.

It’s OK to not have all the answers.

It’s OK to ask for help or to speak up when you don’t understand something.

In many cases, you can learn what you need to know pretty darn close to when you need to know it—believe me, I do it all the time.

My point is, don’t get caught up in trying to learn it all, when that is an impossible task. Instead, focus on learning what you need to know and building the skills that enable you to learn things quickly.

10: Best practices are context dependent

Is test-driven development, the best way to write code?

Should we always pair program?

Are you a scrub if you don’t use IoC containers?

The answer to all of these questions is “it depends.”

It depends on the context.

People will try to shove best practices down your throat and they’ll try to tell you that they always apply—that you should always do this or that—but, it’s simply not true.

I follow a lot of best practices when I am writing code, but I also conditionally don’t follow them as well.

Principles are timeless, best practices will always be situational.

11: Always strive to simplify

All problems can be broken down.

The most elegant solutions are often the most simple ones.

But, simplicity doesn’t come easy. It takes work to make things simple.

The purpose of this blog is to take some of the complexities of software development, and life in general, and make them simple.

Believe me, this isn’t an easy task.

Any fool can create a complex solution to a problem. It takes extra effort and care to refine a solution to make it simple, but still correct.

Take the time. Put forth the effort. Strive for simplicity.

[Dev Rule] C# .net Exception Handling Best Practice

Step 1 – Don’t throw or catch the wrong exceptions

First off, don’t do any of the following things.  Ever. (Almost):

  • Don’t catch “Exception” – If you do this, and you end up catching something really dirty, like an OutOfMemoryException, then your app will muddle on just making your data worse and worse, and shock horror, if crappy data gets in your DB then you’re screwed.
  • Don’t catch “ApplicationException” – This one was originally something you could do, now someone in MS has created exception types that inherit from ApplicationException which are not safe to catch, so this one’s a no-no too.  (Seehttp://blogs.msdn.com/b/kcwalina/archive/2006/06/23/644822.aspx for more on this, or read this pretty darn useful book).
  • Don’t throw “Exception” or “ApplicationException” – If it’s not safe to catch these errors, then it stands you reason you really shouldn’t be throwing them.
  • What you should throw – With regards to what you should throw, I’m still undecided if custom exceptions are a good thing, or if you should as much as possible use the standard .Net exception types, e.g. NullReferenceException, ArgumentException, OperationException, etc.  I might post more on this as our best-practice resources at work start to flesh out.

Incidentally, there is one exception to rule 1 above – your application root should have always catch Exception, so that things that are fatal, no matter what they are, you can try to log and/or alert them in a standard way, and try to let the user down gently.

Step 2 – Don’t catch exceptions unless you can do 1 of the 3 following things

Do not catch exceptions in your code unless you can do one of the following three good things:

  1. You can added more detail – This would be done by catching a specific exception type, then wrapping it in a more meaningful exception to make your root exception handler log something more meaningful.  I cannot emphasis this bit enough, WRAP the exception!  If you don’t use the InnerException property on your newly thrown exception, you’ll lose the more detailed stack trace.
  2. You can fix the problem – This generally applies if you’re dealing with user input, and you can alert the user they’ve thrown in junk, try again.  Or perhaps a service is down and you have a fallback service, which indicates it’s really not exceptional that this particular service it’s down.  If you can fix the problem, then by all means catch the exception and clean things up.
  3. You’re the application root – The application root should always catch every exception that bubbles that far up the stack trace, simply to make sure it’s logged correctly.

I would say, regardless of where you catch exceptions, don’t be shy about using finally blocks for resource management wherever you might need them, they have no impact on the above.

Step 3 – The magic bit (that sadly is the hardest bit)

If you’ve ever tried to adhere to rule 1 above, you’ll probably have realised one key problem – if you never catch “Exception” or “ApplicationException”, how do you know what else to catch?  Do you ever find yourself writing code and thinking, “If this blows up, so what – we’ve still got to carry on and complete this other massively important job”?

Let’s take a typical scenario – you’re writing some code to validate postcodes in a shopping cart, to save the user keying in their full address.  If you get an exception in this logic, and you don’t catch it, the whole page will blow up and you’ve probably lost a customer.  But if you just catch “Exception” and your server’s getting resource issues, you run the risk of the customer thinking you’re going to fulfil their order,when you might have not even received it.  To do this job properly, the magic piece, you need to know where your or someone else’s code throws which specific exceptions.

This is actually quite a fundamental thing – some languages, for example Java, won’t let you throw an exception unless your method signature includes the exception in a special “throws” clause. Therefore, when consuming a method, you can easily see which exceptions it throws. This is an idea called “Checked Exceptions”.  The C# guys however decided that checked exceptions brought in their own issues (see http://www.artima.com/intv/handcuffs.html for more on this), so we don’t currently have this in the C# world.

[Dev Tip] SignalR Scaleout with Redis

In this tutorial, you will use Redis to distribute messages across a SignalR application that is deployed on two separate IIS instances.

Redis is an in-memory key-value store. It also supports a messaging system with a publish/subscribe model. The SignalR Redis backplane uses the pub/sub feature to forward messages to other servers.

For this tutorial, you will use three servers:

  • Two servers running Windows, which you will use to deploy a SignalR application.
  • One server running Linux, which you will use to run Redis. For the screenshots in this tutorial, I used Ubuntu 12.04 TLS.

If you don’t have three physical servers to use, you can create VMs on Hyper-V. Another option is to create VMs on Windows Azure.

Although this tutorial uses the official Redis implementation, there is also a Windows port of Redis from MSOpenTech. Setup and configuration are different, but otherwise the steps are the same.


Before we get to the detailed tutorial, here is a quick overview of what you will do.

  1. Install Redis and start the Redis server.
  2. Add these NuGet packages to your application:
  3. Create a SignalR application.
  4. Add the following code to Startup.cs to configure the backplane:
public class Startup
        public void Configuration(IAppBuilder app)
            // Any connection or hub wire up and configuration should go here
            GlobalHost.DependencyResolver.UseRedis("server", port, "password", "AppName");

Ubuntu on Hyper-V

Using Windows Hyper-V, you can easily create an Ubuntu VM on Windows Server.

Download the Ubuntu ISO from http://www.ubuntu.com.

In Hyper-V, add a new VM. In the Connect Virtual Hard Disk step, select Create a virtual hard disk.

In the Installation Options step, select Image file (.iso), click Browse, and browse to the Ubuntu installation ISO.

Install Redis

Follow the steps at http://redis.io/download to download and build Redis.

wget http://redis.googlecode.com/files/redis-2.6.12.tar.gz
tar xzf redis-2.6.12.tar.gz
cd redis-2.6.12

This builds the Redis binaries in the src directory.

By default, Redis does not require a password. To set a password, edit the redis.conf file, which is located in the root directory of the source code. (Make a backup copy of the file before you edit it!) Add the following directive toredis.conf:

requirepass YourStrongPassword1234

Now start the Redis server:

src/redis-server redis.conf

Open port 6379, which is the default port that Redis listens on. (You can change the port number in the configuration file.)

Create the SignalR Application

Create a SignalR application by following either of these tutorials:

Next, we’ll modify the chat application to support scaleout with Redis. First, add the SignalR.Redis NuGet package to your project. In Visual Studio, from the Tools menu, select Library Package Manager, then select Package Manager Console. In the Package Manager Console window, enter the following command:

Install-Package Microsoft.AspNet.SignalR.Redis 

Next, open the Startup.cs file. Add the following code to the Configuration method:

public class Startup
        public void Configuration(IAppBuilder app)
            // Any connection or hub wire up and configuration should go here
            GlobalHost.DependencyResolver.UseRedis("server", port, "password", "AppName");
  • “server” is the name of the server that is running Redis.
  • port is the port number
  • “password” is the password that you defined in the redis.conf file.
  • “AppName” is any string. SignalR creates a Redis pub/sub channel with this name.

For example:

GlobalHost.DependencyResolver.UseRedis("redis-server.cloudapp.net", 6379,
    "MyStrongPassword1234", "ChatApp");

Deploy and Run the Application

Prepare your Windows Server instances to deploy the SignalR application.

Add the IIS role. Include “Application Development” features, including the WebSocket Protocol.

Also include the Management Service (listed under “Management Tools”).

Install Web Deploy 3.0. When you run IIS Manager, it will prompt you to install Microsoft Web Platform, or you candownload the intstaller. In the Platform Installer, search for Web Deploy and install Web Deploy 3.0

Check that the Web Management Service is running. If not, start the service. (If you don’t see Web Management Service in the list of Windows services, make sure that you installed the Management Service when you added the IIS role.)

By default, the Web Management Service listens on TCP port 8172. In Windows Firewall, create a new inbound rule to allow TCP traffic on port 8172. For more information, see Configuring Firewall Rules. (If you are hosting the VMs on Windows Azure, you can do this directly in the Windows Azure portal. See How to Set Up Communication with a Virtual Machine.)

Now you are ready to deploy the Visual Studio project from your development machine to the server. In Solution Explorer, right-click the solution and click Publish.

For more detailed documentation about web deployment, see Web Deployment Content Map for Visual Studio and ASP.NET.

If you deploy the application to two servers, you can open each instance in a separate browser window and see that they each receive SignalR messages from the other. (Of course, in a production environment, the two servers would sit behind a load balancer.)

If you’re curious to see the messages that are sent to Redis, you can use the redis-cli client, which installs with Redis.

redis-cli -a password

[Dev Rule] Leaving patterns & practices

“Life is like skiing.  Just like skiing, the goal is not to get to the bottom of the hill. It’s to have a bunch of good runs before the sun sets.” – Seth Godin

It’s been a good run.  After more than 10 years in patterns & practices, I’m on to my next adventure here at Microsoft.

For this post, I wanted to take a stroll down memory lane.  During my time at patterns & practices, I learned more about project management, application architecture, software development, processes, teamwork, leadership, product success, and making impact than I think I could have ever hoped to learn anywhere else.  Perhaps the best part, is that I have 10+ years ofdeliberate practice in the art of “best practices” and I’ve had a chance to work with some of the most amazing people in the industry, lead SWAT teams around the world on fantastic voyages and epic adventures, and leave a legacy of several high-impact Microsoft Blue Books, all while mastering the art of prescriptive guidance.

There are a few ways I can share my journey in patterns & practices.  One of my managers referred to me as “the abilities PM” because of my focus on quality attributes (security, performance, scalability, etc.)  and that’s a pretty good place to start.  My role as a PM (Program Manager) in patterns & practices, can largely be defined in terms of my impact on these three areas: security, performance, and application architecture.  (Yes, there is more to the story, but those three areas, serve as a good enough lens for now.)

The Security Story
It all started when I joined patterns & practices (PAG or the Prescriptive Architecture Guidance team at the time.)


I moved from Microsoft Developer Support with the expectation that I would share and scale broadly with customers what I learned from living in across the hall from folks like Scott Guthrie, Brad Abrams, and other .NET Framework leaders.  Having performed more than 650 customer architecture and design reviews, I was in a unique position to share all the principles, patterns, practices, and anti-patterns that I had seen across a large number of customer projects, many of which were on the leading and bleeding edge of this space.

But life has a way of throwing curve balls.  Around this time, security was Jim Allchin’s top priority, and he asked patterns & practices what we were going to do about security.  In turn, my manager asked me, what I was going to do about security.  Coming from a middleware background, security was something I was usually trying to work around, especially when I had to flow callers to the backend.  My new challenge was to design security architectures for our application platform on .NET.  Boy, was I in for a ride.

I knew security was the name of the game, but I had a lot to learn in terms of leading project teams around the world, brokering in all the right parts of the company, our community, and the industry.  I also had a lot to learn in terms of how to create prescriptive guidance.  The purpose was not to just put out a book.  The purpose was to drive customer success on the platform.  This included creating a durable, and evolvable security storythat our customers could build on, and that we could use to “train the trainers.”  This also meant creating a knowledge base that we could use as an anchor for driving product feedback and platform change.  This was all in addition to learning how to think about security from an architecture and design standpoint, in a way that could help customers build more secure applications.

And thus the first Microsoft Blue Book, Building Secure ASP.NET Applications, was born.  It was our answer to IBM Redbooks.

While I learned a lot from doing end-to-end security architectures and putting our variety of products and technologies together, the real learning came from driving Improving Web Application Security, or “Threats and Countermeasures”, as we affectionately called it.  This journey was about learning how to bridge the gap between architecture and design, development, test, and operations.  It was about learning how to think about securityfrom a threats, attacks, vulnerabilities, and countermeasures perspective.  It was about thinking about security in a more holistic way, and our little mantra was “secure the network, host, and app.”

We had the ultimate security dream team, on mission impossible, and we pulled it off.  Our core engineering team included Alex Mackman, Michael Dunner, Srinath Vasireddy, Ray Escamilla and Anandha Murukan, and we had an extended team  of industry champs including Joel Scambray of the Hacking Exposed series.  (In fact, check out the extensive team list at the bottom of our Threats and Countermeasures Landing Page.)

How do I know we pulled it off?  We had outstanding results in our platform security competitive study, and we were told that is was our prescriptive guidance that made the difference in a very big way.  In addition, our guide was downloaded more than 800,000 times in the first six months, and it quickly established the mental models and language for how our growing customer base thought about security on the .NET platform.  It was a powerful thing when customers would say to us back in our language, “We’re using the trusted subsystem model  …”  It was like poetry in motion.

The big thing we learned from the journey was the power of having end-to-end application scenarios, along with maps of threats and countermeasures, while baking security into the life cycle, and using proven practices, like threat modeling, to significantly change the game.

Here are some of the key security deliverables at a glance from the various security adventures over the years:

This doesn’t include the product feedback work we did, or the work we did to bake security into Visual Studio / MSF Agile, or the patents we filed, which were the icing on the cake.  As a sidenote, behind the scenes we called our “threats and countermeasures” guide “WOMA.”  It was short for weapon-of-mass adoption, because our field was continuously telling us stories of how they were winning accounts against the competition.

The Performance Story
Performance was right up my alley, but it was a significant shift from security.


Ironically, I got a lot better at tackling security, by learning more about performance.  The big lesson I learned was that you have to bound or constrain your efforts in some way.  Just like performance can always be improved, so can security, so it’s all about prioritizing, knowing where to focus, and connecting back to the business objectives, aside from the technical perspective, and user experience.

Our first epic adventure in the performance space was the guide, Improving .NET Application Performance and Scalability (or, “Perf and Scale” as we affectionately called it.)   It was where I first got to work with folks like Rico Mariani, Jan Gray, and Gregor Noriskin.   It was mind blowing.

Working on performance and scalability was probably the most technically challenging exercise I’ve had at Microsoft.  I remember spending countless days and nights walking through CLR internals, figuring out how to optimize collections, sorting through multi-threading patterns, and mastering how garbage collection really worked.  Strangely enough, the “ah-ha” that I appreciated the most was figuring out that we could think of performance in terms ofresponse time, throughput, and resource utilization (CPU, memory, network, and disk.)  That little lens was the key to figuring out how to do effective performance modeling and solving nasty performance bottlenecks.  It also helped us parse complicated performance scenarios down into bite-sized chunks.

Here are some of the key performance deliverables at a glance from the various performance adventures over the years:

While performance took me to the depth of things, it was application architecture that took me to the breadth of things …

Application Architecture
Creating the Microsoft Application Architecture Guide was a chance to pull it all together.


It was a chance to finally showcase how to put our platform technologies together into common application archetypes.  Rather than just a bunch of technologies, we could talk about our application platform very specifically in terms of application types: Web applications, RIA applications, desktop applications, Web services, and mobile applications.  We could talk about scenarios and trade-offs.  We could look at the shapes of applications in terms of architectural styles and patterns.  We could look at cross-cutting concerns, such as caching, communication, concurrency, configuration management, data access, exception management, logging, state management, validation, and workflow.  We could also walk the various quality attributes, like performance, security, reliability, manageability, usability, etc.

As you can imagine, this meant putting together a comprehensive map of our Microsoft application platform.  The surprise for me was that by putting together the map and looking broadly at the industry, it was easy to see the forest from the trees, as well as better understand and anticipate where the industry was going in terms of what was growing and what was dying.  It was a great way to get ahead of the curve.  In fact, I’ve continued to map out our Microsoft application platform each year, as a way to quickly see the forest from the trees and to figure out where to spend my time.

During my adventures with application architecture, I got to learn a lot and work with amazing people.   I also learned how to go across a lot of information faster and easier, and bring teams of people along the journey.  The secret was to keep creating maps that helped everybody get on to the same page fast.  This was an invaluable approach as our team was hunting and gathering all the pattern collections we could find.  We basically built a large catalog and constellation of application patterns in the form of maps.  While we didn’t include our maps in the guide, they helped our team and extended team ramp up in various spaces very quickly, as well as advance the practice of application architecture.  Basically, we could browse patterns of solutions at a glance.

If you read nothing else, check out A Technique for Architecture and Design.  Behind the scenes, we created this technique by synthesizing the expertise of more than 30 top solution architects, that had years of experience with structuring and designing end-to-end applications, dealing with security, performance, and reliability issues, and dealing with cross-cutting concerns.  The idea was to put down on paper, a proven practice for rapidly modeling applications on a whiteboard and identify risks earlier vs. later.

What’s Next?
I’ll have more to share as I go along.   What you’ll most likely see is a shift to more focus on strategy, execution, and business impact.  I’ll also share more information on the art and science of program management.   I’ve been mentoring a lot of people and I think the PM role at Microsoft is a very special one.  One of my mail goals is to broadly share the lessons I’ve learned from driving projects and leading teams and making impact as a PM on the patterns & practices team.

patterns & practices Guidance at a Glance
Meanwhile, here is my catalog of patterns & practices guidance at a glance.  Note that a lot of the prescriptive guidance I’ve worked on is out of date because of changes in technology.  That said, you can still learn many of the key principles, patterns, and practices that  the guidance is based on.  In this respect, much of the guidance is “evergreen” in that it’s timeless and durable.


Developer Guidance Maps

Application Architecture

Books / Guides




How Tos


Books / Guides




Practices at a Glance

How Tos




Threats and Countermeasures

Cheat Sheets



Practices at a Glance

Questions and Answers


Application Scenarios

ASP.NET Security How Tos

WCF Security How Tos

Visual Studio Team System



Practices at a Glance

Questions and Answers

How Tos

My Related Posts

REF: http://blogs.msdn.com/b/jmeier/archive/2011/02/28/leaving-patterns-amp-practices.aspx

[Dev Rule] Principles behind the Agile Manifesto

Our highest priority is to satisfy the customer
through early and continuous delivery
of valuable software.

Welcome changing requirements, even late in
development. Agile processes harness change for
the customer’s competitive advantage.

Deliver working software frequently, from a
couple of weeks to a couple of months, with a
preference to the shorter timescale.

Business people and developers must work
together daily throughout the project.

Build projects around motivated individuals.
Give them the environment and support they need,
and trust them to get the job done.

The most efficient and effective method of
conveying information to and within a development
team is face-to-face conversation.

Working software is the primary measure of progress.

Agile processes promote sustainable development.
The sponsors, developers, and users should be able
to maintain a constant pace indefinitely.

Continuous attention to technical excellence
and good design enhances agility.

Simplicity–the art of maximizing the amount
of work not done–is essential.

The best architectures, requirements, and designs
emerge from self-organizing teams.

At regular intervals, the team reflects on how
to become more effective, then tunes and adjusts
its behavior accordingly.