A short excursion into the history of programming, on a way to understanding its fundamental concepts This is the first post on principles and what values and principles they all have in common. SOLID 1972, David Parnas Back in 1972, , a man behind the concepts of encapsulation and , wrote his famous paper called . There he elaborated on criteria to be used when deciding which pieces of code should reside together and which should be separate. David Parnas modular programming “On the Criteria To Be Used in Decomposing Systems into Modules” What was so revolutionary in Parnas’ paper? What is it basically about? Well, it’s about two related things. What it is about First, it’s about choosing right concepts to operate upon. On domain level, these are the concepts of your . These concepts are in high degree independent of each other. When you talk about purchasing an item, you don’t think about how it’s stored. The implementation of these concepts should be independent of each other as well.On the infrastructure level, these are the main technical decisions you’ve made. All the code that works with a database should not be spread all over a project. It’s definitely a single module. problem space Second, it’s encapsulation. When properly decomposed domain concepts are modeled, they should not indulge spreading their implementation details all over a codebase. It’s more like a consequence of a previous point. This principle is applicable at all levels, not just on a module level. It’s about classes and as well. services First, if you need to make some change, with this approach it’s more likely that it would be confined within a clearly defined and comprehensible area. You won’t need to fix half of all your project classes. If you change the way an item is purchased, you won’t have to modify code responsible for storing it. If you change your database, you won’t have to fix every single place that uses a database’s capabilities. Profits Second, it’s apprehensibility. Every piece of code has some clear purpose. 1979, Yordon and Constantine Later in 1979, Yordon and Constantine coined the term of in their book . It went like cohesion “Structured Design: Fundamentals of a Discipline of Computer Program and Systems Design” degree to which the elements inside a belong together module Wikipedia elaborates on it a bit: In one sense, it is a measure of the strength of relationship between the methods and data of a class and some unifying purpose or concept served by that class. In another sense, it is a measure of the strength of relationship between the class’s methods and data themselves. It brings us to the first point: there should be only one such purpose. The second point is more subtle. It’s about conforming a class name to its responsibilities: the abstraction level of these two should match. Here is an example I gave to a relevant question on , that illustrates the violation of the second point: softwareengineering q&a site class Car{ public function __construct() { } public function drive() { // } public function giveFuelToEngine() { }} ’s responsibility, its main purpose — driving — doesn’t correlate to abstraction level of the method Hence different reasons to change. Car giveFuelToEngine. 2003, Robert Martin In 2003, Robert Martin in his book stated the : “ ” Agile Software Development, Principles, Patterns, and Practices Single Responsibility Principle A class should have only one reason to change. Wikipedia says that Martin based this principle on cohesion, inspired by book. I doubt that. Tom DeMarco took data-centric approach, where data flow is the primary concern. So the cohesion there is just a means for enabling , which is fine nevertheless. Structured Analysis and System Specification functional decomposition 2004, Eric Evans Eric Evans, in his book , introduced the concept of an . It’s a set of objects that can be treated as a single unit. It has one prominent feature: aggregates can refer to each other only by an . And keeping in mind the fact that one can not pass any repositories to it, it’s easy to conclude that there is no way for an aggregate to operate upon other aggregates within its boundaries. Their communication can be only via events. “ ” Domain-Driven Design: Tackling Complexity in the Heart of Software aggregate identificator This approach promotes the creation of really cohesive domain concepts, which besides that have explicit boundaries. Here is where cohesion met encapsulation. Wrapping it up So if a class is cohesive, if there is a single higher-level purpose, if its responsibilities conform to its name, the SRP would come out naturally. SRP is just a practical consequence, it’s not a goal by itself. and endowing it with is. Moreover, the whole is just simplified implementational consequence of fundamental OO principles. It’s just a form, not the essence. The cohesive object identifying correct responsibilities SOLID