Phụ thuộc tiêm: tôi nên sử dụng một khuôn khổ?


24

Gần đây tôi đã làm việc trong một dự án Python nơi chúng tôi đã thực hiện tiêm phụ thuộc rất nhiều (vì chúng tôi phải để ứng dụng có thể kiểm tra được), nhưng chúng tôi đã không sử dụng bất kỳ khuôn khổ nào. Đôi khi nó hơi tẻ nhạt khi kết nối tất cả các phụ thuộc bằng tay, nhưng nhìn chung nó hoạt động rất tốt.

Khi một đối tượng phải được tạo ở nhiều nơi, chúng ta chỉ cần có một hàm (đôi khi là một phương thức lớp của đối tượng đó) để tạo một thể hiện sản xuất. Hàm này được gọi bất cứ khi nào chúng ta cần đối tượng đó.

Trong các thử nghiệm, chúng tôi đã làm một điều tương tự: nếu nhiều lần chúng tôi cần tạo một 'phiên bản thử nghiệm' của một đối tượng (nghĩa là một thể hiện thực được hỗ trợ bởi các đối tượng giả), chúng tôi có chức năng tạo ra 'phiên bản thử nghiệm' này của một lớp, được sử dụng trong các bài kiểm tra.

Như tôi đã nói, nói chung điều này làm việc tốt.

Bây giờ tôi đang tham gia một dự án Java mới và chúng tôi đang quyết định nên sử dụng khung công tác DI hay thực hiện DI thủ công (như trong dự án trước đó).

Vui lòng giải thích cách làm việc với khung DI sẽ khác nhau và trong cách cư xử tốt hơn hoặc xấu hơn so với tiêm phụ thuộc 'vanilla' thủ công.

Chỉnh sửa: Tôi cũng muốn thêm vào câu hỏi: bạn đã chứng kiến ​​bất kỳ dự án 'cấp độ chuyên nghiệp' nào thực hiện DI thủ công mà không có khung chưa?


Bên cạnh câu trả lời của tôi. Cả hai cách đều tương thích. Bạn có thể để tiêm phụ thuộc mềm vào khung và giữ cho các nhà máy của bạn cho các thành phần quan trọng. Các thành phần liên quan đến mô hình hoặc doanh nghiệp.
Laiv

4
Tôi đoán bạn đã kiểm tra, chỉ trong trường hợp bạn không Tại sao chúng ta cần khung cho DI?
Laiv

Câu trả lời:


19

Chìa khóa của container DI là sự trừu tượng . DI container trừu tượng thiết kế này quan tâm cho bạn. Như bạn có thể đoán, nó có tác động đáng chú ý đến mã, thường được dịch sang số lượng ít hơn các nhà xây dựng, setters, nhà máy và nhà xây dựng. Do đó, chúng làm cho mã của bạn được ghép lỏng hơn (do IoC cơ bản ), sạch hơn và đơn giản hơn. Mặc dù không phải không có chi phí.

Hình nền

Nhiều năm trước, sự trừu tượng như vậy đòi hỏi chúng ta phải viết các tệp cấu hình khác nhau ( lập trình khai báo ). Thật tuyệt vời khi thấy số lượng LỘC giảm đáng kể, nhưng trong khi các LỘC giảm, số lượng tệp cấu hình tăng nhẹ. Đối với các dự án vừa hoặc nhỏ thì hoàn toàn không phải là vấn đề, nhưng đối với các dự án lớn hơn, việc "lắp ráp mã" nằm rải rác 50% giữa các mô tả mã và XML đã trở thành một vấn đề trong ... Tuy nhiên, vấn đề chính là mô hình chính nó. Nó khá không linh hoạt bởi vì các mô tả để lại không gian nhỏ cho các tùy chỉnh.

Mô hình chuyển dần sang quy ước về cấu hình , giao dịch các tệp cấu hình cho các chú thích hoặc thuộc tính. Nó giữ cho mã của chúng tôi sạch hơn và đơn giản hơn trong khi cung cấp cho chúng tôi tính linh hoạt mà XML không thể.

Có lẽ, đây là sự khác biệt đáng kể nhất liên quan đến cách bạn làm việc cho đến bây giờ. Ít mã hơn và nhiều phép thuật hơn.

Về mặt nhược điểm...

