Hướng dẫn dependency injection php w3schools - phụ thuộc tiêm php w3schools

Tiêm phụ thuộc là một đối tượng thảo luận thường xuyên giữa nhiều nhà phát triển công ty trong vài năm qua. Nhiều người sợ rằng họ có thể hy sinh quá nhiều thời gian để xây dựng kiến ​​trúc ứng dụng của họ mà không làm bất kỳ công việc thực sự nào. Trong bài viết này, tôi sẽ giải thích lý do tại sao các nhà phát triển PHP nên xem xét tận dụng lợi thế của việc tiêm phụ thuộc, khi xây dựng các dự án lớn, có thể mở rộng.


Tiêm phụ thuộc là gì?

Trước khi đào sâu vào đối tượng, hãy xác định chính xác việc tiêm phụ thuộc là gì. Hãy tưởng tượng rằng bạn hiện đang làm việc trên một trang web "câu hỏi và trả lời", tương tự như Stack Overflow. Nhiều khả năng bạn sẽ tạo ra một lớp, được gọi là Question, trong đó có chứa một thành viên loại Author. Trong những ngày cũ, các lập trình viên sẽ tạo ra đối tượng Author trực tiếp trong hàm tạo Question, như thế này:

class Author {
    private $firstName;
    private $lastName;

    public function __construct($firstName, $lastName) {
        $this->firstName = $firstName;
        $this->lastName = $lastName;
    }

    public function getFirstName() {
        return $this->firstName;
    }

    public function getLastName() {
        return $this->lastName;
    }
}

class Question {
    private $author;
    private $question;
    public function __construct($question, $authorFirstName, $authorLastName) {
        $this->author = new Author($authorFirstName, $authorLastName);
        $this->question = $question;
    }

    public function getAuthor() {
        return $this->author;
    }

    public function getQuestion() {
        return $this->question;
    }
}

Mặc dù nhiều lập trình viên có thể gọi mã tốt này, nhưng thực tế có nhiều vấn đề với nó:

  • Thông tin của tác giả được chuyển cho hàm tạo Question không có gì để làm trong phạm vi của ____ 4. Tên của một tác giả nên ở trong lớp Author vì nó không liên quan gì đến câu hỏi.
  • Lớp Author được kết hợp chặt chẽ với lớp Question. Nếu chúng ta thêm một tham số mới vào hàm tạo của ____ 5, thì chúng ta phải sửa đổi mọi lớp nơi chúng ta tạo một đối tượng Author - một quá trình tẻ nhạt và dài, đặc biệt là trong các ứng dụng lớn.
  • Đơn vị kiểm tra lớp Question tạo ra hành vi không mong muốn khi phải kiểm tra lớp Author.

Tiêm phụ thuộc làm giảm bớt các vấn đề này bằng cách chèn các phụ thuộc thông qua hàm tạo của lớp phụ thuộc ("tiêm hàm tạo"). Kết quả là mã có thể duy trì cao, có thể trông như thế này:

class Author {
    private $firstName;
    private $lastName;
    
    public function __construct($firstName, $lastName) {
        $this->firstName = $firstName;
        $this->lastName = $lastName;
    }

    public function getFirstName() {
        return $this->firstName;
    }

    public function getLastName() {
        return $this->lastName;
    }
}

class Question {
    private $author;
    private $question;

    public function __construct($question, Author $author) {
        $this->author = $author;
        $this->question = $question;
    }

    public function getAuthor() {
        return $this->author;
    }

    public function getQuestion() {
        return $this->question;
    }
}

Ưu điểm của việc tiêm phụ thuộc

Bạn cần sử dụng tiêm phụ thuộc cho các dự án dài hạn.

Tôi đã làm việc trong nhiều dự án thương mại trong sự nghiệp của tôi. Một số trong số họ được viết rất tốt; Tuy nhiên, tôi phải nói rằng hầu hết trong số họ có chất lượng mã kém đáng kể. Gần đây tôi đã được chỉ định làm việc trên cơ sở mã như vậy ...

Một công ty đã yêu cầu ứng dụng vào năm 2009. Ngân sách của dự án đã được lên kế hoạch đúng, nhưng người quản lý dự án muốn ứng dụng được xây dựng rất nhanh để gây ấn tượng với ông chủ của mình. Ít nhất, đây là những gì đồng nghiệp của tôi nói với tôi. Viết một ứng dụng nhanh chóng nghe có vẻ tuyệt vời để giảm chi phí, nhưng điều đó cũng có nghĩa là các nhà phát triển đã nhảy vào mã mà không có kế hoạch phù hợp.

Các nhà phát triển đã viết mã nhanh chóng, tạo các lớp cần thiết để thực hiện các chức năng cần thiết. Các tính năng thay đổi khi dự án phát triển và vì dự án đã được lên kế hoạch kém (và mọi lớp học được ghép nối chặt chẽ), dự án trở nên khó phát triển.

