OOP's SOLID Principles vs Functional Programming

[)roi(]

Executive Member
Joined
Apr 15, 2005
Messages
6,282
Reaction score
405
Location
SOLID
In object-oriented computer programming, SOLID is a mnemonic acronym for five design principles intended to make software designs more understandable, flexible and maintainable. It is not related to the GRASP software design principles. The principles are a subset of many principles promoted by American software engineer and instructor Robert C. Martin.
Though they apply to any object-oriented design, the SOLID principles can also form a core philosophy for methodologies such as agile development or adaptive software development. The theory of SOLID principles was introduced by Martin in his 2000 paper Design Principles and Design Patterns, although the SOLID acronym was introduced later by Michael Feathers.

Single responsibility principle
A class should only have a single responsibility, that is, only changes to one part of the software's specification should be able to affect the specification of the class.

SRP if taken to its logical conclusion would result in a class that would resemble a classical record structure. I.e. An encapsulation of only properties / fields and not a container of multiple testable code units with related features e.g. constructors, member functions, ...
Further more the SRP implication is that member functions should be defined as standalone functions because they too should only have a 1 reason to be changed.

This is likely the most contentious topic in this post because many OOP programmers would argue that they are using a class to group related computations; when arguably it is that approach that most directly subverts adherence to SRP and makes classes inherently more difficult to test than simple record structures and standalone functions.

Essentially a more strict adherence to SRP would result in not only a class that is not only more easy to test, but also result in a set of related functions that have a much more clear API; one where all inputs and outputs are clearly defined; and one which arguably leads to a greater adoption of immutability and purity.


Open–closed principle
"Software entities ... should be open for extension, but closed for modification."

OCP implies that we should endeavor to build an API that's easy to extend without the need to modify the internal workings of the API that we are using as a building block. This is a natural occurrence in functional code; which promotes functions that easily compose; are easy to extend through embracing of higher order functions which don't bake in limitations of the internal computation nor the input and/or output of the API; by building APIs that embrace polymorphism by employing generic type place holders for data types, higher order functions, etc.

Liskov substitution principle
"Objects in a program should be replaceable with instances of their subtypes without altering the correctness of that program."

Functional programming has a natural embrace of LSP, in that every monadic type shares a common set of APIs by employing polymorphism of a higher kind or HKTs, making the substitution of one type container for another a relatively seamless process; and where HKTs are not available the discipline of a manually creating a common API is the norm.
Similarly it is a common practice to create functions that embrace polymorphic types (aka generics) to ensure that one set of inputs can seamlessly be substituted for another without any changes to both the underlying code or the code be substituted. Further more the adoption of parameter flipping, partial application, currying techniques among others enable the functional API to morph to fit a veritable variety of requirements.


Interface segregation principle
"Many client-specific interfaces are better than one general-purpose interface."

ISP is similarly the default approach in functional code, because it's the very nature of functional algebras to abstract on the small instead of the large. Practice and experience both in functional programming and mathematics (e.g. calculus, category theory, ...) has proved that a simple API is far more versatile and extensible than a complex API

It is why many standard functional algebras (patterns) like functor (Map / Select) are built for single parameter functions; how ever with techniques like partial application, currying, ... they are able to morph to cater for most any scenario, including multiple parameter functions.

E.g. It's very easy to create a composition of single parameter functions; but an impossibility with 2 or more parameter functions unless techniques like partial application, currying, parameter flipping, ... are employed.



Dependency inversion principle
One should "depend upon abstractions, [not] concretions

DIP comes natural to functional programming; abstractions are the default approach in functional programming; from polymorphic embracing data types to higher order functions, to the embracing of abstract algebras in common interfaces to avoid repetition on the small and to embrace the adoption of a more declarative enabling API.



Related principles to simplify design
DRY
The same conclusions apply to other design principles like KISS (keep it simple, stupid), DRY (Don't Repeat Yourself),

KISS
The KISS principle states that most systems work best if they are kept simple rather than made complicated; therefore, simplicity should be a key goal in design, and unnecessary complexity should be avoided.

DRY
Don't repeat yourself (DRY, or sometimes do not repeat yourself) is a principle of software development aimed at reducing repetition of software patterns, replacing it with abstractions or using data normalization to avoid redundancy.

Package Principles
In computer programming, package principles are a way of organizing classes in larger systems to make them more organized and manageable. They aid in understanding which classes should go into which packages (package cohesion) and how these packages should relate with one another (package coupling). Package principles also includes software package metrics, which help to quantify the dependency structure, giving different and/or more precise insights into the overall structure of classes and packages

YAGNI
You aren't gonna need it" is a principle of extreme programming (XP) that states a programmer should not add functionality until deemed necessary. XP co-founder Ron Jeffries has written: "Always implement things when you actually need them, never when you just foresee that you need them." Other forms of the phrase include "You aren't going to need it" and "You ain't gonna need it".


Conclusion
One could posit that through principles like SOLID, object orientated programmers are essentially striving to create code that in practice behaves a lot more like functional code.

Similarly functional programming techniques of abstracting on the small promotes a natural adoption of DRY, KISS, Package Principles, YAGNI, ...


Note:
For the most part the description of the principles are exact copy / paste of the summations on Wikipedia
 
Last edited:
Top
Sign up to the MyBroadband newsletter
X