Quy ước về cấu hình làm cho sự trừu tượng nặng nề đến mức bạn hầu như không biết nó hoạt động như thế nào. Đôi khi có vẻ kỳ diệu và ở đây có thêm một nhược điểm. Khi đã hoạt động, nhiều nhà phát triển không quan tâm đến cách thức hoạt động của nó.

Đây là một điểm chấp cho những người đã học DI với các thùng chứa DI. Họ không hiểu đầy đủ về sự liên quan của các mẫu thiết kế, các thông lệ tốt và các nguyên tắc được trừu tượng hóa bởi container. Tôi đã hỏi các nhà phát triển nếu họ quen thuộc với DI và các ưu điểm của nó và họ trả lời: - Vâng, tôi đã sử dụng Spring IoC -. (Nó có nghĩa là gì?!?)

Người ta có thể đồng ý hoặc không với mỗi "nhược điểm" này. Theo ý kiến ​​khiêm tốn của tôi, cần phải biết những gì đang diễn ra trong dự án của bạn. Mặt khác, chúng ta không có sự hiểu biết đầy đủ về nó. Ngoài ra là để biết DI dùng để làm gì và có một khái niệm về cách thực hiện nó là một điểm cộng cần xem xét.

Về mặt tích cực ...

Năng suất một từ . Các khung cho phép chúng tôi tập trung vào những gì thực sự quan trọng. Ứng dụng của doanh nghiệp.

Mặc dù thiếu sót nhận xét, đối với nhiều người trong chúng ta (công việc được quy định bởi thời hạn và chi phí), những công cụ này là một nguồn tài nguyên vô giá. Theo tôi, đây nên là đối số chính của chúng tôi ủng hộ việc triển khai các thùng chứa DI. Năng suất .

Kiểm tra

Cho dù chúng tôi triển khai DI hoặc container thuần túy, việc kiểm tra sẽ không thành vấn đề. Hoàn toàn ngược lại. Các thùng chứa tương tự thường cung cấp cho chúng tôi các mô hình thử nghiệm đơn vị ra khỏi hộp. Trong những năm qua, tôi đã sử dụng các bài kiểm tra của mình như nhiệt kế. Họ nói với tôi nếu tôi phụ thuộc nhiều vào các cơ sở container. Tôi nói điều này bởi vì các container này có thể khởi tạo các thuộc tính riêng mà không cần setters hoặc constructor. Họ có thể tiêm các thành phần gần như ở bất cứ nơi nào!

Nghe có vẻ hấp dẫn phải không? Hãy cẩn thận! Đừng rơi vào bẫy !!

Gợi ý

Nếu bạn quyết định triển khai các container, tôi thực sự khuyên bạn nên gắn bó với các thông lệ tốt. Tiếp tục thực hiện các hàm tạo, setters và giao diện. Thực thi khung / container để sử dụng chúng . Nó sẽ làm cho việc di chuyển dễ dàng hơn có thể sang khung khác hoặc loại bỏ khung thực tế. Nó có thể làm giảm đáng kể sự phụ thuộc vào container.

Về thực hành này:

Khi nào nên sử dụng container DI

Câu trả lời của tôi sẽ bị thiên vị bởi kinh nghiệm của bản thân, chủ yếu thiên về các thùng chứa DI (như tôi đã nhận xét, tôi tập trung rất nhiều vào năng suất, vì vậy tôi chưa bao giờ có nhu cầu về DI thuần túy. Hoàn toàn ngược lại).

Tôi nghĩ bạn sẽ tìm thấy bài viết thú vị của Mark Seeman về chủ đề này, cũng trả lời câu hỏi liên quan đến cách thực hiện DI thuần túy .

Cuối cùng, nếu chúng ta đang nói về Java, trước tiên tôi sẽ xem xét việc xem xét JSR330 - Dependency Injection .

Tóm tắt

Lợi ích :

  • Cắt giảm chi phí và tiết kiệm thời gian. Năng suất.
  • Một số lượng nhỏ hơn của các thành phần.
  • Mã trở nên đơn giản và sạch sẽ hơn.

Hạn chế :

  • DI được ủy quyền cho libs bên thứ 3. Chúng ta nên nhận thức được sự đánh đổi, điểm mạnh và điểm yếu của họ.
  • Đường cong học tập.
  • Chúng nhanh chóng khiến bạn quên đi một số thói quen tốt.
  • Tăng sự phụ thuộc của dự án (nhiều lib hơn)
  • Các container dựa trên sự phản chiếu đòi hỏi nhiều tài nguyên hơn (bộ nhớ). Điều này rất quan trọng nếu chúng ta bị hạn chế bởi các nguồn lực.