Hiện tại, thật khó để làm việc trong dự án này. Sửa đổi một lớp đơn giản dẫn đến một loạt các sửa đổi khác trong các lớp khác, bởi vì mọi thứ được kết hợp với nhau - dẫn đến nhiều lỗi. Mỗi lần sửa đổi một cái gì đó, nhà phát triển cần phải đuổi theo và sửa lỗi.

Ứng dụng này cũng không thể kiểm tra đơn vị, làm giảm chất lượng của mã.

Mọi tính năng phải được kiểm tra thủ công, mất thời gian quý giá có thể được sử dụng ở nơi khác. Trên thực tế, để giảm chi phí kiểm tra thủ công, chúng tôi đã tạo phần mềm để kiểm tra cơ sở hạ tầng của ứng dụng. Có, chúng tôi đã phải tạo phần mềm mới để kiểm tra sản phẩm thực tế.

Công ty đã học được rằng cố gắng nhanh chóng viết phần mềm dẫn đến chi phí bất ngờ. Lúc đầu, công ty đã kiếm được rất nhiều tiền vì họ đã tính phí rất nhiều cho nó, nhưng sau ba năm, họ đã mất tiền cho ứng dụng này. Số tiền họ rút ra không bao gồm chi phí bảo trì cao, tiếp tục. Họ cũng mất nhiều nhà phát triển cao cấp, tốt bụng, những người đã mất bất kỳ mong muốn làm việc trong dự án.

Nếu ứng dụng sử dụng tiêm phụ thuộc, các nhà phát triển sẽ có thể kiểm tra đơn vị đúng cách, dẫn đến giảm chi phí bảo trì và gỡ lỗi. Công ty sẽ tập trung vào việc tạo ra các tính năng mới cuối cùng, thay vì mất chất lượng phần mềm mỗi khi tính năng mới được giới thiệu. Họ cũng sẽ giữ các thành viên trong nhóm cao cấp của mình và tránh mất tiền bằng cách tìm và thuê nhân viên mới (rất khó để bắt đầu ở thành phố của tôi).


Bắt đầu với ngân sách hạn chế

Mặc dù tiêm phụ thuộc giúp hỗ trợ bạn viết mã tốt hơn, nhưng nó cũng có thể đòi hỏi thêm thời gian và công sức để thực hiện chính xác. Điều này có thể chứng minh là một vấn đề, nếu bạn cần mã làm việc cho một bản demo.

Nếu tất cả những gì bạn cần là một bằng chứng của khái niệm, thì tôi khuyên bạn nên không lãng phí thời gian với việc tiêm phụ thuộc và kiến ​​trúc phù hợp.

Nhảy ngay vào và bắt đầu mã hóa. Bạn có thể làm mọi thứ một cách chính xác sau khi dự án được phê duyệt và bạn có nguồn tài trợ cần thiết. Trong thực tế, một khi bạn có tài trợ thích hợp, hãy vứt bỏ bản demo của bạn và bắt đầu từ đầu. Nếu không, ứng dụng của bạn sẽ kết thúc dưới dạng spaghetti-code-can.


Mã khởi động lộn xộn

Vì vậy, bạn đã bắt đầu chuyển các phụ thuộc của mình trong các trình xây dựng lớp của bạn, nhưng khi dự án phát triển, bạn sẽ kết thúc với nhiều cấp độ đối tượng phải được tạo khi ứng dụng của bạn bắt đầu. Tùy thuộc vào kích thước của ứng dụng của bạn, việc tạo tất cả các đối tượng để khởi chạy ứng dụng của bạn có thể là một quá trình rất dài và làm tổn thương hiệu suất của ứng dụng của bạn (cũng như kết quả trong mã lộn xộn). Đây là một ví dụ:

/*
    Please note that the nature of the application is not important here. I only wanted to show how hard-to-maintain/awful such code can be:
*/
$filePath = "/path/to/file";

$fileBuilderFactory = new ConcreteFileBuilderFactory();

$filesXmlBuilderFactory = new ConcreteFilesXmlBuilderFactory($fileBuilderFactory);

$softwaresRetrieverCriteriaBuilderFactory = new ConcreteSoftwaresRetrieverCriteriaBuilderFactory($filesXmlBuilderFactory);

$softwareRetrieverCriteriaBuilderFactory = new ConcreteSoftwaresSoftwareRetrieverCriteriaBuilderFactory($filesXmlBuilderFactory);

$filesJsonBuilderFactory = new ConcreteFilesJsonBuilderFactory($fileBuilderFactory);

$objectBuildderFactory = new ConcreteSoftwaresSoftwareObjectBuilderFactory();

