Các đơn Trách nhiệm Nguyên tắc là bạn thân nhất của mình tại đây.
Trước hết, di chuyển AllFromCache () vào một lớp kho lưu trữ và gọi nó là GetAll (). Rằng nó lấy từ bộ đệm là một chi tiết triển khai của kho lưu trữ và không được biết bởi mã gọi.
Điều này làm cho việc kiểm tra lớp lọc của bạn đẹp và dễ dàng. Nó không còn quan tâm nơi bạn nhận được nó từ.
Thứ hai, bọc lớp lấy dữ liệu từ cơ sở dữ liệu (hoặc bất cứ nơi nào) trong một trình bao bọc bộ đệm.
AOP là một kỹ thuật tốt cho việc này. Đó là một trong số ít những điều mà nó rất giỏi.
Sử dụng các công cụ như PostSharp , bạn có thể thiết lập nó để mọi phương thức được đánh dấu bằng thuộc tính được chọn sẽ được lưu vào bộ đệm. Tuy nhiên, nếu đây là điều duy nhất bạn lưu vào bộ nhớ cache, bạn không cần phải đi xa đến mức có khung AOP. Chỉ cần có một Kho lưu trữ và Bộ đệm ẩn sử dụng cùng một giao diện và đưa nó vào lớp gọi.
ví dụ.
public class ProductManager
{
private IProductRepository ProductRepository { get; set; }
public ProductManager
{
ProductRepository = productRepository;
}
Product FetchById(guid id) { ... }
IList<Product> FilterByPropertry(int property) { ... }
}
public interface IProductRepository
{
IList<Product> GetAll();
}
public class SqlProductRepository : IProductRepository
{
public IList<Product> GetAll()
{
// DB Connection, fetch
}
}
public class CachedProductRepository : IProductRepository
{
private IProductRepository ProductRepository { get; set; }
public CachedProductRepository (IProductRepository productRepository)
{
ProductRepository = productRepository;
}
public IList<Product> GetAll()
{
// Check cache, if exists then return,
// if not then call GetAll() on inner repository
}
}
Xem cách bạn đã xóa kiến thức triển khai kho lưu trữ khỏi ProductManager? Xem thêm cách bạn đã tuân thủ Nguyên tắc Trách nhiệm Đơn lẻ bằng cách có một lớp xử lý trích xuất dữ liệu, một lớp xử lý truy xuất dữ liệu và một lớp xử lý bộ đệm ẩn?
Bây giờ bạn có thể khởi tạo Trình quản lý sản phẩm với một trong các Kho lưu trữ đó và nhận bộ đệm ẩn ... hoặc không. Điều này cực kỳ hữu ích sau này khi bạn gặp một lỗi khó hiểu mà bạn nghi ngờ là kết quả của bộ đệm.
productManager = new ProductManager(
new SqlProductRepository()
);
productManager = new ProductManager(
new CachedProductRepository(new SqlProductRepository())
);
(Nếu bạn đang sử dụng bộ chứa IOC, thậm chí còn tốt hơn. Rõ ràng là làm thế nào để thích nghi.)
Và, trong các bài kiểm tra ProductManager của bạn
IProductRepository repo = MockRepository.GenerateStrictMock<IProductRepository>();
Không cần phải kiểm tra bộ đệm.
Bây giờ câu hỏi trở thành: Tôi có nên kiểm tra Bộ nhớ đệm đó không? Tôi đề nghị không. Bộ nhớ cache khá không xác định. Khung làm việc với nó nằm ngoài tầm kiểm soát của bạn. Giống như, chỉ cần loại bỏ những thứ từ nó khi nó quá đầy, chẳng hạn. Bạn sẽ kết thúc với các bài kiểm tra thất bại một lần trong một mặt trăng xanh và bạn sẽ không bao giờ thực sự hiểu tại sao.
Và, đã thực hiện các thay đổi mà tôi đã đề xuất ở trên, thực sự không có nhiều logic để kiểm tra trong đó. Thử nghiệm thực sự quan trọng, phương thức lọc, sẽ ở đó và được trừu tượng hóa hoàn toàn từ chi tiết của GetAll (). GetAll () chỉ ... có tất cả. Từ nơi nào đó.