Sự khác biệt với DI thuần túy :

  • Ít mã hơn và nhiều tập tin cấu hình hoặc chú thích.

1
"Các khung này không riêng tư đối với bạn để thực hiện kiểm tra đơn vị hoặc kiểm tra tính toàn vẹn, vì vậy bạn không lo lắng về việc kiểm tra." Chính xác thì điều này có nghĩa là gì? Từ ngữ khiến tôi nghĩ đó là một lỗi đánh máy nhưng tôi gặp khó khăn khi giải mã nó.
candied_orange

Điều đó có nghĩa là thời gian sửa lỗi khó khăn hoặc việc sử dụng các khung để kiểm tra không đủ nhược điểm để loại bỏ việc sử dụng các khung này. Bởi vì ngay cả khi bạn không thích họ, họ vẫn có những lợi ích thực sự đáng để thử. Những nhược điểm lớn không phải là khuôn khổ của chính họ. Là cách bạn sử dụng chúng. Một số thực tiễn tốt như giao diện và setters vẫn được yêu cầu ngay cả khi khung của bạn không. Cuối cùng, có những lib tốt để thử nghiệm tích hợp dễ dàng với các loại Khung (DI) này
Laiv

Nếu đó là những gì bạn muốn xem xét: "Những khung này không ngăn bạn thực hiện kiểm tra đơn vị hoặc kiểm tra tính toàn vẹn, vì vậy đừng lo lắng về cách chúng ảnh hưởng đến kiểm tra"
candied_orange

Srry. Tôi cố gắng nói rằng anh ta sẽ có thể kiểm tra mã của mình ngay cả với các khung này. Mặc dù trừu tượng, thử nghiệm vẫn có thể thực hiện được. Hãy chỉnh sửa câu trả lời của tôi. Như bạn thấy tiếng Anh của tôi vẫn còn khá tốt :-)
Laiv

1
Lưu ý rằng Dagger2 không DI hơi khác. Mã keo được tạo ra tại thời điểm biên dịch như các nguồn Java thông thường, có thể đọc được, vì vậy việc theo dõi cách mọi thứ được dán lại với nhau thay vì phải xử lý ma thuật thời gian chạy đơn giản hơn nhiều.
Thorbjørn Ravn Andersen

10

Theo kinh nghiệm của tôi, một khung tiêm phụ thuộc dẫn đến một số vấn đề. Một số vấn đề sẽ phụ thuộc vào khung và công cụ. Có thể có các thực hành giảm thiểu các vấn đề. Nhưng đây là những vấn đề mà tôi đã gặp phải.

Các đối tượng phi toàn cầu

Trong một số trường hợp, bạn muốn tiêm một đối tượng toàn cục: một đối tượng sẽ chỉ có một thể hiện trong ứng dụng đang chạy của bạn. Đây có thể là một MarkdownToHtmlRendererer, a DatabaseConnectionPool, địa chỉ cho máy chủ api của bạn, v.v. Đối với những trường hợp này, khung tiêm phụ thuộc hoạt động rất đơn giản, bạn chỉ cần thêm phụ thuộc cần thiết vào hàm tạo của mình và bạn đã có nó.

Nhưng những gì về các đối tượng không phải là toàn cầu? Nếu bạn cần người dùng cho yêu cầu hiện tại thì sao? Điều gì nếu bạn cần giao dịch cơ sở dữ liệu hiện đang hoạt động? Điều gì xảy ra nếu bạn cần phần tử HTML tương ứng với div có chứa một biểu mẫu trong đó là một hộp văn bản vừa phát sinh sự kiện?

Giải pháp mà tôi đã thấy được sử dụng bởi các khung DI là các kim phun phân cấp. Nhưng điều này làm cho mô hình tiêm phức tạp hơn. Nó trở nên khó khăn hơn để tìm ra những gì sẽ được tiêm từ lớp nào của hệ thống phân cấp. Sẽ trở nên khó khăn để biết liệu một đối tượng nhất định có tồn tại trên mỗi ứng dụng, mỗi người dùng, mỗi yêu cầu, v.v. Bạn không còn có thể thêm các phụ thuộc của mình và làm cho nó hoạt động.

Thư viện

