Nguyên tắc đảo ngược phụ thuộc so với Chương trình trên giao diện, không phải là triển khai


12

Tôi đang cố gắng hiểu Nguyên tắc đảo ngược phụ thuộc khác với nguyên tắc "chương trình đến giao diện, không phải là triển khai".

Tôi hiểu "Chương trình cho giao diện, không phải triển khai" nghĩa là gì. Tôi cũng hiểu làm thế nào nó cho phép các thiết kế linh hoạt hơn và có thể bảo trì.

Nhưng tôi không hiểu Nguyên tắc đảo ngược phụ thuộc khác với nguyên tắc "Chương trình với giao diện, không phải là triển khai".

Tôi đã đọc về DIP ở một số nơi trên web và điều đó không làm tôi bối rối. Tôi vẫn không thấy hai nguyên tắc khác nhau như thế nào. Cảm ơn bạn đã giúp đỡ.

Câu trả lời:


25

"Chương trình cho một giao diện" có nghĩa là không phụ thuộc vào một loại cụ thể để thực hiện công việc của bạn , nhưng nó không chỉ định cách bạn nên có được sự phụ thuộc của mình.

"Nguyên tắc đảo ngược phụ thuộc" nói rằng một đối tượng không nên kiểm soát việc tạo ra các phụ thuộc của nó, nó chỉ nên quảng cáo những gì phụ thuộc mà nó cần và để người gọi cung cấp nó . Nhưng nó không xác định liệu phụ thuộc nên là một loại cụ thể hay một giao diện.

Tôi sẽ minh họa sự khác biệt với một số mã C #.

Ví dụ sau đây phụ thuộc vào một loại cụ thể và nó kiểm soát việc tạo ra sự phụ thuộc của chính nó. Nó không theo "chương trình giao diện" hay "đảo ngược phụ thuộc":

public class ThingProcessor
{
    MyThing _myThing;

    public ThingProcessor()
    {
        _myThing = new MyThing();
    }

    public void DoSomething()
    {
        _myThing.DoIt();
    }
}

Ví dụ sau tùy thuộc vào giao diện, nhưng nó kiểm soát việc tạo phụ thuộc của chính nó. Nó theo "chương trình đến một giao diện", nhưng không phải là "đảo ngược phụ thuộc":

public class ThingProcessor
{
    IMyThing _myThing;

    public ThingProcessor()
    {
        _myThing = ThingFactory.GiveMeANewMyThing();
    }

    public void DoSomething()
    {
        _myThing.DoIt();
    }
}

Ví dụ sau đây phụ thuộc vào một loại cụ thể, nhưng nó yêu cầu sự phụ thuộc của nó được tạo ra và chuyển cho nó. Nó tuân theo "nghịch đảo phụ thuộc", nhưng không phải là "chương trình cho một giao diện":

public class ThingProcessor
{
    MyThing _myThing;

    public ThingProcessor(MyThing myThing)
    {
        _myThing = myThing;
    }

    public void DoSomething()
    {
        _myThing.DoIt();
    }
}

Ví dụ sau đây phụ thuộc vào một giao diện và nó yêu cầu sự phụ thuộc của nó được tạo và chuyển cho nó. Nó tuân theo cả "đảo ngược phụ thuộc" "chương trình tới một giao diện":

public class ThingProcessor
{
    IMyThing _myThing;

    public ThingProcessor(IMyThing myThing) // using an interface
    {
        _myThing = myThing;
    }

    public void DoSomething()
    {
        _myThing.DoIt();
    }
}

1
Minh họa tuyệt vời của sự khác biệt.
Rory Hunter

8
Những gì bạn đang nói là tiêm depenendy. Và nghịch đảo phụ thuộc và tiêm phụ thuộc là hai điều khác nhau.
Euphoric

1
@Euphoric Tôi đang nói về Nguyên tắc đảo ngược phụ thuộc, là một khái niệm trừu tượng, bằng cách sử dụng Dependency Injection làm ví dụ triển khai cụ thể. Tôi hiểu sự khác biệt.
Eric King

1
@EricKing Sau đó, bạn nên nói rõ ràng rằng trong câu trả lời của mình thay vì đi đến "Nguyên tắc đảo ngược phụ thuộc" nói ... "điều này rõ ràng là sai nếu bạn đọc câu trả lời của tôi.
Euphoric

1
Tôi đồng ý với Euphoric. Nguyên tắc đảo ngược phụ thuộc nói rằng các lớp mã cấp cao hơn nên phụ thuộc vào các đoạn mã cấp thấp hơn, chứ không phải ngược lại. Ví dụ PrintStreamnên phụ thuộc vào giao diện được thiết lập bởi ByteOutputStream. Dependency Injection đề cập không có gì về người nên phụ thuộc vào ai.
Doval

5

Họ nói chung là điều tương tự. Nếu bạn đọc Nguyên tắc đảo ngược phụ thuộc là gì và tại sao nó quan trọng? Nguyên tắc đảo ngược phụ thuộc , bạn sẽ nhận ra hai "nguyên tắc" nói về cơ bản về cùng một điều.

  • Các mô-đun cấp cao không nên phụ thuộc vào các mô-đun cấp thấp. Cả hai nên phụ thuộc vào trừu tượng.
  • Trừu tượng không bao giờ nên phụ thuộc vào chi tiết. Thông tin chi tiết nên phụ thuộc vào trừu tượng.

Giao diện là một sự trừu tượng và thực hiện là một chi tiết. Nếu bạn thay thế chúng trong hai câu lệnh trước, về cơ bản bạn sẽ nhận được "mã nên phụ thuộc vào giao diện và không triển khai". Và đó là điều tương tự với tôi.


Đây phải là câu trả lời được chấp nhận, câu trả lời được bình chọn nhiều nhất là sai lệch
Sameh Deabes

2

Giao diện là một cách để thực hiện DI. Nếu bạn chỉ định một giao diện là một tham số trong phương thức constructor của một lớp, bạn có thể trao bất kỳ đối tượng nào bạn muốn cho phương thức constructor đó, miễn là đối tượng đó thực hiện giao diện của tham số constructor.

Nói cách khác, lập trình một giao diện cho phép bạn thay đổi việc thực hiện giao diện đó. Đó là cách chúng tôi có thể thay thế các đối tượng giả cho các đối tượng thực trong quá trình kiểm tra đơn vị, chỉ định các nhà cung cấp dữ liệu khác nhau, v.v.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.