Hello everyone, this article I would like to present the knowledge about SOLID that I have learned, I look forward to your follow-up.
1) What is SOLID?
- SOLID is the five basic principles in object-oriented software design, making the code easier to understand, flexible and maintainable.
- The author of SOLID is a famous software engineer, Robert C. Martin.
- SOLID is the following 5 principles in object-oriented design:
- 12S - Single-responsiblity principle
- 12O - Open-closed principle
- 12L - Liskov substitution principle
- 12I - Interface segregation principle
- 12D - Dependency Inversion Principle
1.1) S – Single-responsiblity principle
A class should only have one reason to change, meaning that the class is only responsible for a certain job.
For example
1 2 3 4 5 6 7 | <span class="token keyword">class</span> <span class="token class-name">ReportManager</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">public</span> <span class="token keyword">function</span> <span class="token function">ReadDataFromDB</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token punctuation">}</span> <span class="token punctuation">;</span> <span class="token keyword">public</span> <span class="token keyword">function</span> <span class="token function">ProcessData</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token punctuation">}</span> <span class="token punctuation">;</span> <span class="token keyword">public</span> <span class="token keyword">function</span> <span class="token function">PrintReport</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token punctuation">}</span> <span class="token punctuation">;</span> <span class="token punctuation">}</span> |
- This class holds up to 3 responsibilities: Read data from the DB, process data, print results. As long as we change the database, change the way we print the results, we will have to modify this class. Later, the class will become bigger and bigger and harder to manage.
- In principle, we have to separate this class into 3 separate classes. While the number of classes is greater than the number of repairs it will be simpler, the class is shorter so there are fewer bugs.
1.2) O – Open-closed principle
Do not modify an existing Class, but you can extend it by inheriting
For example
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 | <span class="token keyword">class</span> <span class="token class-name">Circle</span> <span class="token punctuation">{</span> <span class="token keyword">public</span> <span class="token variable">$radius</span> <span class="token punctuation">;</span> <span class="token keyword">public</span> <span class="token keyword">function</span> <span class="token function">__construct</span> <span class="token punctuation">(</span> <span class="token variable">$radius</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token variable">$this</span> <span class="token operator">-</span> <span class="token operator">></span> <span class="token property">radius</span> <span class="token operator">=</span> <span class="token variable">$radius</span> <span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token keyword">class</span> <span class="token class-name">Square</span> <span class="token punctuation">{</span> <span class="token keyword">public</span> <span class="token variable">$length</span> <span class="token punctuation">;</span> <span class="token keyword">public</span> <span class="token keyword">function</span> <span class="token function">__construct</span> <span class="token punctuation">(</span> <span class="token variable">$length</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token variable">$this</span> <span class="token operator">-</span> <span class="token operator">></span> <span class="token property">length</span> <span class="token operator">=</span> <span class="token variable">$length</span> <span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token keyword">class</span> <span class="token class-name">AreaCalculator</span> <span class="token punctuation">{</span> <span class="token keyword">protected</span> <span class="token variable">$shapes</span> <span class="token punctuation">;</span> <span class="token keyword">public</span> <span class="token keyword">function</span> <span class="token function">__construct</span> <span class="token punctuation">(</span> <span class="token variable">$shapes</span> <span class="token operator">=</span> <span class="token keyword">array</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token variable">$this</span> <span class="token operator">-</span> <span class="token operator">></span> <span class="token property">shapes</span> <span class="token operator">=</span> <span class="token variable">$shapes</span> <span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">public</span> <span class="token keyword">function</span> <span class="token function">sum</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">foreach</span> <span class="token punctuation">(</span> <span class="token variable">$this</span> <span class="token operator">-</span> <span class="token operator">></span> <span class="token property">shapes</span> <span class="token keyword">as</span> <span class="token variable">$shape</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">if</span> <span class="token punctuation">(</span> <span class="token function">is_a</span> <span class="token punctuation">(</span> <span class="token variable">$shape</span> <span class="token punctuation">,</span> <span class="token single-quoted-string string">'Square'</span> <span class="token punctuation">)</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token variable">$area</span> <span class="token punctuation">[</span> <span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token function">pow</span> <span class="token punctuation">(</span> <span class="token variable">$shape</span> <span class="token operator">-</span> <span class="token operator">></span> <span class="token property">length</span> <span class="token punctuation">,</span> <span class="token number">2</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">else</span> <span class="token keyword">if</span> <span class="token punctuation">(</span> <span class="token function">is_a</span> <span class="token punctuation">(</span> <span class="token variable">$shape</span> <span class="token punctuation">,</span> <span class="token single-quoted-string string">'Circle'</span> <span class="token punctuation">)</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token variable">$area</span> <span class="token punctuation">[</span> <span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token function">pi</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token operator">*</span> <span class="token function">pow</span> <span class="token punctuation">(</span> <span class="token variable">$shape</span> <span class="token operator">-</span> <span class="token operator">></span> <span class="token property">radius</span> <span class="token punctuation">,</span> <span class="token number">2</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token keyword">return</span> <span class="token function">array_sum</span> <span class="token punctuation">(</span> <span class="token variable">$area</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> |
Suppose if you want the sum () method to be able to sum the area of other images as well, then we have to add some more if / else so that it violates the Open-closed principle. To solve the problem we put the sum () function and in the class definition of each image.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 | <span class="token keyword">class</span> <span class="token class-name">Square</span> <span class="token punctuation">{</span> <span class="token keyword">public</span> <span class="token variable">$length</span> <span class="token punctuation">;</span> <span class="token keyword">public</span> <span class="token keyword">function</span> <span class="token function">__construct</span> <span class="token punctuation">(</span> <span class="token variable">$length</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token variable">$this</span> <span class="token operator">-</span> <span class="token operator">></span> <span class="token property">length</span> <span class="token operator">=</span> <span class="token variable">$length</span> <span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">public</span> <span class="token keyword">function</span> <span class="token function">area</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> <span class="token function">pow</span> <span class="token punctuation">(</span> <span class="token variable">$this</span> <span class="token operator">-</span> <span class="token operator">></span> <span class="token property">length</span> <span class="token punctuation">,</span> <span class="token number">2</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token keyword">class</span> <span class="token class-name">Circle</span> <span class="token punctuation">{</span> <span class="token keyword">public</span> <span class="token variable">$radius</span> <span class="token punctuation">;</span> <span class="token keyword">public</span> <span class="token keyword">function</span> <span class="token function">__construct</span> <span class="token punctuation">(</span> <span class="token variable">$radius</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token variable">$this</span> <span class="token operator">-</span> <span class="token operator">></span> <span class="token property">radius</span> <span class="token operator">=</span> <span class="token variable">$radius</span> <span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">public</span> <span class="token keyword">function</span> <span class="token function">area</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> <span class="token function">pi</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token operator">*</span> <span class="token function">pow</span> <span class="token punctuation">(</span> <span class="token variable">$this</span> <span class="token operator">-</span> <span class="token operator">></span> <span class="token property">radius</span> <span class="token punctuation">,</span> <span class="token number">2</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token keyword">class</span> <span class="token class-name">AreaCalculator</span> <span class="token punctuation">{</span> <span class="token keyword">protected</span> <span class="token variable">$shapes</span> <span class="token punctuation">;</span> <span class="token keyword">public</span> <span class="token keyword">function</span> <span class="token function">__construct</span> <span class="token punctuation">(</span> <span class="token variable">$shapes</span> <span class="token operator">=</span> <span class="token keyword">array</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token variable">$this</span> <span class="token operator">-</span> <span class="token operator">></span> <span class="token property">shapes</span> <span class="token operator">=</span> <span class="token variable">$shapes</span> <span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">public</span> <span class="token keyword">function</span> <span class="token function">sum</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">foreach</span> <span class="token punctuation">(</span> <span class="token variable">$this</span> <span class="token operator">-</span> <span class="token operator">></span> <span class="token property">shapes</span> <span class="token keyword">as</span> <span class="token variable">$shape</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token variable">$area</span> <span class="token punctuation">[</span> <span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token variable">$shape</span> <span class="token operator">-</span> <span class="token operator">></span> <span class="token function">area</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">return</span> <span class="token function">array_sum</span> <span class="token punctuation">(</span> <span class="token variable">$area</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> |
This will make the totals easier and more scalable. For example, if you want to calculate the total area with a triangle, we will create a Triangle class for the triangle without changing the calculation class content. However, suppose the object passed to AreaCalculator is not an instance of the image classes and if it is already an image, does it have an area method? To solve this problem we create an interface where the The image class will implement this interface
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | <span class="token keyword">interface</span> <span class="token class-name">ShapeInterface</span> <span class="token punctuation">{</span> <span class="token keyword">public</span> <span class="token keyword">function</span> <span class="token function">area</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">class</span> <span class="token class-name">Circle</span> <span class="token keyword">implements</span> <span class="token class-name">ShapeInterface</span> <span class="token punctuation">{</span> <span class="token keyword">public</span> <span class="token variable">$radius</span> <span class="token punctuation">;</span> <span class="token keyword">public</span> <span class="token keyword">function</span> <span class="token function">__construct</span> <span class="token punctuation">(</span> <span class="token variable">$radius</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token variable">$this</span> <span class="token operator">-</span> <span class="token operator">></span> <span class="token property">radius</span> <span class="token operator">=</span> <span class="token variable">$radius</span> <span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">public</span> <span class="token keyword">function</span> <span class="token function">area</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> <span class="token function">pi</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token operator">*</span> <span class="token function">pow</span> <span class="token punctuation">(</span> <span class="token variable">$this</span> <span class="token operator">-</span> <span class="token operator">></span> <span class="token property">radius</span> <span class="token punctuation">,</span> <span class="token number">2</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> |
Then in the AreaCalculator class in sum () method we check if the given image is not an instance of ShapeInterface then fires the error:
1 2 3 4 5 6 7 8 9 10 11 | <span class="token keyword">public</span> <span class="token keyword">function</span> <span class="token function">sum</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">foreach</span> <span class="token punctuation">(</span> <span class="token variable">$this</span> <span class="token operator">-</span> <span class="token operator">></span> <span class="token property">shapes</span> <span class="token keyword">as</span> <span class="token variable">$shape</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">if</span> <span class="token punctuation">(</span> <span class="token function">is_a</span> <span class="token punctuation">(</span> <span class="token variable">$shape</span> <span class="token punctuation">,</span> <span class="token single-quoted-string string">'ShapeInterface'</span> <span class="token punctuation">)</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token variable">$area</span> <span class="token punctuation">[</span> <span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token variable">$shape</span> <span class="token operator">-</span> <span class="token operator">></span> <span class="token function">area</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token keyword">continue</span> <span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">throw</span> <span class="token keyword">new</span> <span class="token class-name">AreaCalculatorInvalidShapeException</span> <span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">return</span> <span class="token function">array_sum</span> <span class="token punctuation">(</span> <span class="token variable">$area</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token punctuation">}</span> |
1.3) L – Liskov substitution principle
In a program, objects of subclasses can replace the parent class without changing the correctness of the program
For example
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 | <span class="token keyword">class</span> <span class="token class-name">Rectangle</span> <span class="token punctuation">{</span> <span class="token keyword">public</span> <span class="token variable">$width</span> <span class="token punctuation">;</span> <span class="token keyword">public</span> <span class="token variable">$height</span> <span class="token punctuation">;</span> <span class="token keyword">public</span> <span class="token keyword">function</span> <span class="token function">setWidth</span> <span class="token punctuation">(</span> <span class="token variable">$width</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token variable">$this</span> <span class="token operator">-</span> <span class="token operator">></span> <span class="token property">width</span> <span class="token operator">=</span> <span class="token variable">$width</span> <span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">public</span> <span class="token keyword">function</span> <span class="token function">setHeight</span> <span class="token punctuation">(</span> <span class="token variable">$height</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token variable">$this</span> <span class="token operator">-</span> <span class="token operator">></span> <span class="token property">height</span> <span class="token operator">=</span> <span class="token variable">$height</span> <span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">public</span> <span class="token keyword">function</span> <span class="token function">area</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> <span class="token variable">$this</span> <span class="token operator">-</span> <span class="token operator">></span> <span class="token property">width</span> <span class="token operator">*</span> <span class="token variable">$this</span> <span class="token operator">-</span> <span class="token operator">></span> <span class="token property">height</span> <span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token keyword">class</span> <span class="token class-name">Square</span> <span class="token keyword">extends</span> <span class="token class-name">Rectangle</span> <span class="token punctuation">{</span> <span class="token keyword">public</span> <span class="token keyword">function</span> <span class="token function">setWidth</span> <span class="token punctuation">(</span> <span class="token variable">$width</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token variable">$this</span> <span class="token operator">-</span> <span class="token operator">></span> <span class="token property">width</span> <span class="token operator">=</span> <span class="token variable">$width</span> <span class="token punctuation">;</span> <span class="token variable">$this</span> <span class="token operator">-</span> <span class="token operator">></span> <span class="token property">height</span> <span class="token operator">=</span> <span class="token variable">$width</span> <span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">public</span> <span class="token keyword">function</span> <span class="token function">setHeight</span> <span class="token punctuation">(</span> <span class="token variable">$height</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token variable">$this</span> <span class="token operator">-</span> <span class="token operator">></span> <span class="token property">width</span> <span class="token operator">=</span> <span class="token variable">$height</span> <span class="token punctuation">;</span> <span class="token variable">$this</span> <span class="token operator">-</span> <span class="token operator">></span> <span class="token property">height</span> <span class="token operator">=</span> <span class="token variable">$height</span> <span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token variable">$rect</span> <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Rectangle</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token variable">$rect</span> <span class="token operator">-</span> <span class="token operator">></span> <span class="token function">setWidth</span> <span class="token punctuation">(</span> <span class="token number">5</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token variable">$rect</span> <span class="token operator">-</span> <span class="token operator">></span> <span class="token function">setHeight</span> <span class="token punctuation">(</span> <span class="token number">10</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token keyword">echo</span> <span class="token variable">$rect</span> <span class="token operator">-</span> <span class="token operator">></span> <span class="token function">area</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token comment">// Kết quả là 5 * 10</span> <span class="token variable">$square</span> <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Square</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token variable">$square</span> <span class="token operator">-</span> <span class="token operator">></span> <span class="token function">setWidth</span> <span class="token punctuation">(</span> <span class="token number">5</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token variable">$square</span> <span class="token operator">-</span> <span class="token operator">></span> <span class="token function">setHeight</span> <span class="token punctuation">(</span> <span class="token number">10</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token keyword">echo</span> <span class="token variable">$square</span> <span class="token operator">-</span> <span class="token operator">></span> <span class="token function">area</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> |
- Result 10 * 10, so the class Square has modified the definition of the parent class Rectangle
- Looking at the example above, we can see that all calculations are reasonable. Because the square has two equal sides, every time a set length is set, the length of the other side is always set.
- However, Class Square inherited from Rectangle class, but Square class has other micro images and it changed the behavior of Rectangle class, resulting in LSP violation.
- In this case, so that the code does not violate the LSP principle, we must create a parent class Shape class, then let Square and Rectangle inherit this Shape class.
1.4) I – Interface segregation principle
Instead of using a large interface, we should split into many small interfaces, with many specific purposes.
For example
For example, if we want to calculate the volume of a shape, we can include it in ShapeInterface:
1 2 3 4 5 | <span class="token keyword">interface</span> <span class="token class-name">ShapeInterface</span> <span class="token punctuation">{</span> <span class="token keyword">public</span> <span class="token keyword">function</span> <span class="token function">area</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token keyword">public</span> <span class="token keyword">function</span> <span class="token function">volume</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token punctuation">}</span> |
Now any image created must implement the volume () method, but as we all know, flat geometry will not be able to calculate the volume so they don’t have a volume, so this interface Forcing the Square class to implement a method that does not use it will go against this principle instead we create a new interface called SolidShapeInterface that has a volume method
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | <span class="token keyword">interface</span> <span class="token class-name">ShapeInterface</span> <span class="token punctuation">{</span> <span class="token keyword">public</span> <span class="token keyword">function</span> <span class="token function">area</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">interface</span> <span class="token class-name">SolidShapeInterface</span> <span class="token punctuation">{</span> <span class="token keyword">public</span> <span class="token keyword">function</span> <span class="token function">volume</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token comment">// Lớp hình hộp chữ nhật thực hiện cả hai interface</span> <span class="token keyword">class</span> <span class="token class-name">Cuboid</span> <span class="token keyword">implements</span> <span class="token class-name">ShapeInterface</span> <span class="token punctuation">,</span> SolidShapeInterface <span class="token punctuation">{</span> <span class="token keyword">public</span> <span class="token keyword">function</span> <span class="token function">area</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment">// Tính toán diện tích bề mặt hình hộp chữ nhật</span> <span class="token punctuation">}</span> <span class="token keyword">public</span> <span class="token keyword">function</span> <span class="token function">volume</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment">// Tính toán thể tích hình hộp chữ nhật</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> |
1.5) D – Dependency Inversion Principle
System components (classes, modules, etc.) should only depend on abstractions, not specific concretions or implementations.
Interface should not depend on details, but vice versa. (Classes communicate with each other through interfaces, not implementations)
For example
1 2 3 4 5 6 7 8 | <span class="token keyword">class</span> <span class="token class-name">PasswordReminder</span> <span class="token punctuation">{</span> <span class="token keyword">private</span> <span class="token variable">$dbConnection</span> <span class="token punctuation">;</span> <span class="token keyword">public</span> <span class="token keyword">function</span> <span class="token function">__construct</span> <span class="token punctuation">(</span> MySQLConnection <span class="token variable">$dbConnection</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token variable">$this</span> <span class="token operator">-</span> <span class="token operator">></span> <span class="token property">dbConnection</span> <span class="token operator">=</span> <span class="token variable">$dbConnection</span> <span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> |
We see that the PasswordReminder class is a higher class than the MySQLConnection class that violates D in SOLID because PasswordReminder is forced to depend on the MySQLConnection class. Suppose later you want to change another database, we have to modify the PasswordReminder class so it will violate the Open-closed principle. To solve the problem we create a new interface
1 2 3 4 | <span class="token keyword">interface</span> <span class="token class-name">DBConnectionInterface</span> <span class="token punctuation">{</span> <span class="token keyword">public</span> <span class="token keyword">function</span> <span class="token function">connect</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token punctuation">}</span> |
This interface has a connect method and the MySQLConnection class implements this interface instead of using MySQLConnection in the contructor of PasswordReminder.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | <span class="token keyword">class</span> <span class="token class-name">MySQLConnection</span> <span class="token keyword">implements</span> <span class="token class-name">DBConnectionInterface</span> <span class="token punctuation">{</span> <span class="token keyword">public</span> <span class="token keyword">function</span> <span class="token function">connect</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> <span class="token double-quoted-string string">"Database connection"</span> <span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token keyword">class</span> <span class="token class-name">PasswordReminder</span> <span class="token punctuation">{</span> <span class="token keyword">private</span> <span class="token variable">$dbConnection</span> <span class="token punctuation">;</span> <span class="token keyword">public</span> <span class="token keyword">function</span> <span class="token function">__construct</span> <span class="token punctuation">(</span> DBConnectionInterface <span class="token variable">$dbConnection</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token variable">$this</span> <span class="token operator">-</span> <span class="token operator">></span> <span class="token property">dbConnection</span> <span class="token operator">=</span> <span class="token variable">$dbConnection</span> <span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> |
Conclude
- There are many principles in software design and above are the 5 most important object-oriented design principles (SOLID).
- Mastering and applying the principles in the design will help our program source code look clearer, take advantage of the advantages of OOP, the components do not depend too much on each other, so that Convenient for later maintenance and expansion.
- Thank you for watching.