Thường thì bạn sẽ muốn có một thư viện mã tái sử dụng. Điều này cũng sẽ bao gồm các hướng dẫn về cách xây dựng các đối tượng từ mã đó. Nếu bạn sử dụng khung tiêm phụ thuộc, điều này thường sẽ bao gồm các quy tắc ràng buộc. Nếu bạn muốn sử dụng thư viện, bạn thêm các quy tắc ràng buộc của họ vào thư viện của bạn.

Tuy nhiên, các vấn đề khác nhau có thể dẫn đến. Bạn có thể kết thúc với cùng một lớp bị ràng buộc với các triển khai khác nhau. Thư viện có thể mong đợi các ràng buộc nhất định tồn tại. Thư viện có thể ghi đè một số ràng buộc mặc định khiến mã của bạn làm điều lạ. Mã của bạn có thể ghi đè một số ràng buộc mặc định khiến mã thư viện làm những việc lạ.

Độ phức tạp ẩn

Khi bạn tự viết các nhà máy, bạn có cảm giác làm thế nào các phụ thuộc của ứng dụng khớp với nhau. Khi bạn sử dụng khung tiêm phụ thuộc, bạn không thấy điều này. Thay vào đó, các đối tượng có xu hướng phát triển ngày càng nhiều phụ thuộc hơn cho đến sớm hay muộn mọi thứ phụ thuộc vào khá nhiều thứ.

Hỗ trợ IDE

IDE của bạn có thể sẽ không hiểu khung tiêm phụ thuộc. Với các nhà máy thủ công, bạn có thể tìm thấy tất cả các người gọi của nhà xây dựng để tìm ra tất cả các vị trí mà đối tượng có thể được xây dựng. Nhưng nó sẽ không tìm thấy các cuộc gọi được tạo bởi khung DI.

Phần kết luận

Chúng ta nhận được gì từ một khung tiêm phụ thuộc? Chúng ta phải tránh một số nồi hơi có đầu óc đơn giản cần thiết để khởi tạo các đối tượng. Tôi là tất cả để loại bỏ nồi hơi có đầu óc đơn giản. Tuy nhiên, duy trì nồi hơi có đầu óc đơn giản là dễ dàng. Nếu chúng ta sẽ thay thế cái nồi hơi đó, chúng ta nên nhấn mạnh vào việc thay thế nó bằng một cái gì đó dễ dàng hơn. Do các vấn đề khác nhau mà tôi đã thảo luận ở trên, tôi không nghĩ các khung (ít nhất là khi chúng đứng) phù hợp với dự luật.


Đây là một câu trả lời rất hay, nhưng tôi không thể tưởng tượng được việc sử dụng bộ chứa IoC cho thư viện lớp. Điều đó cảm thấy như thiết kế kém với tôi. Tôi mong đợi một thư viện sẽ yêu cầu tôi cung cấp cho nó bất cứ sự phụ thuộc nào.
RubberDuck

@RubberDuck, trong trường hợp của tôi, tôi đã làm việc cho một công ty lớn với một số lượng lớn các dự án java tất cả được tiêu chuẩn hóa trên cùng một khung tiêm phụ thuộc. Vào thời điểm đó, nó trở nên hấp dẫn đối với một số nhóm xuất khẩu một thư viện dự kiến ​​sẽ được kết hợp bởi khung DI, thay vào đó cung cấp một giao diện bên ngoài hợp lý.
Winston Ewert

Điều đó thật đáng tiếc @WinstonEwert. Cảm ơn đã điền vào bối cảnh cho tôi.
RubberDuck

Nó sẽ là tuyệt vời cho phần IDE, với ràng buộc thời gian chạy của khung tiêm thay vì ràng buộc kiểu thời gian thiết kế của tiêm thủ công. Trình biên dịch ngăn chặn việc tiêm quên khi chúng là thủ công.
Basilevs

IntelliJ hiểu CDI (tiêu chuẩn Java EE DI)
Thorbjørn Ravn Andersen

3

Có phụ thuộc Java + tiêm = khung cần thiết không?

Không.

Khung DI mua gì cho tôi?

Xây dựng đối tượng xảy ra trong một ngôn ngữ không phải là Java.


Nếu các phương thức xuất xưởng đủ tốt cho nhu cầu của bạn, bạn có thể thực hiện DI trong java hoàn toàn khung miễn phí trong java pojo xác thực 100%. Nếu nhu cầu của bạn vượt xa mà bạn có các lựa chọn khác.

