This is a listing of articles about concepts I find essential for any developer to know. This is organized in order of most base structural concepts to most high level concepts and includes good practices, principles, and lists of articles, conference talks and books on software development.
This page is in constant enhancement.
-
Good Practices
-
Reflect the architecture in the code folder structure
Doing structural encapsulation makes it a lot easier to communicate bounded contexts, dependencies, layers, related functionality and purpose of grouped classes. Close proximity in the tree suggests closer coupling. The top level should reflect the software usage, so it should be named according to the Domain, but in broad encapsulated concepts, because as business evolve the domain details might change. [Mathias Verraes, Robert C. Martin]
Make the architecture predictable and readable. Once you’ve agreed on an overall architectural structure for your project, make it obvious where the main elements are located. It will reduce time wasted, keep consistency, prevent lost code and avoid unaware code duplication. [Christian Maioli]
-
Clean Code
- Make the code predictable and readable
Don’t code “your way”. Just follow your team coding standards. Make your code predictable and easy to read by coding the way people expect. [Christian Maioli] - Create small, focused and encapsulated code units
The approach when breaking a problem down should be to have each section as focused as possible, affecting only local state, without mixing in irrelevant issues, and without side-effects if at all possible. [Christian Maioli] - Make it discrete and processable
Using magic strings, magic array indexes and custom template language features will lead to a more disconnected codebase. [Christian Maioli]
- Make the code predictable and readable
-
Conditionals (if, case)
- Avoid nested IF statements [Christian Maioli]
- Avoid ELSE statements [Christian Maioli]
- Encapsulate the IF condition in a meaningfully named method [Christian Maioli]
- Blocks inside conditionals should be one line long, a function call which, if named correctly, adds documentary value [Robert C. Martin]
- Do the exclusionary IFs first, and do early returns from those conditions. That leaves the bulk of the method body to do the expected work. [Matthew W. O’Phinney]
- Replace conditionals by polymorphism, when you have a conditional that chooses different behavior depending on the type of object.
Using inheritance: Extract the different behaviors into different subclasses and make the original method abstract. [Misko Hevery]
Using composition: Extract the different behaviors into different classes and inject the one you want in the original class. [Sandi Metz]
-
Loops
- Blocks inside loops should be one line long, a function call which, if named correctly, adds documentary value [Robert C. Martin]
-
Naming conventions
- Name your variables according to the class they contain [Mathias Verraes]
- Name functions/methods using a verb, according to their context and what they do
Document the why. Relevant and contextual variable and function names are the way to do this. [Robert C. Martin, Christian Maioli] - Name your classes using a noun, according to their domain and architectural meaning [Robert C. Martin]
- A class name should start by its domain meaning (ie. User) and be postfixed by their architectural meaning (ie. Factory) like UserFactory.
- A class name should identify it without ambiguity
Name your classes with a name as unique as possible, regardless of their namespace, so we don’t have to lose our focus from the code to go check the namespace.
-
Functions / methods
- Should be as small as possible [Robert C. Martin]
- Should have an explicit intent, both in its name and code [Robert C. Martin]
- Should do one thing only and do it well. One thing means one level of abstraction (manipulating strings is one level, manipulating business rules is another level), or when nothing else can be extracted and meaningfully reused in another function or method [Robert C. Martin]
- Methods in a class should be organized per level of abstraction, where the methods used by a method sit directly below it [Robert C. Martin]
- Choose descriptive names, for small functions, that do one thing [Robert C. Martin]
- Should have at most 3 arguments, if we have more than 3 and they are conceptually related, we should group them in an object [Robert C. Martin]
- Do not use output-arguments (arguments to output data out of a function/method) [Robert C. Martin]
- Don’t use boolean arguments, use 2 functions/methods instead [Robert C. Martin]
- Comply to CQS, either:
– Do something (change state)
– Get something (return info about an object)
Not both [Robert C. Martin] - Don’t return an error code, throw an exception instead [Robert C. Martin, Misko Hevery]
-
Classes
- Named constructors
Its OK to use them. [Mathias Verraes] - Static methods
Use them when they are stateless and generic (not domain, so we can have different implementations of domain logic injected in different places) [Mathias Verraes] - Private members access between sibling objects
It is handy, and OK, to do so in restricted situations, like comparing sibling objects properties. [Mathias Verraes] - Don’t set state by reference
All state should be encapsulated and inaccessible from outside the object. If we set a property using a given reference, the given object is still accessible from outside. If needed, clone the object being set; [Marco Pivetta] - Don’t use setters
Change in an object state should be the consequence of a conceptual/domain operation applied and encapsulated in the object. The constructor should be the only state injection point. If a business logic only sets a data value, so be it, but don’t name the method as a setter, name it by the business logic it reflects; [Mark Ragazzo, Marco Pivetta, TellDontAsk] - Avoid Getters
Using getters is sometimes necessary, but most of the times they should not be necessary. Their mere existence encourages putting business logic outside the class that has the data necessary to fulfill that logic, breaking encapsulation; [TellDontAsk] - Declare class as final
So it can’t inadvertently break LSP; [Mark Ragazzo, Marco Pivetta] - No mixed argument types
Don’t use an array/collection with different types inside as a parameter; [Marco Pivetta] - No mixed return types
Don’t return an array/collection with different types inside. If needed, use a value object to encapsulate the different types; [Marco Pivetta] - No boolean parameters
A boolean parameter will most likely be a logic switch for the method logic. This means it is actually hiding 2 methods. Then its better to actually have two methods. [Marco Pivetta, Robert C. Martin] - NULL objects:
As an argument
When a class has an optional dependency on a service, it is common practice to initialize it with NULL. However, it might be more readable and less error prone to initialize that dependency with an object that fulfills the dependency but all its methods just do nothing. This makes it possible to not need to check if the dependency is set and will make sure no errors will occur if someone tries to use a non set dependency; [qafoo.com]
As a return value
Never return null, return a null object or empty list instead, to reduce the conditionals needed by the client code; [Misko Hevery, Sandi Metz] - Composition over inheritance [Sandi Metz]
- Named constructors
-
Immutable objects [Mark Ragazzo, Marco Pivetta]
- When you need to modify an immutable object we actually return a new object with the new state;
- Declare properties as private so state can’t be modified from outside the object, nor even extending classes;
- Do not store references to mutable objects or mutable collections, in an immutable object. If we store a collection inside an immutable object, it should be immutable too, including its size, its elements and content of its elements;
- Declare class as final
So it can’t be overridden adding methods that modify internal state;
-
Entities
- They are the same if their ID is the same; [Mathias Verraes]
- Don’t create/use anemic entities
Entities should contain logic that manipulates their instances data, inside a specific object and between objects of the same type. However, they should not have knowledge about higher level domain processes. This is a fine line, easy to miss, and involves heavy ponderation and contextualization into the domain concepts; [Ross Tuck]
-
Value objects [Marco Pivetta, Mathias Verraes]
- They are the same if their state is the same;
- They ensure consistency, because the data is encapsulated and immutable.
- They simplify data validation, because we don’t need to validate their data everywhere its needed (its validated when creating the value object);
- They encapsulate state and behavior (including validation);
-
Exception Handling
- Don’t return an error code, throw an exception instead [Robert C. Martin, Misko Hevery]
- Always create your own exceptions hierarchy [toptal.com]
- Handle the minimum exceptions as possible [toptal.com]
- Handle exceptions as late as possible [toptal.com]
-
Business Rules
- BRs applicable to a Domain Object must be enforced by the object itself. For example, if a Costumer must always have an email, make it impossible to create a Customer entity without an email, by forcing its injection in the constructor; [Mathias Verraes]
- If a BR should be enforced in a domain object sometimes and sometimes not, maybe we are missing some relevant domain concept, maybe we should be using two different domain objects instead. For example, if a customer sometimes doesn’t need an email and sometimes must have an email, maybe we should have a ProspectiveCustomer and a PayingCustomer entities; [Mathias Verraes]
- If the verification of a BR needs more than one object (ie an entity and a repository) encapsulate it in a SPECIFICATION object.
- When using a specification object to model a BR, encapsulate its different representations in the same specification object (ie code and SQL representations); [Mathias Verraes]
- When using a specification object, test the different representations of the BR by comparing their result against each other; [Mathias Verraes]
-
Modeling the domain
- Start modeling the domain by defining the use cases (ie addProductToBasket) and from there decide what commands, handlers, services, entities, value objects and repositories are needed; [Mathias Verraes]
-
Talks
- Clean Code 3: Functions – 2008 – Robert C. Martin (my review)
- Clean Code 1: Arguments (why CC?)- 2010 – Robert C. Martin (my review)
- Your code sucks, lets fix it! – 2014 – Rafael Dohms
- Extract Till You Drop – 2014 – Matthias Verraes
- Unbreakable Domain Models – 2014 – Matthias Verraes
- Extremely Defensive PHP – 2015 – Marco Pivetta
- Nothing is Something – 2015 – Sandi Metz
- Writing code that lasts – 2016 – Rafael Dohms
-
-
Principles
- DRY – Don’t Repeat Yourself
- KISS – Keep It Simple Stupid
- Law of Demeter
A component or object should not know about internal details of other components or objects (Encapsulation). - YAGNI – You Ain’t Gonna Need It
If some code, methods, classes are not needed now, don’t leave them there just in case they are needed in the future. Not even if they are commented out. Who knows how it will look in the future, we might end up spending time updating code that is not used, we might never need it, we can always rebuild it or get it from the VCS. - TellDontAsk [Martin Fowler, Don’t use setters, Avoid getters]
Instead of having a class with getters and setters and call those methods to perform some business logic, we should encapsulate that business logic inside the class that has the data and create a method named after the business logic we are implementing. - STUPID [nikic]
- Singleton
- Tight coupling
- Untestability
- Premature Optimization
- Indescriptive Naming
- Duplication
- SOLID – Robert C. Martin
- SRP – Single responsibility principle – A class should have only a single responsibility
- OCP – Open/closed principle – Software entities … should be open for extension, but closed for modification
- LSP – Liskov substitution principle – Objects in a program should be replaceable with instances of their subtypes
- ISP – Interface segregation principle – Many client-specific interfaces are better than one general-purpose interface
- DIP – Dependency inversion principle – Depend upon abstractions, not upon concretions
- Package Cohesion Principles – Robert C. Martin
- REP – The Release Reuse Equivalence Principle – The granule of reuse is the granule of release
- CCP – The Common Closure Principle – Classes that change together are packaged together
- CRP – The Common Reuse Principle – Classes that are used together are packaged together
- Package Coupling Principles – Robert C. Martin
- ADP – The Acyclic Dependencies Principle – The dependency graph of packages must have no cycles
- SDP – The Stable Dependencies Principle – Depend in the direction of stability
- SAP – The Stable Abstractions Principle – Abstractness increases with stability
- Inversion of Control – The Hollywood Principle (NOT the Dep. Inv. Principle)
- GRASP – “General Responsibility Assignment Software Patterns”
- Easy reading: Wikipedia
- Complete reading: Carnegie Mellon School of Computer Science
- My own short descriptions:
- Controller
Controller pattern
A controller is defined as the first object beyond the UI layer that receives and coordinates (“controls”) a use case scenario. - Creator
Factory method, Abstract Factory and Builder patterns
In general, a class B should be responsible for creating instances of class A if one, or preferably more, of the following apply:
– Instances of B contain or compositely aggregate instances of A
– Instances of B record instances of A
– Instances of B closely use instances of A
– Instances of B have the initializing information for instances of A and pass it on creation. - High Cohesion
The responsibilities of a given element are strongly related and highly focused. Relates to the SOLID Single Responsibility Principle. - Indirection
Mediator pattern
Increase low coupling by using a Mediator class to coordinate the interactions between two objects. - Information Expert
Encapsulation
Place a given responsibility on the class with the most information required to fulfill it. - Low Coupling
Low coupling is an evaluative pattern that dictates how to assign responsibilities to support:
– lower dependency between the classes,
– change in one class having lower impact on other classes,
– higher reuse potential. - Polymorphism
Usage of inheritance, abstracts, interfaces, generics, overloading and overriding. - Protected Variations
Bridge, adapter and similar patterns
Protect elements from the variations on other elements (objects, systems, subsystems) by wrapping the focus of instability with an interface and using polymorphism to create various implementations of this interface. - Pure Fabrication
Service class
Use Service classes, who do not represent a concept in the problem domain, specially made up to achieve low coupling, high cohesion, and reusability.
- Controller
-
Talks
- Don’t Be STUPID GRASP SOLID – 2013 – Anthony Ferrara (slides)
-
Object-Oriented Programming
- When FP? And when OOP? – 2013 – Reginald Braithwaite
- All the Little Things – 2014 – Sandi Metz
- Nothing is Something – 2015 – Sandi Metz
- Polly want a message – 2018 – Sandi Metz
-
Functional Programming
- Functional Programming Jargon
- When FP? And when OOP? – 2013 – Reginald Braithwaite
- Functional Programming: The failure of state – 2014 – Robert C. Martin
- The pits of success – 2016 – Mark Seemann
-
Testing
- The magic tricks of testing – Rails Conf 2013 – Sandi Metz
- TDD Where did it all go wrong – DevTernity 2017 – Ian Cooper
- A Case For Outside-In Design – SCLConf 2018 – Sandro Mancuso
-
Design Patterns
- Design patterns, the big picture, Part 1: Design pattern history and classification
- Design patterns, the big picture, Part 2: Gang-of-four classics revisited
- SourceMaking :: Design Patterns (easy explanation of many Design Patterns)
- DesignPatternsPHP (PHP examples of many Design Patterns)
- Beyond Design Patterns – PHP Barcelona Conf 2015 – Anthony Ferrara
-
Architecture
-
Articles
- 1979 – MVC – Trygve Reenskaug
- 1987 – PAC – Joëlle Coutaz
- 1992 – BCE – Ivar Jacobson
- 1996 – MVP – Mike Potel
- 2000 – HMVC – Jason Cai, Ranjit Kapila, Gaurav Pal
- 2005 – MVVM – Ken Cooper, Ted Peters
- 2005 – Hexagonal Architecture (aka Ports & Adapters) – Alistair Cockburn
- 2008 – MVA – Sun Microsystems
- 2008 – DCI – Trygve Reenskaug, James Coplien
- 2008 – Onion Architecture [1, 2, 3, 4] – Jeffrey Palermo
- 2009 – Clarified CQRS – Udi Dahan
- 2009 – Software Architecture and Design – MS App. Architecture Guide
- 2011 – Domain Driven Design – Ward Cunningham
- 2011 – Screaming Architecture – Robert C. Martin
- 2011 – CQRS – Martin Fowler
- 2011 – When to avoid CQRS – Udi Dahan
- 2012 – Clean Architecture – Robert C. Martin
- 2014 – DDD – Integrating Bounded Contexts – Philip Brown @ Culttt
- 2015 – Platform Building Cheat Sheet –
- 2017 – What do you mean by “Event-Driven”? – Martin Fowler
- 2019 – Mistakes we made adopting event sourcing (and how we recovered) – Nat Price
- 2019 – Why Event Sourcing is a microservice communication anti-pattern –
Oliver Libutzki
-
Talks
- 2008 – Strategic Design – Eric Evans
- 2011 – Architecture the Lost Years – Robert C. Martin
- 2012 – Clean Architecture and Design – Robert C. Martin
- 2014 – CQRS and Event Sourcing – Greg Young
- 2014 – Event Sourcing – Greg Young
- 2014 – Models & Service Layers; Hemoglobin & Hobgoblins – Ross Tuck
- 2014 – How You Can Architect and Develop Enterprise Mission-Critical Applications with Domain-Driven Design – Vaughn Vernon
- 2014 – How You Can Implement Aggregates and Domain Entities Effectively in Domain Models, with .NET – Vaughn Vernon
- 2014 – Software Architecture vs. Code – Simon Brown (my review)
- 2014 – DDD and Hexagonal Architecture with Rails – Eric Roberts & Declan Whelan
- 2014 – Hexagonal Architecture – Chris Fidao
- 2015 – Hexagonal Architecture – Message-Oriented Software Design – Matthias Noback
- 2015 – Hexagonal Architecture in DDD – Gordon Skinner
- 2016 – oDDs and enDDs – Vaughn Vernon
- 2017 – TDD, Where Did It All Go Wrong – Ian Cooper
- 2017 – The Many Meanings of Event-Driven Architecture – Martin Fowler
- 2018 – Modular Monoliths – Simon Brown
- 2018 – Event Sourcing You are doing it wrong – David Schmitz
- 2019 – Software Management Lessons from the 1960s – Larry Garfield
- 2019 – All our aggregates are wrong – Mauro Servienti
-
-
REST
-
Microservices
- Cheat Sheets
- Micro-Services – Martin Fowler
-
Professionalism
- Craftsmanship and Ethics – 2011 – Robert C. Martin
- The responsibility of knowing – 2013 – Robert C. Martin (my review)
- Expecting professionalism – 2014 – Robert C. Martin (my review)
- Guidelines
- A Programmer has the right to [Robert C. Martin, Kent Beck]
- Know what is needed with clear declarations of priority;
- Produce quality work at all times;
- Ask for and receive help from pears, supervisors and customers;
- Make and update their own estimates;
- Accept responsibility instead of having them assigned
- A Customer has the right to [Robert C. Martin, Kent Beck]
- An overall plan, when it can be accomplished and at what cost;
- Get the most out of every programming week;
- See progress in a running system, working by passing a set of tests they specify;
- Change their mind, to substitute functionality, and to change priorities without paying exorbitant costs;
- Be informed of a schedule change in order to reduce scope and restore the original date;
- Cancel the project and be left with a system that runs and reflects investment to date.
- A CTO has the right to expect [Robert C. Martin]
- We shall not ship crap!
- At the end of every iteration we are ready to deploy!
- Stable productivity:
We must be able to keep the code easy to maintain and develop further; - Continuous improvement:
We must continuously improve the code, following the boyscout rule; - Inexpensive adaptability:
Software must be easy to change;
We must accept changes in requirements; - Fearless competence:
We must not be afraid of modifying and improving the code;
We must have tests we trust, so we have no fear of changing code; - Extreme quality:
We must not allow a sloppy or careless attitude; - QA will find nothing:
We must demand of ourselves that the software reaches QA perfect; - Nothing is fragile:
Making a change will not break something completely unrelated; - We cover for each other:
We are a team, if a member can not be there, a colleague must be able to take charge;
A developer can not be working isolated, he must work together with colleagues. Do pair programming; - Honest estimates:
We must be honest about the exequibility of our estimates
If it can’t be done in the expected time frame we must say so. And we must not cave in when under pressure;
We can use a 3 possibilities frame:
1 – Estimate if everything goes perfect;
2 – Estimate if things go OK;
3 – Estimate if everything goes wrong;
We must be able to say NO! - Continuous aggressive learning:
Our industry evolves super fast, we must keep up;
We must read books, go to conferences, read articles, experiment;
The employer is not responsible for our learning nor our career; - Mentoring:
People coming out of school are not properly trained;
The more senior people must teach the younger ones;
- A Programmer has the right to [Robert C. Martin, Kent Beck]
-
Agile
- Top 10 Lessons Learned From 10 Years in Agile
- Simplicity is Sophistication
- Define your Rhythm
- Agile is Fundamentally About Discipline
- Software is Hard to Scale, Agile is Not
- Think of the Big Picture
- Lose the Religion
- Continuous Focus on Business Value
- Agile – It’s Not Just For Software Anymore
- Continuous Planning
- Doing agile and being agile aren’t the same
- Practical Agile development: A challenge from the trenches – 2016 – Sandy Metz
- Top 10 Lessons Learned From 10 Years in Agile
-
Team Building
- The Geek’s Guide to Leading Teams – 2012 – Patrick Kua
- How to Build a Great Software Development Team – 2012 – Robert C. Martin
- Software Development in the 21st Century – 2013 – Martin Fowler
- Teams: building, managing, leading, performing – 2015 – Herberto Graça
-
Technical leadership
- Riding the paradox as a lead developer – Patrick Kua – LeadDev 2015
- Flavours of technical leadership – Patrick Kua – LeadDev 2019
- Software Management Lessons from the 1960s – DPC 2019 – Larry Garfield
-
Books to read
- Object-Oriented Software Engineering: A Use Case Driven Approach
1992 – Ivar Jacobson - The Mythical Man-Month: Essays on Software Engineering
1995 – Frederick P. Brooks Jr. - Analysis Patterns: Reusable Object Models
1996 – Martin Fowler - Refactoring: Improving the Design of Existing Code
1999 – Martin Fowler, Kent Beck, John Brant - The Pragmatic Programmer: From Journeyman to Master
1999 – Andrew Hunt, David Thomas - Patterns of Enterprise Application Architecture
2002 – Martin Fowler - Agile Software Development, Principles, Patterns, and Practices
2002 – Robert C. Martin - Domain-Driven Design: Tackling Complexity in the Heart of Software
2003 – Eric Evans - Lean Thinking: Banish Waste and Create Wealth in Your Corporation, Revised and Updated
2003 – James P. Womack, Daniel T. Jones - The Toyota Way: 14 Management Principles from the World’s Greatest Manufacturer
2004 – Jeffrey K. Liker - Head First Design Patterns
2004 – Eric Freeman, Bert Bates, Kathy Sierra - Working Effectively with Legacy Code
2004 – Michael Feathers - Code Complete: A Practical Handbook of Software Construction
2004 – Steve McConnell - Clean Code: A Handbook of Agile Software Craftsmanship
2008 – Robert C. Martin - Growing Object-Oriented Software, Guided by Tests
2009 – Steve Freeman, Nat Pryce - Lean Architecture: for Agile Software Development
2010 – James O. Coplien, Gertrud Bjørnvig - Business Model Generation
2010 – Alexander Osterwalder, Yves Pigneur - Seven Languages in Seven Weeks: A Pragmatic Guide to Learning Programming Languages
2010 – Bruce Tate - The Clean Coder: A Code of Conduct for Professional Programmers
2011 – Robert C. Martin - The Lean Startup: How Today’s Entrepreneurs Use Continuous Innovation to Create Radically Successful Businesses
2011 – Eric Ries - Peopleware: Productive Projects and Teams
2013 – Tom DeMarco, Tim Lister -
Implementing Domain-Driven Design
2013 – Vaughn Vernon - Soft Skills: The software developer’s life manual
2014 – John Somnez - Lean Enterprise: How High Performance Organizations Innovate at Scale
2015 – Jez Humble, Joanne Molesky, Barry O’Reilly - Patterns, Principles, and Practices of Domain-Driven Design
2015 – Scott Millett, Nick Tune - Building Microservices
2015 – Sam Newman
- Object-Oriented Software Engineering: A Use Case Driven Approach
-
Other
- My mostly incomplete list of memorable talks that should probably be required material – Jeroen V. D. Gulik
- Every Programmer Should Know – Hesky Ji
- Awesome & Interesting Talks concerning Programming – Veit Heller
2 thoughts on “Dev curricula”