Reputation: 577
After searching different forums related to tight coupling (when a group of classes are highly dependent on one another) Example1
class CustomerRepository
{
private readonly Database database;
public CustomerRepository(Database database)
{
this.database = database;
}
public void Add(string CustomerName)
{
database.AddRow("Customer", CustomerName);
}
}
class Database
{
public void AddRow(string Table, string Value)
{
}
}
Above class CustomerRepository is dependent on Database class so they are tightly coupled .and i think this class is also an example of Compostion ,then i searched for loose coupling so changing the above class so that tight coupling dependency is removed. Example2
class CustomerRepository
{
private readonly IDatabase database;
public CustomerRepository(IDatabase database)
{
this.database = database;
}
public void Add(string CustomerName)
{
database.AddRow("Customer", CustomerName);
}
}
interface IDatabase
{
void AddRow(string Table, string Value);
}
class Database : IDatabase
{
public void AddRow(string Table, string Value)
{
}
}
I have searched that composition support loose coupling now my question is how example1 is tightly coupled as it were based on composition? secondly what is the relation between loose coupling and composition?
Any help will be greatly appreciated.
Upvotes: 2
Views: 860
Reputation: 7903
@deceze's explains most of your questions. I am just adding my 2 cents to his answer.
Both examples are loosely coupled but to different degrees.
Example -1 You are allowed to inject object of concrete type via its constructor.
Example -2 You are allowed to inject an objecto of abstract type via its constructor.
What makes the example 2 more loosly coupled is the due to Dependency Inversion Principle. It's main idea is - one should “Depend upon Abstractions. Do not depend upon concretions.”
Second example depends on interface and not on a Concrete class like the first one. Now comes the confusion -why interface is special why not a class both of them do the same thing?
Lets assume tomorrow if you want to delete Database
Class and replace it with new class FlatFile
, you need to change CustomerRepository
class in the first example but not the second. In the second example the person who will create an instance of CustomerRepository
only should worry replacing Database
class with FlatFile
Class. This is the meaning of loose copling changing Database
class should not force you to change CustomerRepository
class.
To answer your last question
what is the relation between loose coupling and composition?
There is no direct relation, you can still use composition and mess up the coupling between class by not implementing the Dependency inversion principle. So the right question you should ask is -
How to make a tightly coupled code to loosely coupled?
Follow Dependency inversion principle.
Upvotes: 2
Reputation: 522024
What you have there is not really tight coupling. Tight coupling would be this:
class CustomerRepository {
private readonly Database database;
public CustomerRepository() {
this.database = new Database;
}
}
The class has a hardcoded dependency on a specific Database
class which cannot be substituted. That's really tight coupling.
The composition example you're showing is already loosely coupled, since it's entirely possible to substitute the dependency being injected into the constructor by any other Database
inheriting class.
Your second example is even more loosely coupled, since it uses an interface instead of a concrete class; but that's something of a minor detail.
Upvotes: 4