Khi thực hiện những dự án với độ phức tạp cao ngoài việc thiết kế tính năng cho ứng dụng, tổ chức code luôn luôn là vấn đề được đặt lên hàng đầu. Tổ chức tốt giúp lập trình viên dễ dàng bảo trì, cũng như mở rộng code về sau. Để có thể tiết kiệm chi phí và thời gian cho công đoạn này nhưng vẫn đem lại hiệu quả cao, việc nắm vững về các design pattern được thiết kế sẵn sẽ giúp ích rất nhiều. Bài viết nhằm mang đến sự tiếp cận đầu tiên cho độc giả về Dependency Injection. Đây là một dạng design pattern nhằm ngăn chặn sự phụ thuộc giữa các class.
Design Pattern Java Trần Thị Thu Hiền 2017-10-10 09:58:40

Giới thiệu

Khi thực hiện những dự án với độ phức tạp cao ngoài việc thiết kế tính năng cho ứng dụng, tổ chức code luôn luôn là vấn đề được đặt lên hàng đầu. Tổ chức tốt giúp lập trình viên dễ dàng bảo trì, cũng như mở rộng code về sau. Để có thể tiết kiệm chi phí và thời gian cho công đoạn này nhưng vẫn đem lại hiệu quả cao, việc nắm vững về các design pattern sẽ giúp ích rất nhiều. Bài viết nhằm mang đến sự tiếp cận đầu tiên cho độc giả về Dependency Injection. Đây là một dạng design pattern được thiết kế với mục đích ngăn chặn sự phụ thuộc giữa các class.

Tiền đề bài viết

Bài viết nằm trong chuỗi bài viết về đề tài Design Pattern.

Dependency Injection là gì?

Với lập trình hướng đối tương, chúng ta hầu như luôn phải làm việc với rất nhiều class trong một chương trình, các class được liên kết với nhau theo một mối quan hệ nào đó. Dependency là một loại quan hệ giữa 2 class mà trong đó một class hoạt động độc lập và class còn lại phụ thuộc bởi class kia. Điển hình là khi ta có 2 class: class Wheel và class Bicycle, trong class Bicycle có chứa một biến toàn cục kiểu class Wheel. 

public class Wheel{
	...
	public Wheel(){
		...
	}
	
	public void Roll(){
		...
	}
}

public class Bicycle{
	public Wheel _wheel;
	
	public void Bicycle(){
		_wheel = new Wheel();
	}
	
	public void Run(){
		_wheel.Roll();
	}
}

public class Application{
	public Bicycle _bicycle;
	
	public Application(){
		_bicycle = new Bicycle();
	}
	
	public Start(){
		Bicycle.Run();
	}
}

Đây là một trong những cách hiện thực quen thuộc nhưng với cách thiết kế này sẽ sinh ra sự phụ thuộc code giữa class Bicycle và Wheel. Như ta thấy Wheel được khởi tạo trong constructor của Bicycle, vậy giả sử trong tương lai bạn muốn sử dụng một loại Wheel khác, lúc này bạn phải thay đổi rất nhiều trong class Bicycle, hay đơn giản là bạn muốn chỉnh sửa trong class Wheel cũ, không có gì để đảm bảo chắc chắn rằng Bicycle vẫn có thể hoạt động tốt mà không cần trải qua 1 sự nâng cấp nào.

Dependency Injection là một dạng design pattern được thiết kế nhằm ngăn chặn sự phụ thuộc nêu trên, điều này giúp giảm chi phí trong việc sửa đổi và nâng cấp hệ thống. Nhờ vậy khi bạn thực thiện thay đổi một class A thì những class chứa biến kiểu class A cũng không cần phải thay đổi theo.

Cách hiện thực

Dependency Injection có thể được hiện thực dựa trên các quy tắc sau:

  • Các class sẽ không phụ thuộc trực tiếp lẫn nhau mà thay vào đó chúng sẽ liên kết với nhau thông qua một Interface hoặc base class (đối với một số ngôn ngữ không hỗ trợ Interface) 
  • Việc khởi tạo các class sẽ do các Interface quản lí thay vì class phụ thuộc nó
public interface IWheel{
	void Roll();
}

public class WoodenWheel implements InterfaceWheel{
	@Override
	public void Roll(){
		....
	}
}

//--------------------------------------------------------------

public interface IBicycle{
	void Run();
}

public class SmartBike implement IBicycle{
	private IWheel _wheel;
	
	public SmartBike(IWheel wheel){
		this._wheel = wheel;
	}
	
	@Override
	public void Run(){
		_wheel.Roll();
	}
}

//--------------------------------------------------------------

public interface WheelInjector{
	public IBicycle getBicycle();
}

public class WoodenWheelInjector element WheelInjector{
	public IBicycle getBicycle(){
		return new SmartBike(new WoodenWheel());
	}
}

//--------------------------------------------------------------

public class Application{
	public WheelInjector injector = null;
	private SmartBike _bicycle;
		
	public Application(){
		injector = new WoodenWheelInjector();
        _bicycle = injector.getBicycle();
	}
	
	public Start(){
		_bicycle.Run();
	}
}