Các mẫu thiết kế của Gang of Four hoàn thành nhiều điều tuyệt vời nhưng luôn có điểm yếu khi nói đến các mẫu sáng tạo. Bản thân Java có một số điểm yếu ở đây. Các khung DI thực sự giúp ích cho điểm yếu sáng tạo này nhiều hơn so với việc tiêm thuốc thực tế. Bạn đã biết làm thế nào để làm điều đó mà không có họ. Họ sẽ làm tốt đến mức nào tùy thuộc vào mức độ bạn cần giúp đỡ khi xây dựng đối tượng.

Có rất nhiều mô hình sáng tạo xuất hiện sau Gang of Four. Trình xây dựng Josh Bloch là một bản hack tuyệt vời xung quanh việc thiếu các tham số được đặt tên của java. Ngoài ra, các nhà xây dựng iDSL cung cấp rất nhiều tính linh hoạt. Nhưng mỗi trong số này đại diện cho công việc quan trọng và nồi hơi.

Các khung có thể cứu bạn khỏi một số tedium này. Họ không phải không có nhược điểm. Nếu không cẩn thận, bạn có thể thấy mình phụ thuộc vào khuôn khổ. Hãy thử chuyển đổi khung sau khi sử dụng một cái và tự mình xem. Ngay cả khi bạn bằng cách nào đó giữ xml hoặc chú thích chung chung, bạn vẫn có thể hỗ trợ hai ngôn ngữ cơ bản mà bạn phải đề cập cạnh nhau khi bạn quảng cáo các công việc lập trình.

Trước khi bạn trở nên quá say mê với sức mạnh của các khung DI, hãy dành một chút thời gian và điều tra các khung công tác khác cung cấp cho bạn các khả năng mà bạn có thể nghĩ rằng bạn cần một khung DI cho. Nhiều người đã phân nhánh ra ngoài DI đơn giản . Hãy xem xét: Lombok , AspectJslf4J . Mỗi chồng chéo với một số khung DI nhưng mỗi khung hoạt động tốt.

Nếu thử nghiệm thực sự là động lực thúc đẩy điều này, xin vui lòng xem xét: jUnit (bất kỳ xUnit thực sự nào)Mockito (bất kỳ giả thực sự nào) trước khi bạn bắt đầu nghĩ rằng một khung DI sẽ chiếm lấy cuộc sống của bạn.

Bạn có thể làm những gì bạn thích, nhưng đối với công việc nghiêm túc, tôi thích một hộp công cụ đông dân hơn là một con dao quân đội Thụy Sĩ. Mong muốn nó dễ dàng hơn để vẽ những đường này nhưng một số đã làm việc chăm chỉ để làm mờ chúng. Không có gì sai với điều đó nhưng nó có thể làm cho những lựa chọn này đầy thách thức.


PowerMock đã giải quyết một số trường hợp này. Toàn bộ nó cho phép bạn chế nhạo thống kê
Laiv

Meh. Nếu bạn đang thực hiện DI đúng cách, việc trao đổi một khung công tác IoC Container khác sẽ tương đối đơn giản. Giữ những chú thích đó ra khỏi mã của bạn và bạn sẽ ổn thôi. Về cơ bản, sử dụng bộ chứa IoC để thực hiện DI thay vì sử dụng bộ chứa làm công cụ định vị dịch vụ.
RubberDuck

@RubberDuck đúng. Thiếu kiểm tra và duy trì cơ sở mã của bạn liên tục trong nhiều khung DI, bạn có biết một cách đáng tin cậy đơn giản để kiểm tra xem "bạn đang làm DI đúng cách" không? Ngay cả khi tôi không sử dụng gì ngoài pojo trong java, nếu nỗ lực đáng kể đã tạo ra XML thì đó vẫn không phải là một sự hoán đổi đơn giản khi XML phụ thuộc vào bộ chứa IoC.
candied_orange

@CandiedOrange Tôi đang sử dụng "đơn giản" như một thuật ngữ tương đối. Trong sơ đồ lớn của mọi thứ, thay thế một gốc thành phần khác không phải là một nhiệm vụ quá khó khăn. Một vài ngày làm việc ngọn. Để đảm bảo bạn đang thực hiện DI đúng cách, đó là những gì Code Reviews dành cho.
RubberDuck

2
@RubberDuck hầu hết "gốc thành phần" tôi đã thấy là khoảng 5 dòng mã chính. Vì vậy, không. không phải là một nhiệm vụ quá khó khăn Đó là thứ độc quyền thoát khỏi những dòng mà tôi cảnh báo. Bạn gọi nó là "làm DI đúng cách". Tôi đang hỏi nếu bạn sử dụng những gì để chứng minh một vấn đề trong đánh giá mã. Hay bạn chỉ cần nói "Meh"?
candied_orange

