Это список статей о концепциях, которые я считаю важным для любого разработчика. Он составлен в порядке от самых базовых структурных концепций до высокоуровневых концепций и включает лучшие практики (best practices), принципы и списки статей, доклады на конференциях и книги по разработке программного обеспечения.
Страница постоянно обновляется.
-
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] - Don’t use Magic Numbers. Unique values with unexplained meaning or multiple occurrences which could (preferably) be replaced with named constants [medium.com]
- Make the code predictable and readable
-
Conditionals (if, case)
- Avoid nested IF statements [Christian Maioli]. Deeply nested conditionals make it just about impossible to tell what code will run, or when. [source]
- 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]
- 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] - Flags are not a best practice because they reduce the cohesion of a function. It does more than one thing.
- Booleans make it hard to understand what a function does based on the call site. [source]
- 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 only (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] - 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;
- When you need to modify an immutable object we actually return a new object
-
Dependencies
- All services should get all their dependencies and configuration values injected as constructor arguments. Following this rule ensures that you’ll never fetch a service ad hoc, e.g. by using Container::get(UserRepository::class). This is needed for framework decoupling because the global static facility that returns the service for you is by definition framework-specific. The same is true for fetching configuration values (e.g. Config::get(’email.default_sender’)). [Matthias Noback]
- When a dependency uses IO (the database, the filesystem, etc.), you have to introduce an abstraction for it. If you depend on a concrete class, that class will work only with the specific library or framework that you’re working with right now, so in order to stay decoupled you should use your own abstraction, combined with an implementation that uses your current library/framework. [Matthias Noback]
- Other types of objects shouldn’t have service responsibilities. [Matthias Noback]
- Contextual information should always be passed as method arguments. Instead of fetching this data whenever you need it (like Auth::getUser()->getId()) you should pass it from method to method as a regular argument. [Matthias Noback]
-
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]
- BRs applicable to a Domain Object must be enforced by the object itself. For
-
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]
- Start modeling the domain by defining the use cases (ie
-
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. Суть принципа инверсии зависимостей проста: заменить композицию агрегацией. То есть вместо создания зависимостей напрямую, класс должен требовать их у более высокого уровня через аргументы метода или конструктора. При этом зависимость должна передаваться не в виде экземпляров конкретных классов, а в виде интерфейсов или абстрактных классов. [Sergey Teplyakov]
- 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
- DI vs. DIP vs. IoC [Sergey Teplyakov]
- 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
-
Внедрение зависимости (Dependency injection, DI)
- Какое главное отличие Dependency Injection от Service Locator? [habr.com]
-
Talks
- Don’t Be STUPID GRASP SOLID – 2013 – Anthony Ferrara (slides)
-
Object-Oriented Programming
- Наследование (Inheritance)
- Композиция или наследование: как выбрать? [habr.com]
- Полиморфизм (Polymorphism)
- Полиморфизм простыми словами [medium.com]
- Полиморфизм [wikipedia]
- Инкапсуляция (Encapsulation)
- Interfaces
- Для чего нужны интерфейсы? [Sergey Teplyakov]
- Abstract class
- Composition
- Композиция или наследование: как выбрать? [habr.com]
- Reading
- 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
- Наследование (Inheritance)
-
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
- Patterns
- Active Record
- Chain of Responsibility (Цепочка обязанностей)
- Middleware и возможности Pipeline в Laravel (habr.com)
- 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
- Patterns
-
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
- Project structure
- 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
-
-
PHP
- Как устроены переменные в PHP [habr.com, 2021]
-
REST
-
Microservices
- Cheat Sheets
- Micro-Services – Martin Fowler
-
Frameworks
-
Laravel
- Используем IoC-контейнер Laravel на полную мощность [habr.com]
-
Symfony
- Приложение Symfony2 в разрезе [habr.com]
- Workflow Component
- Symfony Workflow component. Область применения. Опыт использования. [Алексей Медведев]
- Сети Петри с Symfony а-ля WorkFlow компонент [habr.com]
-
-
MySQL
- Читаем EXPLAIN на максималках [habr.com]
-
Redis
- Redis на практических примерах [habr.com]
- Redis + Laravel: Storing and retrieving objects [42mate.com]
-
Kafka vs RabbitMQ
- RabbitMQ против Kafka: два разных подхода к обмену сообщениями [habr.com]
-
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)
- 20 вещей, которые я узнал за 20 лет работы инженером-программистом [habr.com]
- 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
- Design Patterns: Elements of Reusable Object-Oriented Software, 1994 – Erich Gamma, Richard Helm, Ralph Johnson, John Vlisside. В этой книге описаны 23 шаблона проектирования. Также команда авторов этой книги известна общественности под названием «Банда четырёх» (англ. Gang of Four, часто сокращается до GoF). Именно эта книга стала причиной роста популярности шаблонов проектирования.
- 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
-
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
_________