Low coupling
When designing some architecture, you face with the problem “which object should perform X task?” We discussed this question in my previous post in this series. There we noted, that object should perform the tasks he has enough info for. He should be an “expert”. But because one of the main OOP characteristics is interaction between objects, it’s often hard to answer this question.
Introducing example
Consider you should print the table parameters (see What is OOP post for this example). There are tables of 2 types: square and circle ones. Square has parameter “side”, circe has parameter – “radius”. And we need the table:
Sure, we can create a class Lister and method Lisert::out(). But what logic to place there? We can go with something like this:
Identifying the problem
However, this method is strictly linked to using only CircleTable and SquareTable, it will not work without CircleTable and adding other table types is impossible. This can be imagined like this:
Notice that since Lister class uses CircleTable and SquareTable, they can’t be used along. This picture illustrates it – they are coupled together.
Coming up with a solution
The correct variant of solving the task of table output is the following.
- Refactor Table classes putting the output logic, that is specific to the table into the class
- Use these new methods of table classes in the Lister::out method
Enough talk, let’s walk!
-
-
class CircleTable extends Table
-
{
-
public $radius;
-
-
public function __construct($r, $h)
-
{
-
parent::__construct($h);//calling the constructor of the parent class, passing height there.
-
$this->radius = $r;//setting the radius
-
}
-
-
public function getSquare()
-
{
-
return $this->radius*$this->radius*M_PI;
-
}
-
-
public function out()
-
{
-
}
-
}
-
-
class SquareTable extends Table
-
{
-
public $side;
-
-
public function __construct($s, $h)
-
{
-
parent::__construct($h);//calling the constructor of the parent class, passing height there.
-
$this->side = $s;//setting the side
-
}
-
-
public function getSquare()
-
{
-
return $this->side*$this->side;
-
}
-
-
public function out()
-
{
-
}
-
}
-
And we’ll use these methods in the Lister class:
Running the code with the same data will give us exactly the same thing. But only one difference – this code is easy to maintain, change and expand. We can imagine this structure as following:
For example, if we need one more table – triangle – we just add this class and then – created object into the List::tables property and that’s all. It will be printed out.
Here is the code:
-
-
class TriangleTable extends Table
-
{
-
public $side;
-
-
public function __construct($s, $h)
-
{
-
parent::__construct($h);//calling the constructor of the parent class, passing height there.
-
$this->side = $s;//setting the side
-
}
-
-
public function getSquare()
-
{
-
return $this->side*$this->side*0.433;
-
}
-
-
public function out()
-
{
-
}
-
}
-
And now add this table to the test script:
-
-
<?php
-
require_once(‘Table.php’);
-
require_once(‘Lister.php’);
-
$list = new Lister();
-
new CircleTable(5, 90),
-
new SquareTable(2, 85),
-
new SquareTable(8, 100),
-
new TriangleTable(7,150),
-
new TriangleTable(10,120),
-
);
-
$list->out();
-
?>
-
And we’ll get the following table with no modifications in the Lister class:
Note, that we can populate tables list from the DB table and no code will be changed. Adding new table type is very simple – you just develop the class similar to CircleTable or SquareTable and then use it. No more changes needed.
This technique when you do your best to write the isolated pieces of code, which can be reused separately is called “Low Coupling”, your goal is to create classes in such a way that they do not depend on each other or check these dependencies preventing runtime errors.
Sure, that’s the goal, it can’t be achieved in full, but you should aim to do this.
High cohesion
When you do your best to implement the Lout Coupling principle, you write your code in a small portions, and each of them does some definite task. And since each class is small and does only one or several cohesive jobs, you get High Cohesion in your code.
These two principles go together. When you fulfil one of them, you automatically follow another one.
Summary
Putting it all together, we may say that Low Coupling principle requires writing isolated pieces of code, that form complex logic only by interacting with each other, not by themselves. And While following this principle, our little parts automatically become focused on one task, so they become cohesive. This way we fulfil both principles at once.
And good OO-design follow all GRASP principles at the same time just because they characterise nice application design.
What can you add here? Maybe you’ve got some questions? Feel free to ask here in comments or by email.
Grab the code of examples here.
Related posts:
- Requirements and Use Cases. SMS Notification System. Background I’ve graduated in March 2010 and I don’t need...
Related posts brought to you by Yet Another Related Posts Plugin.
Share this post with a friend















hitesh says:
Nice explanation. It will help !
October 10, 2009, 15:15