2

Tạo các lớp và gán cho chúng các phụ thuộc là một phần của quy trình mô hình hóa, các phần thú vị. Đó là lý do tại sao hầu hết các lập trình viên thích lập trình.

Quyết định, việc triển khai nào sẽ được sử dụng và cách các lớp được xây dựng là một điều sẽ phải được thực hiện bằng cách nào đó và là một phần của cấu hình ứng dụng.

Nhà máy viết thủ công là một công việc tẻ nhạt. Khung DI làm cho nó dễ dàng hơn bằng cách tự động giải quyết các phụ thuộc có thể được giải quyết và yêu cầu cấu hình cho những phụ thuộc có thể không.

Sử dụng các IDE hiện đại cho phép bạn điều hướng thông qua các phương thức và tập quán của chúng. Có các nhà máy được viết thủ công là khá tốt, bởi vì bạn có thể chỉ cần làm nổi bật hàm tạo của lớp, hiển thị các công dụng của nó và nó sẽ cho bạn thấy tất cả các vị trí và cách thức lớp cụ thể được xây dựng.

Nhưng ngay cả với khung DI, bạn có thể có một vị trí trung tâm, chẳng hạn như cấu hình xây dựng biểu đồ đối tượng (OGCC kể từ bây giờ) và nếu một lớp phụ thuộc vào các phụ thuộc mơ hồ, bạn có thể chỉ cần nhìn vào OGCC và xem cách xây dựng một lớp cụ thể ngay đó

Bạn có thể phản đối, rằng cá nhân bạn nghĩ rằng có thể thấy các tập quán của một nhà xây dựng cụ thể là một điểm cộng tuyệt vời. Tôi muốn nói rằng những gì đi ra tốt hơn với bạn không chỉ chủ quan, mà chủ yếu đến từ kinh nghiệm cá nhân.

Nếu bạn đã luôn làm việc với các dự án dựa trên khung DI, bạn thực sự sẽ chỉ biết điều đó và khi bạn muốn xem cấu hình của một lớp, bạn sẽ luôn xem xét OGCC và thậm chí sẽ không thử xem các nhà xây dựng được sử dụng như thế nào , bởi vì bạn sẽ biết các phụ thuộc đều được kết nối tự động.

Đương nhiên, các khung DI không thể được sử dụng cho mọi thứ và cứ sau đó bạn sẽ phải viết một hoặc hai phương thức xuất xưởng. Một trường hợp rất phổ biến là xây dựng một phụ thuộc trong quá trình lặp qua bộ sưu tập, trong đó mỗi lần lặp cung cấp một cờ khác nhau sẽ tạo ra cách triển khai khác nhau của giao diện chung.

Cuối cùng, rất có thể tất cả sẽ thuộc về sở thích của bạn là gì và bạn sẵn sàng hy sinh điều gì (cả thời gian viết nhà máy hay minh bạch).


Kinh nghiệm cá nhân (cảnh báo: chủ quan)

Nói như một nhà phát triển PHP, mặc dù tôi thích ý tưởng đằng sau các khung DI, tôi chỉ mới sử dụng chúng một lần. Đó là khi một nhóm tôi làm việc cùng được cho là sẽ triển khai một ứng dụng rất nhanh và chúng tôi không thể mất thời gian viết các nhà máy. Vì vậy, chúng tôi chỉ đơn giản chọn một khung DI, cấu hình nó và nó hoạt động, bằng cách nào đó .

Đối với hầu hết các dự án tôi muốn có các nhà máy được viết thủ công vì tôi không thích phép màu đen xảy ra trong khuôn khổ DI. Tôi là người chịu trách nhiệm mô hình hóa một lớp và các phụ thuộc của nó. Tôi là người quyết định tại sao thiết kế trông giống như nó. Vì vậy, tôi sẽ là người xây dựng lớp đúng cách (ngay cả khi lớp có các phụ thuộc cứng, chẳng hạn như các lớp cụ thể thay vì giao diện).


2

Cá nhân tôi không sử dụng DI-container và không thích chúng. Tôi có thêm vài lý do cho việc đó.

