Skip to content

Instantly share code, notes, and snippets.

What would you like to do?
I'm your CTO! As a developer, here the rules I expect you to follow:

Developer: Principles


Like Robert C. Martin would say on this video,

Imagine I'm your CTO, as your CTO I expect you to follow this principles:

Untitled-collage-10-min-9 (1)


# 17 Principles
1 Simple code, easy to read
2 Explicit "Needs" first, do not over-engineer
3 Fail Fast: Crash as soon as possible with explicit message
4 Be careful with "silent return" or "if" without "else"
5 Immutable POJO objects
6 One source of truth
7 Composition over inheritance
8 Feature over layer
9 Write unit-testable code
10 Split concern
11 Avoid god objects
12 Minimize cross feature dependencies
13 Minimize API
14 Expose interfaces
15 Copy & Paste over generic & factorisation
16 Do not use tools you do not masterize
17 Always produce your best "code"
18 Design affordance in code


1. Simple code, easy to read

The most important rule. A program must be "maintainable" so "readable". Software is meant to change in constant time, not in exponential time. "Readability" is the first step to achieve that goal.

2. Explicit "Needs" first, do not over-engineer

Be pragmatic. Even if it's great to anticipate the futur when possible, do not produce dead code. Make the code evolutive to be able to modify it later. Keep it simple, easy to maintain. Explicit what's your main "needs" first to avoid to produce code you will not need.

3. Fail Fast: Crash as soon as possible with explicit message

Avoid side effects & Avoid silent wrong behaviours. When you detect something wrong, crash! When a variable, an argument or a field contains something wrong, crash! At first your code will crash, sure. But you will spot issue very fast. Then your code will be more robust and easier to read because in the range of all possibilities, side effects have been excluded.

  • Try to exclude edge cases with return or throw as soon as possible in top of methods / constructors.
  • Try to avoid if statement without else

4. Be careful with "silent return" or "if" without "else"

We try to avoid as much as possible return that does nothing in method. Why? Often that the cause of issue difficult to spot. That's why it's better to crash when something is wrong than simply return. Here Linus Torvals point in video.

5. Immutable POJO objects

Like in real life. Most of a "chair" will not change during its lifetime. Immutability makes object comparison easier. Creating a new object to change a property is totally OK.

6. One source of truth

Multiple sources of truth lead to:

  • one will not be maintained for sure
  • more changes to do at maintenance
  • less obvious for clients which one to use

So be careful to:

  • API exposed to your Dependency Injection graph
  • Extra fields you have in your classes (presenters, controllers, managers...).
  • Maintain documentation as the code is the only source of truth

7. Composition over inheritance

"Be something" notion brings by inheritance is a strong notion. Factorization should never be the only reason leading to inheritance.

8. Feature over layer

A project splitted by feature instead of layer is more scallable. Feature packages/namespaces are "more standalone". In other words a feature can be easily deleted. Moreover that give to developer a better look of the feature scope and context.

9. Write unit-testable code

Unit testable code will force your code to be designed carefully, less dependent of your platform and less inter-dependant. For pure "logic" code like Algorithm to convert decimal number to Roman Numeral, TDD is a great way to go.

  • Do not let managers/PO decide if you should skip tests.
  • Never expose code coverage out of the developer team. This metric is for developers only because only developers are fully aware of the meaning of this percentage.

What code must be tested:

  • Most critical part like billing, main feature...
  • Storage to assure non-regression
  • "Pure" logic code to help the code reviewier and futur developer

What code must not be tested:

  • Never test implementation details (private method, code that change). Avoid tests that bring rigidity.

Unit-testable code doesn't mean all the code must be unit-tested.

10. Split concern

Single responsibility principle. One "module", "class" or "method" should only have one role.

11. Avoid god object

Same reason as the Split concern rule.

In the same way for arguments, try to ask only what a function/constructor need. For example, on Android, do not ask a Context when youre only need is to convert a ColorRes to a ColorInt. Try to abstract the Color convert notion from the god object Context.

12. Minimize cross feature dependencies

Same reason as the Split concern rule. Will make your feature easier to change, easier to delete.

13. Minimize API

API: Contract your software as with the world. I'm taling of public API out of your software as far as you inner feature that you will share to the rest of your app.

Great design try to avoid redoncancy. Why?

  • Easier to maintain
  • Avoid client questions: which one should I use
  • Readable

14. Expose API with interfaces

  • More readable contract
  • Easier to change implementation
  • Makes clients of this API easier to test

15. Copy & Paste over generic & factorisation

To be more robust to change. A lot of junior are using the "duplicate code is evil" principle: that's dangerous. If the code serves separate feature that means that the code can change for different reasons.

16. Do not use tools you do not masterize

PROs and CONs of third-party libraries, new languages or external softwares must be known before taking the descision of using them. Adding new tool has hidden costs to be aware:

  • Teach people how to use the tool
  • Be sure the tool will be maintained
  • What will be the cost of changing the tool to another one

17. Always produce your best "code"

No excuse to not respect that. Wrong, you will not "gain time"! For a non developer, this point is obvious, for some developers, not so obvious.

Any git-repository must be better over time. Refactorization should be done continously. Architecture should be improved continously.

18. Design affordance in code

No need to comment great code. Here the reason. Affordance in code is having your code self-explained by design.


Principles are defining a goal, a vision. In day to day code, sure, as principles are not strict rules, it's OK to not follow strictly principles.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment