Quá nhiều phụ thuộc có thể chỉ ra rằng chính lớp đang làm quá nhiều. Để xác định xem nó có làm quá nhiều không:
Bằng cách nhìn vào các phụ thuộc thực tế, tôi không thấy bất cứ điều gì có thể là dấu hiệu của những điều xấu xảy ra:
IDbContextFactory - tạo bối cảnh cho cơ sở dữ liệu.
OK, có lẽ chúng ta đang ở trong một lớp nghiệp vụ nơi các lớp tương tác với lớp truy cập dữ liệu. Nhìn ổn.
IMapper - Ánh xạ từ các thực thể đến các mô hình miền.
Thật khó để nói bất cứ điều gì mà không có bức tranh tổng thể. Có thể kiến trúc đã sai và việc ánh xạ phải được thực hiện trực tiếp bởi lớp truy cập dữ liệu hoặc có thể kiến trúc đó hoàn toàn ổn. Trong mọi trường hợp, nó có ý nghĩa để có sự phụ thuộc này ở đây.
Một lựa chọn khác là chia lớp thành hai: một xử lý ánh xạ, lớp còn lại xử lý logic nghiệp vụ thực tế. Điều này sẽ tạo ra một lớp thực tế sẽ tách BL ra khỏi DAL. Nếu ánh xạ là phức tạp, nó có thể là một ý tưởng tốt. Trong hầu hết các trường hợp, mặc dù, nó sẽ chỉ thêm sự phức tạp vô dụng.
IClock - Tóm tắt DateTime. Làm thế nào để giúp kiểm tra đơn vị.
Có lẽ không hữu ích lắm khi có một giao diện (và lớp) riêng biệt chỉ để có được thời gian hiện tại. Tôi chỉ đơn giản là sẽ chuyển DateTime.Now
các phương thức đòi hỏi thời gian hiện tại.
Một lớp riêng biệt có thể có ý nghĩa nếu có một số thông tin khác, như múi giờ hoặc phạm vi ngày, v.v.
IPerformanceFactory - đo thời gian thực hiện cho các phương thức cụ thể.
Xem điểm tiếp theo.
ILog - Log4net để đăng nhập.
Chức năng siêu việt như vậy phải thuộc về khung và các thư viện thực tế phải có thể thay thế và cấu hình được khi chạy (ví dụ thông qua app.config trong .NET).
Thật không may, đây không phải là (chưa), cho phép bạn chọn một thư viện và gắn bó với nó, hoặc tạo một lớp trừu tượng để có thể trao đổi các thư viện sau này nếu cần. Nếu ý định của bạn là đặc biệt độc lập với sự lựa chọn của thư viện, hãy thực hiện nó. Nếu bạn khá chắc chắn rằng bạn sẽ tiếp tục sử dụng thư viện trong nhiều năm, đừng thêm một sự trừu tượng.
Nếu thư viện quá phức tạp để sử dụng, một mẫu mặt tiền có ý nghĩa.
ICollectionWrapperFactory - Tạo các bộ sưu tập (mở rộng IEnumerable).
Tôi giả định rằng điều này tạo ra các cấu trúc dữ liệu rất cụ thể được sử dụng bởi logic miền. Nó trông giống như một lớp tiện ích. Thay vào đó, sử dụng một lớp cho mỗi cấu trúc dữ liệu với các hàm tạo có liên quan. Nếu logic khởi tạo hơi phức tạp để phù hợp với hàm tạo, hãy sử dụng các phương thức tĩnh của nhà máy. Nếu logic thậm chí còn phức tạp hơn, hãy sử dụng nhà máy hoặc mẫu xây dựng.
IQueryFilterFactory - Tạo các truy vấn dựa trên đầu vào sẽ truy vấn db.
Tại sao không phải là trong lớp truy cập dữ liệu? Tại sao có một Filter
trong tên?
IIdentityHelper - Truy xuất người dùng đã đăng nhập.
Tôi không chắc tại sao lại có Helper
hậu tố. Trong mọi trường hợp, các hậu tố khác sẽ không đặc biệt rõ ràng ( IIdentityManager
?)
Dù sao, nó có ý nghĩa hoàn hảo để có sự phụ thuộc này ở đây.
IFaultFactory - Tạo FaultExceptions khác nhau (Tôi sử dụng WCF).
Nó logic phức tạp đến mức nó đòi hỏi phải sử dụng một mô hình nhà máy? Tại sao Dependency Injection được sử dụng cho điều đó? Bạn có thể trao đổi việc tạo ra các ngoại lệ giữa mã sản xuất và thử nghiệm không? Tại sao?
Tôi sẽ cố gắng cấu trúc lại thành đơn giản throw new FaultException(...)
. Nếu một số thông tin toàn cầu nên được thêm vào tất cả các ngoại lệ trước khi truyền chúng cho khách hàng, WCF có thể có một cơ chế trong đó bạn bắt được một ngoại lệ chưa được xử lý và có thể thay đổi và chia sẻ lại cho khách hàng.
Đo lường chất lượng bằng các con số thường tệ như được trả bằng các dòng mã bạn viết mỗi tháng. Bạn có thể có một số lượng lớn các phụ thuộc trong một lớp được thiết kế tốt, vì bạn có thể có một lớp nhảm nhí bằng cách sử dụng một vài phụ thuộc.
Rất nhiều phụ thuộc làm cho logic khó theo dõi hơn. Nếu logic khó theo dõi, lớp có lẽ đang làm quá nhiều và nên được chia.