2012-08-15 25 views
7

Tôi muốn khởi tạo Tài khoản người dùng. Tôi có thể sử dụng một nhà máy như thế này:Google Guice không chỉ là một Nhà máy khác?

public class UserFactory { 
    public User newUser(UserType type) { 
    if (type == UserType.FREE) return new FreeUser(); 
    } 
} 

User user = UserFactory.newUser(UserType.FREE); //UserType.FREE is an enum 

Bây giờ nếu tôi sử dụng Google Guice, tôi phải viết một "module":

public class UserModule extends AbstractModule { 

    public voidSetType(UserType type) { 
    this.type = type; 
    } 

    @Override 
    protected void configure() { 
    if (this.type = UserType.FREE) 
     bind(User.class).to(FreeUser.class); 
    else bind ..... 
    } 
} 

Sau đó, đây là mã khách hàng:

Injector injector = Guice.createInjector(new UserModule().setType(UserType.FREE))); 

Câu hỏi của tôi là: Thay vì viết một lớp nhà máy, tôi phải viết một lớp học mô-đun. Và từ ví dụ trên, tôi không thấy bất kỳ lợi thế nào. Phản hồi sử dụng lớp Mô-đun, nó chậm hơn câu lệnh gán của tôi trong lớp nhà máy. Lớp Mô-đun không đơn giản hơn lớp nhà máy. Thay vì duy trì nhà máy, tôi phải duy trì mô-đun.

Lợi thế thực sự là gì? Google Guice không chỉ là một lớp nhà máy khác?

Trả lời

8

Bạn không thấy lợi thế khi Guice (Dependency Injection) không được thiết kế để thay thế factories. Nó có thể làm cho một mức độ hạn chế (xem AssistedInject và nhà cung cấp) nhưng nếu bạn có logic trong nhà máy của bạn thì nó không chắc rằng bạn sẽ có thể sử dụng Guice như là một thay thế trực tiếp.

Cách Guice cho điều này sẽ vẫn còn có một nhà máy và Guice sẽ tiêm nhà máy. Bây giờ người dùng âm thanh như một đối tượng tên miền, và rất có thể không yêu cầu một cây phụ thuộc tiêm Guice. Nếu có thì nhà máy phải được Guice biết và có thể lấy Provider s cho từng loại Người dùng hoặc có quyền truy cập trực tiếp vào Tiêm để tạo đối tượng Người dùng bằng cách sử dụng khác nhau Key s.

DI là tất cả về cây phụ thuộc. Nhà máy là tất cả về sản xuất các đối tượng mà không có người gọi phải quan tâm về cách đối tượng đó được thực hiện. Họ đã vượt qua và có thể được sử dụng cùng nhau, nhưng họ đang giải quyết các vấn đề khác nhau.

0

Bạn có thực sự cần "UserType" không?

xem xét việc này:

class FreeUser extends User {...} 
class NonFreeUser extends User {...} 

void configure() { 
    // if Type=Free 
    bind(User.class).annotatedWith(Free.class).to(FreeUser.class); 
    // else 
    bind(User.class).to(NonFreeUser.class) 
} 

và sau đó

class SomeClassThatNeedsAFreeUser { 
    @Inject 
    @Free 
    private User user; 

} 

vì vậy khi bạn sử dụng injector.getInstance (SomeClassThatNeedsAFreeUser.class), bạn sẽ nhận được một Instance tự động có một FreeSUer tiêm ... Tôi nghĩ rằng đây là một cách tiếp cận tốt hơn nhiều so với khớp nối chặt chẽ thông qua các nhà máy cụ thể.

+0

Mã giả bằng tay, sẽ không biên dịch trừ khi bạn sửa các phần còn thiếu –

+0

Tôi cần UserType vì tôi muốn người dùng chọn loại tài khoản họ muốn đăng ký. Nếu họ chọn Miễn phí thì trình duyệt sẽ gửi thông số "Miễn phí", đó là một chuỗi, nó không an toàn, vì vậy tôi sẽ chuyển nó thành enum. –

2

Guice chắc chắn KHÔNG chỉ là một nhà máy. Nó được thiết kế để giảm bớt sự sôi nổi của việc xây dựng cộng tác viên trong hệ thống, và để phân chia trách nhiệm tạo ra sự phụ thuộc của những cộng tác viên đó. Lý do cho điều này bao gồm:

  1. Giảm mã boilerplate (nếu bạn làm điều đó đúng)
  2. Dependencies được trừu tượng, và như vậy có thể được hoán đổi ở tại địa chỉ:
    • thời gian thử nghiệm - giả/mô hình triển khai/bài có thể được đổi chỗ trong
    • thời gian chạy - triển khai thay thế có thể được đổi chỗ khi các tính năng thay đổi.
  3. nguyên tắc thiết kế cân nhắc như "Giao diện Tách riêng" và "Trách nhiệm Single"

