Giả sử bạn không tìm kiếm một khung mô phỏng, bởi vì chúng cực kỳ phổ biến và dễ tìm , có một vài điều đáng chú ý phía trước:
- Có "không bao giờ" bất cứ điều gì bạn nên "luôn luôn" làm.
Không phải lúc nào cũng tốt nhất để kết thúc một thư viện bên thứ ba. Nếu ứng dụng của bạn thực chất phụ thuộc vào một thư viện hoặc nếu nó được xây dựng theo nghĩa đen xung quanh một hoặc hai thư viện cốt lõi, đừng lãng phí thời gian của bạn để gói nó. Nếu các thư viện thay đổi, ứng dụng của bạn sẽ cần phải thay đổi .
- Bạn có thể sử dụng các bài kiểm tra tích hợp.
Điều này đặc biệt đúng xung quanh các ranh giới ổn định, nội tại đối với ứng dụng của bạn hoặc không thể dễ dàng bị chế giễu. Nếu những điều kiện đó được đáp ứng, việc gói và chế nhạo sẽ phức tạp và tẻ nhạt. Trong trường hợp đó, tôi sẽ tránh cả hai: không quấn và không chế nhạo; chỉ cần viết bài kiểm tra tích hợp. (Nếu kiểm tra tự động là mục tiêu.)
- Các công cụ và khung có thể loại bỏ sự phức tạp logic.
Về nguyên tắc, một công cụ chỉ có thể cắt giảm nồi hơi. Tuy nhiên, không có thuật toán tự động hóa nào để lấy giao diện phức tạp và làm cho nó đơn giản - hãy để một mình lấy giao diện X và điều chỉnh nó cho phù hợp với nhu cầu của bạn. (Chỉ bạn biết thuật toán đó !) Vì vậy, trong khi chắc chắn có những công cụ có thể tạo ra các hàm bao mỏng, tôi đề nghị rằng chúng không phổ biến vì cuối cùng, bạn vẫn cần mã hóa một cách thông minh, và do đó, bằng tay, đối với giao diện ngay cả khi nó ẩn đằng sau một trình bao bọc.
Điều đó nói rằng, có những chiến thuật bạn có thể sử dụng bằng nhiều ngôn ngữ để tránh tham chiếu trực tiếp đến một lớp học. Và trong một số trường hợp, bạn có thể "giả mạo" một giao diện hoặc trình bao bọc mỏng không thực sự tồn tại. Ví dụ, trong C #, tôi sẽ đi một trong hai tuyến đường:
- Sử dụng một nhà máy và gõ ngầm .
Bạn có thể tránh nỗ lực gói hoàn toàn một lớp phức tạp với combo nhỏ này:
// "factory"
class PdfDocumentFactory {
public static ExternalPDFLibraryDocument Build() {
return new ExternalPDFLibraryDocument();
}
}
// code that uses the factory.
class CoreBusinessEntity {
public void DoImportantThings() {
var doc = PdfDocumentFactory.Build();
// ... i have no idea what your lib does, so, I'm making stuff but.
// but, you can do whatever you want here without explicitly
// referring to the library's actual types.
doc.addHeader("Wee");
doc.getAllText().makeBiggerBy(4).makeBold().makeItalic();
return doc.exportBinaryStreamOrSomething();
}
}
Nếu bạn có thể tránh lưu trữ các đối tượng này với tư cách là thành viên, thông qua cách tiếp cận "chức năng" hơn hoặc bằng cách lưu trữ chúng trong từ điển (hoặc bất cứ điều gì ), phương pháp này có lợi ích của việc kiểm tra kiểu thời gian biên dịch mà không cần các đối tượng kinh doanh cốt lõi của bạn cần biết chính xác họ đang làm việc với lớp nào
Tất cả những gì được yêu cầu là, tại thời điểm biên dịch, lớp được trả về bởi nhà máy của bạn thực sự có các phương thức mà đối tượng kinh doanh của bạn đang sử dụng.
- Sử dụng kiểu gõ động .
Điều này cũng giống như sử dụng cách gõ ngầm , nhưng liên quan đến một sự đánh đổi khác: Bạn mất kiểm tra kiểu biên dịch và có được khả năng thêm ẩn danh phụ thuộc bên ngoài với tư cách là thành viên lớp và tiêm phụ thuộc của bạn.
class CoreBusinessEntity {
dynamic Doc;
public void InjectDoc(dynamic Doc) {
Doc = doc;
}
public void DoImortantThings() {
Doc.addHeader("Wee");
Doc.getAllText().makeBiggerBy(4).makeBold().makeItalic();
return Doc.exportBinaryStreamOrSomething();
}
}
Với cả hai chiến thuật, khi nói đến thời gian để chế nhạo ExternalPDFLibraryDocument
, như tôi đã nói ở trên, bạn có một số việc phải làm - nhưng, nó làm việc bạn cần phải làm nào . Và, với cấu trúc này, bạn đã tránh tẻ nhạt xác định 100 lớp lớp bao bọc nhỏ. Bạn chỉ đơn giản là sử dụng thư viện mà không cần nhìn thẳng vào nó - phần lớn.
Với tất cả những gì đã nói, có ba lý do lớn mà tôi vẫn sẽ xem xét rõ ràng là gói thư viện của bên thứ ba - không có lý do nào gợi ý sử dụng công cụ hoặc khung:
- Thư viện cụ thể không bản chất của ứng dụng.
- Nó sẽ là rất tốn kém để trao đổi mà không gói nó.
- Tôi không thích API.
Nếu tôi không có mối quan tâm cấp độ nào trong cả ba lĩnh vực đó, bạn sẽ không thực hiện bất kỳ nỗ lực đáng kể để bọc lại. Và, nếu bạn có một số lo ngại trong cả ba lĩnh vực, một trình bao bọc mỏng được tạo tự động sẽ không thực sự có ích.
Nếu bạn đã quyết định bọc thư viện, việc sử dụng thời gian hiệu quả và hiệu quả nhất của bạn là xây dựng ứng dụng của bạn theo giao diện bạn muốn ; không chống lại API hiện có.
Đặt một cách khác, chú ý lời khuyên cổ điển: hoãn mọi quyết định bạn có thể. Xây dựng "cốt lõi" của ứng dụng của bạn đầu tiên. Mã chống lại các giao diện cuối cùng sẽ làm những gì bạn muốn, cuối cùng sẽ được thực hiện bởi "công cụ ngoại vi" chưa tồn tại. Cầu những khoảng trống khi cần thiết.
Nỗ lực này có thể không cảm thấy như tiết kiệm thời gian; nhưng nếu bạn cảm thấy bạn cần một cái bọc, đây là cách hiệu quả nhất để làm điều đó một cách an toàn.
Nghĩ theo cách này.
Bạn cần mã hóa thư viện này trong một số góc tối của mã của bạn - ngay cả khi nó được gói lại. Nếu bạn chế nhạo thư viện trong quá trình thử nghiệm, sẽ không thể tránh khỏi nỗ lực thủ công ở đó - ngay cả khi nó được gói lại. Nhưng, điều đó không có nghĩa là bạn cần trực tiếp thừa nhận thư viện đó theo tên trong toàn bộ phần lớn ứng dụng của bạn.
TLD
Nếu thư viện đáng để bọc, hãy sử dụng các chiến thuật để tránh phổ biến, tham chiếu trực tiếp đến thư viện bên thứ 3 của bạn, nhưng không sử dụng phím tắt để tạo các trình bao bọc mỏng. Xây dựng logic kinh doanh của bạn trước tiên, hãy cân nhắc về các giao diện của bạn và xuất hiện các bộ điều hợp của bạn một cách hữu cơ, khi cần thiết.
Và, nếu nói đến nó, đừng sợ các bài kiểm tra tích hợp. Chúng hơi mập hơn một chút, nhưng chúng vẫn đưa ra bằng chứng về mã làm việc và chúng vẫn có thể dễ dàng được thực hiện để giữ hồi quy.