A Software Entity Should Have
One and Only One Reason to Change
As stated by Steve McConnell in his updated
Code Complete 2: A Practical Handbook of Software Construction:
“Software’s Primary Technical Imperative: Managing Complexity”
Software is inherently complex by nature.
The Single Responsibility Principle, or SRP, states that the responsibility of a software entity, generally Classes, Struts, Interfaces and Class Methods should be a single, well-defined State or Behavior function.
It should be clear the viewer of the entity code the “What” and the “How” of the entity.
SRP helps to manage complexities in the design by encapsulating the design into manageable entities that can be understood much easier.
Large code files with Properties, Methods, nested Classes and Enums that support numerous responsibilities becomes difficult to manage over the life cycle of the code.
It cost money for developers to understand exactly what to change when a new feature or function change request is received.
In addition to those concerns, the chance of regressive testing issues is much greater when a multiple responsibility code file is touched.
You can easily break a part of some responsibility in the code that interacts with your change without even knowing about that responsibility.
When Creating a New Software Code Files
… it is the Primary Technical Imperative of the Developer
…… to Manage the Complexity of the New Software Entity Type
The developer must clearly define the purpose of the new type
By complying with the Responsibility and Dependencies Principle (RDP) and the Single Responsibility Principle (SRP) the complexity of the assembly will be maintained at a lower cost of ownership throughout the life cycle of the assembly.
The Software Elements
CLASSES – All members of a class should have an “Is A” relationship to the name of the class.
All Classes should be in a unique Namespace that follows the directory structure of the assembly.
File names are the same as the Class name and should be a Noun that describes the function of the responsibility of that class.
A Developer should be able to abstract away the “How” of an assembly simply by viewing the folder structure of an assembly.
It should represent the Object Model of the assembly and preview the responsibilities of the assembly within the folder structure and naming conventions of the Classes.
METHODS – All methods should be lean.
Only the code that acts to perform the responsibility defined by the signature of the Method should be in the code body.
Method signatures should support some behavior that represents the Class responsibility directly.
Any supporting functional requirements such as algorithms, dependency calls or complex logic decisions should be seen as a dependency to the Class’s responsibility.
These code blocks should be refactored into a Static Private Class-level Helper Method if it only has value only to this class entity.
The Helper Method should be refactored into a Common Helpers Assembly that can support other Class responsibilities as a Public Helper Instance Class Method.
Each helper method should perform a single behavior action that complies with SRP.
INTERFACES – All Interfaces should define a contract for implementing Classes and Struts that support the single responsibility of that Class or Strut.
Software entities should not have to implement Interface contracts that they do not need.
This is the Interface Segregation Principle (ISP) in S.O.L.I.D Design Principles.
Interfaces should be lean.
They should contain Methods, Properties, Indexers and Events that supports the Single Responsibility of the consuming Class or Strut.
If when you implement an Interface and Visual Studio or ReSharper should create code stub that represents a related responsibility function.
PUBLIC HELPER CLASSES and PRIVATE HELPER METHODS – Helpers that have a one and only one dependency to a consuming Class should be private static methods encapsulated within the Class using Regions for easy reading.
Helpers that have a more than one dependency possibility should be refactored into a Common Assembly for code reuse by other Entity types as Utility Classes.
Helper Classes, such as Utility Classes, should be of Static and be public accessible.
The Single Responsibility Principle Gives Us the Tool We Need
… To Manage the Complexity of Software Development
…… By Clearly Defining the Goals of a Software Entity.
The following two tabs change content below.
I am a Principal Architect at Liquid Hub in the Philadelphia area specializing in Agile Practices as a Certified Scrum Master (CSM). I use Test Driven Development (TDD) and Acceptance Test Driven Development (ATDD) with Behavior Driven Development (BDD) as my bridge to Agile User Stories Acceptance Criteria in a Domain Driven Design (DDD) implementing true RESTful services