Category Archives: Design

The Twelve-Factor App

The Twelve-Factor App is a set of golden rules for web-based applications:

In the modern era, software is commonly delivered as a service: called web apps, or software-as-a-service. The twelve-factor app is a methodology for building software-as-a-service apps that:

  • Use declarative formats for setup automation, to minimize time and cost for new developers joining the project;
  • Have a clean contract with the underlying operating system, offering maximum portability between execution environments;
  • Are suitable for deployment on modern cloud platforms, obviating the need for servers and systems administration;
  • Minimize divergence between development and production, enabling continuous deployment for maximum agility;
  • And can scale up without significant changes to tooling, architecture, or development practices.

The twelve-factor methodology can be applied to apps written in any programming language, and which use any combination of backing services database, queue, memory cache, etc.

via The Twelve-Factor App.

The Words of Martin Fowler

Any fool can write code that a computer can understand. Good programmers write code that humans can understand.

Martin Fowler’s Wikiquote page is a diamond mine of aphorisms.

Often designers do complicated things that improve the capacity on a particular hardware platform when it might actually be cheaper to buy more hardware.

Analysis Patterns: Reusable Object Models, 1997

Modeling Principle: Models are not right or wrong; they are more or less useful.

Refactoring: Improving the Design of Existing Code, 1999

When you find you have to add a feature to a program, and the program’s code is not structured in a convenient way to add the feature, first refactor the program to make it easy to add the feature, then add the feature.

When you feel the need to write a comment, first try to refactor the code so that any comment becomes superfluous.

The key is to test the areas that you are most worried about going wrong. That way you get the most benefit for your testing effort. It is better to write and run incomplete tests than not to run complete tests.

UML Distilled: A Brief Guide to the Standard Object Modeling, 2004

Comprehensiveness is the enemy of comprehensibility.

Martin Fowler deserves a knighthood.

node-di: a dependency injection framework for node.js

Uncle Bob is a proponent of inversion of control to counter what he defines as “bad design”:

There is one set of criteria that I think all engineers will agree with. A piece of software that fulfills its requirements and yet exhibits any or all of the following three traits has a bad design.

1. It is hard to change because every change affects too many other parts of the system. (Rigidity)
2. When you make a change, unexpected parts of the system break. (Fragility)
3. It is hard to reuse in another application because it cannot be disentangled from the current application. (Immobility)

What is it that makes a design rigid, fragile and immobile? It is the interdependence of the modules within that design.

source

One solution to standardise the interfaces of modules (or classes) is dependency injection. Vojta Jina has put together a powerful, lightweight dependency injection library for node.js. Its example is testament to its simplicity:

var Car = function(engine) {
  this.start = function() {
    engine.start();
  };
};

var createPetrolEngine = function(power) {
  return {
    start: function() {
      console.log('Starting engine with ' + power + 'hp');
    }
  };
};


// a module is just a plain JavaScript object
// it is a recipe for the injector, how to instantiate stuff
var module = {
  // if an object asks for 'car', the injector will call 
  // new Car(...) to produce it
  'car': ['type', Car],
  // if an object asks for 'engine', the injector will call 
  // createPetrolEngine(...) to produce it
  'engine': ['factory', createPetrolEngine],
  // if an object asks for 'power', the injector will give it number 1184
  'power': ['value', 1184] // probably Bugatti Veyron
};


var di = require('di');
var injector = new di.Injector([module]);

injector.invoke(function(car) {
  car.start();
});

Martin Fowler has more to say on the benefits of Dependency Injection.

Signs that you’re a good programmer

A truly superb list of aspirational qualities for software developers. It includes symptoms of each particular quality and guidelines on how to acquire the desired traits.

Signs that you’re a good programmer

1. The instinct to experiment first
2. Emotional detachment from code and design
3. Eager to fix what isn’t broken
4. Fascinated by the incomprehensible
5. Compelled to teach

Signs that you’re a fantastic programmer

1. Incorruptible patience
2. A destructive pursuit of perfection
3. Encyclopedic grasp of the platform
4. Thinks In Code
5. When In Rome, Does As Romans Do
6. Creates their own tools

Signs that you’re destined for more

1. Indifferent to Hierarchy
2. Excited by failure
3. Indifferent to circumstances
4. Unswayed by obligations
5. Substitutes impulse for commitment
6. Driven by experiences

Signs that you’re a bad programmer

A blood-curdling selection of negative traits and anti-patterns that programmers should recognise and avoid. Remedies are included for the ailing.

Signs that you’re a bad programmer

1. Inability to reason about code
2. Poor understanding of the language’s programming model
3. Deficient research skills / Chronically poor knowledge of the platform’s features
4. Inability to comprehend pointers
5. Difficulty seeing through recursion
6. Distrust of code

Signs that you are a mediocre programmer

1. Inability to think in sets
2. Lack of critical thinking
3. Pinball Programming
4. Unfamiliar with the principles of security
5. Code is a mess

Signs that you shouldn’t be a programmer

1. Inability to determine the order of program execution
2. Insufficient ability to think abstractly
3. Collyer Brothers syndrome
4. Dysfunctional sense of causality
5. Indifference to outcomes

Know Your Onions (and Antipatterns)

Antipatterns (styles of design or process that may proliferate, but are ineffectual or counter-productive) can confound even the most battle-hardened of developers. Only knowledge can set us free, and to that end Source Making’s list of antipatterns is a welcome reminder.

Good software structure is essential for system extension and maintenance. Software development is a chaotic activity, therefore the implemented structure of systems tends to stray from the planned structure as determined by architecture, analysis, and design.

Software Development AntiPatterns