$softwaresSoftwareBuilderFactory = new ConcreteSoftwaresSoftwareBuilderFactory($objectBuildderFactory);

$xmlSoftwareRepository = new XmlSoftwareRepository($softwaresSoftwareBuilderFactory);

$softwaresBuilderFactory = new ConcreteSoftwaresBuilderFactory($xmlSoftwareRepository, $softwareRetrieverCriteriaBuilderFactory, $filesJsonBuilderFactory);

$xmlSoftwaresRepository = new XmlSoftwaresRepository($softwaresBuilderFactory);

$softwareToHashMap = new ConcreteSoftwareToHashMap();

$softwaresToHashMap = new ConcreteSoftwaresToHashMap($softwareToHashMap);

$jsonSoftwaresService = new JsonSoftwaresService($softwaresToHashMap);

$di = new DependencyInjection($softwaresRetrieverCriteriaBuilderFactory, $xmlSoftwaresRepository, $jsonSoftwaresService);

Mã khởi động này khá nhỏ. Nếu bạn xây dựng một ứng dụng lớn, mã khởi động của bạn có thể trở nên nặng hơn thế này. Không cần phải nói, điều này dẫn đến một số khó duy trì mã.

Để giải quyết vấn đề này, chúng tôi cần một ứng dụng tiêm phụ thuộc đọc tệp XML và tạo tất cả các đối tượng cần thiết để khởi chạy ứng dụng. Các đối tượng sau đó sẽ được tuần tự hóa và ghi vào một tệp. Mã khởi động sau đó chỉ cần đọc tệp đó và trực tiếp tạo các đối tượng. Điều này làm cho mã khởi động của bạn đơn giản như:

$objectFilePath = "/path/to/serialized/object/file";
$di = unserialize(file_get_contents($objectFilePath));

Phần mềm tiêm phụ thuộc nguồn mở

Hầu hết các công ty không có nhiều ngân sách để tạo ra các công cụ, chẳng hạn như khung tiêm phụ thuộc. Tuy nhiên, bạn có thể tìm thấy nhiều giải pháp nguồn mở và miễn phí trên web. Symfony2 sử dụng một thành phần DI rất chắc chắn dựa trên lò xo Java. Tuy nhiên, tôi sẽ bao gồm lập trình một giải pháp tiêm phụ thuộc trong tương lai gần, nếu điều đó làm bạn quan tâm. Giữ nguyên!


Php Devs và tiêm phụ thuộc

Tôi không muốn khái quát hóa, nhưng, do sự phổ biến của nó, nhiều nhà phát triển PHP là những người có sở thích, những người thích kết hợp PHP và HTML.

Những nhà phát triển này thường không lên kế hoạch cho dự án của họ; Họ chỉ muốn viết mã nhanh chóng để "hoàn thành công việc."

Tôi tin rằng việc thuê các loại nhà phát triển này là điều tồi tệ nhất mà người quản lý có thể làm. Bằng cách nhấn mạnh tầm quan trọng của việc tiêm phụ thuộc, bạn có thể khiến những "tin tặc" này không quan tâm đến công ty của bạn, đồng thời, lôi kéo các nhà phát triển tốt làm việc cho công ty của bạn. Nói cách khác, dự án của bạn sẽ thu hút các nhà phát triển cao cấp tốt, đây là tài nguyên quan trọng nhất mà công ty phát triển phần mềm có thể có được!


Khi nào nên sử dụng tiêm phụ thuộc

Tiêm phụ thuộc là hữu ích nhất, khi làm việc trên các dự án dài hạn.

Từ kinh nghiệm của tôi, tiêm phụ thuộc là hữu ích nhất, khi làm việc trên các dự án dài hạn - các dự án được tích cực phát triển và duy trì trong một thời gian dài. Điều này làm giảm đáng kể chi phí của bạn và thu hút các nhà phát triển tốt nhất. Nhưng, như tôi đã đề cập trước đây, nếu bạn cần một ứng dụng demo để nhận hợp đồng hoặc một số tài trợ, tôi khuyên bạn nên đào ngay vào mã. Tuy nhiên, nếu bạn đi theo con đường đó, hãy lưu ý rằng bản demo sẽ cần phải bị vứt bỏ sau khi bạn có được hợp đồng và/hoặc tài trợ.


Giờ kể chuyện!

Tôi thích những câu chuyện về các nhà phát triển muốn làm điều đúng đắn, nhưng đồng nghiệp của họ muốn từ bỏ các thực tiễn tốt nhất và đẩy một dự án ra nhanh nhất có thể. Suy nghĩ của bạn về tiêm phụ thuộc là gì? Một biến đổi quá mức, hoặc một yêu cầu cho bất kỳ ứng dụng bền vững?

Bạn có thấy bài đăng này hữu ích?