Thông thường đó là một phụ thuộc tĩnh. Vì vậy, nó chỉ là một công cụ định vị dịch vụ với tất cả các nhược điểm của nó. Sau đó, do bản chất của phụ thuộc tĩnh, chúng bị ẩn. Bạn không cần phải đối phó với chúng, bằng cách nào đó chúng đã ở đó và điều đó thật nguy hiểm, vì bạn không còn kiểm soát chúng nữa.

phá vỡ các nguyên tắc OOP , chẳng hạn như sự gắn kết và phép ẩn dụ vật thể bằng gạch Lego của David West .

Vì vậy, xây dựng toàn bộ đối tượng càng gần càng tốt với điểm vào của chương trình là cách để đi.


1

Như bạn đã nhận thấy: Tùy thuộc vào ngôn ngữ bạn sử dụng, có nhiều quan điểm khác nhau, khác nhau về cách xử lý các vấn đề tương tự.

Liên quan đến tiêm phụ thuộc, vấn đề này là: tiêm phụ thuộc, như thuật ngữ đã nói, không gì khác hơn là đặt các phụ thuộc mà một đối tượng cần vào đối tượng đó - ngược lại theo cách khác: để cho chính đối tượng tạo ra các thể hiện của các đối tượng mà nó phụ thuộc. Bạn tách rời việc tạo đối tượngtiêu thụ đối tượng để giành chiến thắng linh hoạt hơn.

Nếu thiết kế của bạn được bố trí tốt, bạn thường có một vài lớp có nhiều phụ thuộc, do đó, việc kết nối các phụ thuộc - bằng tay hoặc bằng khung - nên tương đối dễ dàng và số lượng soạn thảo để viết các bài kiểm tra có thể dễ dàng quản lý.

Điều đó nói rằng, không cần phải có DI-framework.

Nhưng tại sao bạn vẫn muốn sử dụng một khung công tác?

I) Tránh mã soạn sẵn

Nếu dự án của bạn có kích thước, nơi bạn cảm thấy đau đớn khi viết các nhà máy (và bản năng) nhiều lần, bạn nên sử dụng khung DI

II) Phương pháp tiếp cận lập trình

Khi Java đã từng lập trình với XML thì bây giờ: rắc câu chuyện cổ tích với các chú thích và điều kỳ diệu xảy ra .

Nhưng nghiêm túc: Tôi thấy rõ ràng lộn ngược này. Bạn rõ ràng truyền đạt ý định bằng cách nói những gì cần thiết thay vì tìm nó ở đâu và làm thế nào để xây dựng nó.


tl; dr

Các khung DI không làm cho cơ sở mã của bạn trở nên tốt hơn một cách kỳ diệu nhưng nó giúp làm cho mã đẹp mắt trông thật sắc nét . Sử dụng nó, khi bạn cảm thấy bạn cần nó. Tại một thời điểm nhất định trong dự án của bạn, nó sẽ giúp bạn tiết kiệm thời gian và ngăn ngừa buồn nôn.


1
Bạn đúng rồi! Tôi có xu hướng lo lắng quá nhiều về cách mọi thứ hoạt động dưới mui xe. Tôi đã có những kinh nghiệm khủng khiếp khi làm việc với các khung mà tôi hầu như không hiểu. Tôi không ủng hộ việc thử nghiệm các khung công tác, chỉ cần hiểu những gì họ làm và cách họ thực hiện (nếu có thể). Nhưng nó phụ thuộc vào lợi ích của riêng bạn. Tôi nghĩ rằng hiểu cách họ làm việc, bạn đang ở một vị trí tốt hơn để quyết định xem họ có phù hợp với bạn không. Ví dụ, cùng một cách bạn sẽ so sánh các ORM khác nhau.
Laiv

1
Tôi nghĩ luôn luôn đúng khi biết cách thức hoạt động của công cụ dưới mui xe. Nhưng nó không nên khiến bạn không biết. Tôi nghĩ rằng điểm bán hàng cho Spring, ví dụ, nó chỉ hoạt động. Và vâng, bạn hoàn toàn đúng, rằng để đưa ra quyết định sáng suốt về việc có nên sử dụng khung hay không, bạn phải có một số mức độ kiến ​​thức. Nhưng tôi thường thấy một mô hình không tin tưởng đối với những người không có vết sẹo giống như mình, mặc dù không phải trong trường hợp của bạn, nơi có niềm tin, chỉ có người có kinh nghiệm săn bắn thủ công mới được phép đi siêu thị.
Thomas Junk

