Dependency Injection

Hôm nay mình sẽ chia sẻ với các bạn về Dependency Injection: Về dependency là gì? Dependency Injection là gì? Cách đơn giản để loại bỏ dependency Injection.
Do đây là bài viết đầu tiên khi mình mới bước vào cộng đồng Viblo, nếu có sai sót, xin mọi người được góp ý.
Đầu tiên ta cùng tìm hiều Dependency là gì?
Đúng như nghĩa đen của nó, dependency là sự phục thuộc. Trong lập trình khái niệm này ám chỉ sự phụ thuộc giữa phần tử mà sự thay đổi của phần tử này sẽ ảnh hưởng đến tiến trình chạy của các phần tử khác. Thường thì người ta hay nhắc tới dependency khi nhắc tới các Class, với tình trạng khi một Class thay đổi thì kéo theo sự thay đổi của các Class khác.
Ví dụ nhé:
Ta có class quickSort với hàm sort nhiệm vụ sắp xếp một mảng. Bạn sử dụng thuật toán quickSort để thực hiện quá trình này.

public class  Sort()
{
    public arr sort()
    {
        //quickSort_process
        return arr_sorted;
    }
}

Tiếp theo đấy là 1 class Process đại diện là class sẻ sử dụng Class Sort của bạn để tiến hành Sort

public class Process
{
    public void run()
    {
        //Other process;
        quickSort();
        //continue process;
    }
}

Hệ thống hoạt động trơn chu cho đến một ngày đẹp trời, ông sếp của bạn yêu cầu thay đổi thuật toán Sort thành merge Sort. Việc của bạn hiện tại là gì. Sẽ là thay đổi thuật toán sort thành merge Sort. Oke! Cũng khá đơn giản, xóa thuật toán quickSort trong hàm sort và thay đổi thuật toán thành mergeSort thôi.

public class  Sort()
{
    public arr sort()
    {
        //mergeSort_process
        return arr_sorted;
    }
}

Oke. Hệ thống lại hoạt động bình thường, Cuộc sống lai cứ thế diễn ra cho dến khi...
Một ngày đẹp trời nữa lại đến, ông sếp của bạn lại yêu cầu bạn phải thay đổi thuật toán Sort thành quickSort vì thấy nó tốt hơn mergeSort. Cảm xúc của ông sếp khi đấy sẽ là thế này 😃 😃 😃, và của bạn thì... 😦 😦 😦 .
Bạn lại phải mày mò một lần nữa vào class Sort để sửa thuật toán trong hàm Sort. Lần này bạn có "kinh nghiệm" hơn. Bạn comment đống code mergeSort của mình lại và thêm lại đống code quickSort vào. Nhưng điều gì sẽ xảy ra nếu yêu cầu cứ thế thay đổi và bạn cứ liện tục comment lại code. Sẽ là một hàm Sort "khổng lồ" với hàng trăm đống comment, lâu lâu sẽ không thể kiểm soát.
Vậy giải pháp ở đây là gì? Việc chúng ta giải quyết sự phụ thuộc giữa các Class với nhau được gọi là Dependency Injection.
Mình xin được trình bày một cách để giải quyết điều này. Theo như mình biết thì nó được giải quyết theo tư tưởng của Factory Patten. Bạn có thể tìm hiểu thêm. Còn bây giờ là cách giải quyết cụ thể:
Đầu tiên tạo 1 Interface định nghĩa công việc Sort của bạn:

public interface Sort()
{
	public arr sort();
}

Làn lượt định nghĩa các thuật toán mà bạn nghĩ ông Sếp có thể yêu cầu:
Ví dụ nhé:

Merge Sort
public class  MergeSort implement Sort()
{
    public arr sort()
    {
        //mergeSort_process
        return arr_sorted;
    }
}
Quick Sort
public class  QuickSort implement Sort()
{
    public arr sort()
    {
        //quickSort_process
        return arr_sorted;
    }
}

Tiếp theo, bạn sẽ phải tạo một class để xác định xem sẽ dùng Thuật toán Sort nào. Mình tạm gọi là SortAlgorithm

Quick Sort
public class  SortAlgorithm ()
{
    public arr getSort()
    {
        return new QuickSort;
        //or
        // return new MergeSort;
    }
}

Khi đó bạn sẽ viết lại class Process ở trên như sau:

public class Process
{
    Sort sort;
    public void run()
    {
        //Other process;
        sort = Factory.getSort();
        sort.Sort();
        //continue process;
    }
}

Đó, khi này, nếu thay đổi thuật toán sort, bạn chỉ cần thay đỏi trong class SortAlgorithm. Như vậy là xong, đơn giản phải không nào.