DI is a design pattern where an object's dependencies are provided to it externally rather than the object creating them itself, promoting loose coupling between components.
Example
// Service Interface
public interface MyService {
void performAction();
}
// Service Implementation
public class MyServiceImpl implements MyService {
@Override
public void performAction() {
System.out.println("Action performed!");
}
}
// Component that depends on MyService
public class MyComponent {
private final MyService myService;
// Constructor injection (Dependency Injection)
public MyComponent(MyService myService) {
this.myService = myService;
}
public void doSomething() {
myService.performAction();
}
}
// Main Class to run the example
public class Main {
public static void main(String[] args) {
// Manual dependency injection
MyService myService = new MyServiceImpl();
MyComponent myComponent = new MyComponent(myService);
myComponent.doSomething(); // Outputs: Action performed!
}
}
IoC is a broader principle where the control of object creation and management is inverted, typically from the application to a framework or container, allowing the framework to inject dependencies into the application components.
Example
Consumer class does not create its own dependencies (i.e., instances of Food). Instead, these dependencies are injected into the Consumer via its constructor. This is a common form of IoC known as constructor injection.Food implementation (Chicken or Pizza) is used lies outside the Consumer class. The Consumer class is not responsible for deciding or creating the Food instance, which demonstrates the IoC principle.public class Consumer {
private Food food;
// Dependency is injected via a constructor (IoC)
public Consumer(Food food) {
this.food = food;
}
void eat() {
this.food.eat();
}
public static void main(String[] args) {
// The dependencies are created outside of the Consumer
Food chicken = new Chicken();
Consumer consumer1 = new Consumer(chicken);
consumer1.eat(); // Outputs: I'm eating a chicken.
Food pizza = new Pizza();
Consumer consumer2 = new Consumer(pizza);
consumer2.eat(); // Outputs: I'm eating Pizza
}
}
interface Food {
void eat();
}
class Chicken implements Food {
@Override
public void eat() {
System.out.println("I'm eating a chicken.");
}
}
class Pizza implements Food {
@Override
public void eat() {
System.out.println("I'm eating Pizza");
}
}