May mắn thay, vào những ngày này, chúng ta thậm chí không cần các khung công tác Spring hoặc DI cho Java. Chúng tôi đã có phiên bản JSR330 đáng buồn bị bỏ qua (ít nhất là tôi đã không thấy một dự án triển khai nó). Vì vậy, mọi người vẫn có thời gian để giành được những vết sẹo của họ :-)
Laiv 16/07/17

Tôi đã chỉnh sửa câu trả lời của mình và tôi đã xem xét ý kiến ​​của bạn. Tôi đã loại bỏ các "nhược điểm" liên quan đến gỡ lỗi. Tôi đi đến kết luận rằng bạn đã đúng về điều đó. Hãy xem và xem xét cập nhật câu trả lời của bạn, bởi vì ngay bây giờ bạn sẽ trích dẫn những phần tôi đã loại bỏ khỏi câu trả lời của tôi.
Laiv

1
Câu trả lời thay đổi quá ít !!! Không có gì khiến bạn phải lo lắng :-). Thông điệp và các đối số vẫn giữ nguyên. Tôi chỉ muốn câu trả lời của bạn tiếp tục như vậy. Tôi đoán Nó chỉ đưa bạn để loại bỏ một trong những trích dẫn.
Laiv

0

Vâng. Có lẽ bạn nên đọc cuốn sách của Mark Seemann có tựa đề "Dependency Injection". Ông phác thảo một số thực hành tốt. Dựa trên một số điều bạn đã nói, bạn có thể được hưởng lợi từ. Bạn nên đặt mục tiêu có một gốc thành phần hoặc một gốc thành phần cho mỗi đơn vị công việc (ví dụ: yêu cầu web). Tôi thích cách nghĩ của anh ấy rằng bất kỳ đối tượng nào bạn tạo đều được coi là một phụ thuộc (như bất kỳ tham số nào đối với phương thức / hàm tạo), vì vậy bạn nên thực sự cẩn thận về vị trí và cách bạn tạo đối tượng. Một khung sẽ giúp bạn giữ các khái niệm này rõ ràng. Nếu bạn đọc cuốn sách của Mark, bạn sẽ tìm thấy nhiều hơn là câu trả lời cho câu hỏi của bạn.


0

Có, khi làm việc trong Java, tôi muốn giới thiệu một khung công tác DI. Có một vài lý do cho việc này:

  • Java có một số gói DI cực kỳ tốt cung cấp tính năng tiêm phụ thuộc tự động và cũng thường được đóng gói với các khả năng bổ sung khó viết thủ công hơn so với DI đơn giản (ví dụ: phụ thuộc phạm vi cho phép kết nối tự động giữa các phạm vi bằng cách tạo mã để tìm phạm vi nên có trong phạm vi nào sử dụng một d tìm phiên bản chính xác của sự phụ thuộc cho phạm vi đó - vì vậy, đối tượng trong phạm vi ứng dụng có thể tham chiếu đến các đối tượng trong phạm vi yêu cầu).

  • chú thích java cực kỳ hữu ích và cung cấp một cách tuyệt vời để cấu hình các phụ thuộc

  • xây dựng đối tượng java quá dài so với những gì bạn đã sử dụng trong python; sử dụng một khung ở đây giúp tiết kiệm nhiều công việc hơn so với ngôn ngữ động.

  • Các khung công tác java DI có thể thực hiện những việc hữu ích như tự động tạo proxy và trang trí, công việc nhiều hơn trong Java hơn là ngôn ngữ động.


0

Nếu dự án của bạn đủ nhỏ và bạn không có nhiều kinh nghiệm với DI-Framework, tôi khuyên bạn không nên sử dụng khung và làm thủ công.

Lý do: Tôi đã từng làm việc trong một dự án sử dụng hai thư viện có phụ thuộc trực tiếp vào các khung di khác nhau. cả hai đều có mã khung cụ thể như di-give-me-an-instance-of-XYZ. Theo như tôi biết, bạn chỉ có thể có một triển khai di-framework hoạt động tại một thời điểm.

với mã như thế này bạn có thể làm hại nhiều hơn lợi ích.

Nếu bạn có nhiều kinh nghiệm hơn, có lẽ bạn sẽ trừu tượng hóa di-framwork bằng một giao diện (nhà máy hoặc người phục vụ) để vấn đề này sẽ không tồn tại nữa và khung di động sẽ có lợi hơn cho tác hại đó.

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.