Như câu trả lời khác nói, có chéo giữa phụ thuộc-phun và nhà máy - cả hai đều liên quan đến đối tượng là quản lý và có họ các phụ thuộc được thỏa mãn bởi một hệ thống bên ngoài, nhưng chúng hoạt động khác nhau. Trong trường hợp này, bạn sẽ muốn nhà máy. Nhưng với Dependency-Injection, nếu bạn có rất nhiều nhà máy yêu cầu nhau hoạt động đúng cách, bạn có thể có một khung tiêm phụ thuộc như Guice quản lý sự phụ thuộc lẫn nhau của các nhà máy mà không cần nhiều mã số bằng tay và các bản mẫu khác.

Tôi có xu hướng muốn chia nhỏ những phụ thuộc tồn tại thành một vài loại khác nhau và chỉ xem xét việc tiêm cho một số loại.

 
+======================+=============================+====================+ 
| Type     | Note      | Inject?   | 
+======================+=============================+====================+ 
| Static Dependencies | Inherited types    | N/A    | 
+----------------------+-----------------------------+--------------------+ 
| Collaborators  | Services, Factories, etc. | Definitely   | 
+----------------------+-----------------------------+--------------------+ 
| Configuration  | Context      | Maybe - be careful | 
+----------------------+-----------------------------+--------------------+ 
| Consumables/Data  | Value types     | No - use factories | 
+======================+=============================+====================+ 

Tất nhiên, không có quy tắc cứng và nhanh, nhưng nói chung, tôi cố gắng không tiêm các loại giá trị, trừ khi họ đang được sử dụng bất biến như bối cảnh cho toàn bộ phạm vi của các đối tượng phụ thuộc.

Vì vậy, việc sử dụng loại Người dùng làm ngữ cảnh, cho biết yêu cầu là tốt, nhưng chỉ khi nó không thay đổi và được cung cấp dưới dạng "ngữ cảnh chung" cho tất cả các đối tượng có phạm vi yêu cầu đó. Nhưng nếu tôi có ý định hoạt động trên Người dùng đó, tôi sẽ quản lý nó với các nhà máy, có lẽ trong một quy trình/yêu cầu công việc riêng biệt khác.

Tự động chèn phụ thuộc tự động là điều tuyệt vời để quản lý cộng tác viên, dịch vụ, lớp tiện ích - phần lớn ứng dụng của bạn. Bạn có thể, tất nhiên, đưa nó xuống mức vi mô, nhưng bạn cần phải khá cẩn thận để không đi quá điên với điều đó, hoặc để nhận thức được sự cân bằng trong sự phức tạp. Có, mã của bạn sẽ trở nên phổ biến hơn và có thể tái sử dụng và trừu tượng hơn - nhưng cũng có hiệu ứng sẽ có ít nguyên nhân rõ ràng hơn (lỗi bây giờ có thể là kết quả khởi tạo sớm hơn trong hệ thống đang chạy), luồng của bạn sẽ ít tuyến tính hơn và mã của bạn có vẻ huyền diệu hơn.

Nếu bạn thấy mình viết nhiều mã mô-đun hơn bạn đang tiết kiệm từ hệ thống dây dẫn thủ công, hãy xem xét lại thiết kế của bạn.

Ghi chú bên: 1. Bạn có thể lấy được khuôn khổ Guice và Dependency-Injection bằng cách tái cấu trúc các nhà máy và mã dây đến mức cực đoan, nhưng các nhà máy được đặc biệt định nghĩa để quản lý các lớp cụ thể - Guice theo định nghĩa chung. thay thế một số loại nhà máy. Các nhà máy lò hơi tinh khiết, có lẽ. 2. Bạn có thể tiêm các loại giá trị bằng cách tiêm, nhưng bạn gặp khó khăn - kiểu giá trị (đối tượng miền) có thể yêu cầu chu kỳ phụ thuộc hợp pháp, mà Guice và những người khác không thực sự dự định, mặc dù chúng hỗ trợ nó. Bạn đang chơi với lửa, nhưng trong một hệ thống mà mọi người đều hiểu được phong cách và cách tiếp cận, nó có thể mạnh mẽ. Sử dụng hết sức thận trọng.

Các vấn đề liên quan