As many of you already know, Clean Code Studio is also a YouTube channel.
- Comments, ever get 'em? ------> Tons!
Now and again a comment will come in that PROVOKES the living HELL out of me.
You know which one I mean?
A đĽ under your a** is lit, your inner Shakespearian rockets from the abyss of your sub-conscience, and WHAMMMYY!!!
Before you know it, you've written the greatest monologue since Hamlet's "To Be Or Not To Be" spiel.
A while back, one of those provoking comments came up.
Check it...I've posted the comment and my Shakespearian monologue of a response below.
My Reply [To why use interfaces]
("Interfaces, why use them?" - A Shakespearian Monologue)
That's a verrryy reasonable perspective that I respect quite a bit.
Given this series wasn't an extremely in depth overview covering the reasons behind WHY interfaces and abstract classes are useful for implementing design principles -- I highly recommend you checkout our SOLID principles series and specifically the lesson diving into the Open Closed Principle.
Personally, the fact that you challenge adding seemingly needless code is awesome - in my opinion. I'm with you, and whenever possible, opt out of adding needless code if it isn't necessary.
In the lessons offered through out this object oriented PHP, we're covering the very basics.
We only cover HOW to implement concepts like abstract classes and interfaces.
In this OOP PHP series we also, very deliberately, avoid many of the WHY questions behind using object oriented concepts like abstract classes and interfaces.
Here's a quick "why interfaces" example.
Example:
1. Imagine we have 3 classes
Class CsvFile
{
}
class JsonFile
{
}
class HtmlFile
{
}
2. Imagine we have a parse function
function parse ($file)
{
if (is_a ($file, 'CsvFile') {
// parse csv file
}
else if (is_a($file, 'JsonFile')) {
// parse json file
}
else if (is_a($file, 'HtmlFile')) {
// parse html file
}
}
php
Note: Any time we add a new file type, we have to find our parse function and add a new else if conditional to parse the given file type.
3. Imagine we have a file interfaces
interface File
{
public function parse();
}
class CsvFile implements File {}
class JsonFile implements File {}
class HtmlFile implements File {}
Note: Currently Everything breaks because each of our classes implements a given interface
but none actually has the parse method. Interfaces contractually obligate
Classes to implement methods.
4. Correctly Implement File Interface
class CsvFile implements File
{
public function parse() {
// parse csv file
}
}
class JsonFile implements File {
public function parse() {
// parse json file
}
}
class HtmlFile implements File {
public function parse() {
// parse html file
}
}
- Refactor the parse method
function parse(File $file)
{
$file->parse();
}
Note: Each class implements the file interface. This forces each class to Have a parse method. The parse(File $file) function accepts an instance that implements the _File Interface.
This means we know that the $file
passed in can parse()
even if we don't know exactly how it will parse.
Each class implementing the File Interface is contractually bound to implement their own parse method. Each class implement the File Interface defines how it will parse itself.
In the short term, this does lead to more verbose code. In fact, if you do only have two or three file types and absolutely never need to add any more file types I would recommend sticking with else if conditionals.
That being said, if you are unsure how many file types there will be in the future then I recommend using interfaces.
That way, you only have to create a new class and implement the given interface. You don't have to add a new class (SqlFile Class for example) and then update the parse function with another if else conditional because you removed a dependency from your code depending on an interface.
Design principles in software are recommendations for best practices, but by no means are they absolutes for designing the cleanest most simplified code.
In the short run, they usually add verbosity - it's up to you as the software engineer to decide if you need to plan for the long run and implement interfaces and specific design principles that'll use interfaces to force functions to be implemented or if this is the last time you'll ever need to change this code and if else conditionals are the simplest way to create your software.
Context, attentive care, and intuition based on experience are by far more important than any design principles.
The catch is understanding the purpose behind interface, abstract classes, and the design principles they allow you to implement are necessary to learn if you truly want to make the best decision based on the context of your problem.
Sometimes interfaces are incredible sometimes they are not. Understanding how, why, and when they are valuable or inhibiting gives you the control to make the best decision based on the context of your software.
Understanding visual simplicity vs. longer term architecture requirements as well as design principles best fit to meet longer term architecture requirements gives you contextual understanding of your software.
Contextual understanding along with intimate care and a love for simplifying - together - make great software engineers and helps build world shifting applications.
Top comments (2)
Well the point is, "patterns" and other such abstractions should ONLY be used when they're useful and necessary, but some people (not the author!) are adding interfaces everywhere "because they can", even when there's no reason.
It's called overengineering, and it's a main reason why many people came to dislike Java as a programming language (the Java world is pretty fanatic about adding tons of abstraction layers all over the place, whether it's useful or not).
So I say yes, do keep SOLID in mind and make sure you understand its principles, but there are many 'simple' scenarios where you can code it in the simplest way possible and where that would actually be the way to go.
Nice! This is one of the best examples I have come across on why interfaces are useful. Thanks