7

Tôi đang thực hiện một số công việc R & D và khám phá các mẫu thiết kế. Gần đây tôi đã đọc lên mẫu Đặc điểm kỹ thuật và được giới thiệu đến this bài viết tuyệt vời.So sánh Mô hình Đặc điểm, Func <T,bool> Cung cấp và Ống và Bộ lọc

Tôi bị hấp dẫn bởi sự đơn giản và sạch sẽ của mã, nhưng tôi bắt đầu vẽ một số so sánh để thực hiện cùng một sự sạch sẽ bằng các kỹ thuật khác.

Hãy xem xét các hợp đồng giao sau cho một lớp dịch vụ:

public interface IFooDataService 
{ 
    ICollection<Foo> GetFoosBySpecification(Specification<Foo> specification); 
    ICollection<Foo> GetFooByPredicate(Func<Foo,bool> predicate); 
    ICollection<Foo> GetFooBySearchArgs(FooSearchArgs searchArgs); 
} 

điểm Vì vậy, một số ban đầu:

  • Cả ba trở lại một bộ sưu tập của Foo đối tượng
  • Cả ba lấy một đối số duy nhất
  • Phương pháp đặc điểm hạn chế quyền truy cập vào các yêu cầu cụ thể
  • phương pháp Predicate có về cơ bản không có phương pháp hạn chế
  • Tìm kiếm args hạn chế quyền truy cập vào các yêu cầu cụ thể

Bây giờ, vào việc thực hiện:

public ICollection<Foo> GetFoosBySpecification(Specification<Foo> specification) 
{ 
    return fooDataRepository 
      .Find() 
      .Where(f => specification.IsSatisfiedBy(f)) 
      .ToList(); 
} 

public ICollection<Foo> GetFooByPredicate(Func<Foo, bool> predicate) 
{ 
    return fooDataRepository 
      .Find() 
      .Where(predicate) 
      .ToList(); 
} 

public ICollection<Foo> GetFooBySearchArgs(FooSearchArgs searchArgs) 
{ 
    return fooDataRepository 
      .Find() 
      .WhereMeetsSearchCriteria(searchArgs) 
      .ToList(); 
} 

điểm tình hình thực hiện:

  • Cả ba cực kỳ đơn giản trong thực hiện (một dòng mã chuỗi)
  • Spe cification và Search Args được lọc thực hiện bên ngoài.
  • Tìm kiếm args phương pháp đơn giản là sử dụng phương pháp mở rộng IEnumerable để kiểm tra args

Vì vậy, điều đó đang được nói, dưới những điều kiện nào bạn sẽ sử dụng một trong 3 kỹ thuật trên?

những suy nghĩ của tôi về Đặc điểm kỹ thuật Pattern:

  • đẹp ở chỗ nó phân lập doanh nghiệp/yêu cầu miền thành các thành phần tái sử dụng
  • Vô cùng dễ đọc, làm cho mã nói tiếng Anh
  • chút Fair mã liên quan (giao diện , các lớp trừu tượng). Nếu tôi đã sử dụng này, tôi sẽ đặt abstractions trong một hội đồng chung (vì vậy tôi không có một loạt các tập tin tĩnh trong giải pháp của tôi).
  • Dễ thay đổi các yêu cầu bằng cách chỉ thay đổi đặc điểm kỹ thuật chứ không phải lớp dịch vụ.
  • tối cao testability của logic miền (kỹ thuật)

những suy nghĩ của tôi về phương pháp mở rộng (Ống & Filters):

  • 'nặng' trong logic, nhưng vẫn cho kết quả trong cùng đơn giản.
  • truy vấn logic Cô lập từ lớp dịch vụ cho phương pháp tĩnh
  • Tuy nhiên đòi hỏi "phản ánh" của loại (kiểm tra args tìm kiếm cung cấp và xây dựng truy vấn)
  • Cho phép bạn cấu trúc mã (kho, lớp dịch vụ) đầu tiên, mà không cần suy nghĩ về các yêu cầu kinh doanh cụ thể (đó là tiện dụng trong tình huống nhất định)

những suy nghĩ của tôi trên Predicate Phương pháp:

  • thể được sử dụng khi bạn cần đồng hạt thô ntrol qua các truy vấn.
  • Tốt cho các dự án nhỏ, nơi thông số kỹ thuật có thể được quá trớn nó

My thức tư duy logic là rằng nếu bạn đang làm việc trên một ứng dụng kinh doanh phức tạp, nơi yêu cầu kinh doanh được gọi lên phía trước nhưng có thể thay đổi theo thời gian, sau đó tôi sẽ sử dụng mẫu Đặc điểm kỹ thuật. Tuy nhiên, đối với một ứng dụng là "khởi động", nghĩa là các yêu cầu sẽ phát triển theo thời gian và có vô số cách để truy xuất dữ liệu mà không cần xác thực phức tạp, tôi sẽ sử dụng các phương thức Pipes and Filters.

Suy nghĩ của bạn là gì? Có ai trong số các bạn gặp vấn đề với bất kỳ phương pháp nào ở trên không? Bất kỳ đề xuất?

Bắt đầu một dự án mới để những loại cân nhắc này là rất quan trọng.

Cảm ơn sự giúp đỡ.

EDIT cho rõ về Đặc điểm kỹ thuật mô hình

Đây là cùng sử dụng các mô hình kỹ thuật.

Specification<Foo> someSpec; // Specification is an abstract class, implementing ISpecification<TEntity> members (And, Or, Not, IsSatisfiedBy). 
someSpec = new AllFoosMustHaveABarSpecification(); // Simple class which inherits from Specification<Foo> class, overriding abstract method "IsSatisfiedBy" - which provides the actual business logic.  
ICollection<Foo> foos = fooDataService.GetFoosBySpecification(someSpec); 
+0

Không hoàn toàn rõ ràng cách 'Đặc điểm kỹ thuật ' khác với 'Func '. – Gabe

+0

@Gabe - tôi không muốn đăng mã về cách mô hình đặc tả được triển khai, như a) rất nhiều mã (4 lớp) và b) liên kết mà tôi cung cấp cung cấp chi tiết triển khai. – RPM1984

+0

Tôi đã đọc liên kết; Tôi không thấy sự khác biệt ngữ nghĩa. – Gabe

Trả lời

2

Từ kinh nghiệm nhỏ của tôi:

  1. yêu cầu tài luôn luôn thay đổi và tôi không biết tại sao ông chủ của tôi luôn cho phép những thay đổi sắp tới. Vì vậy, +1 đến Đặc điểm kỹ thuật
  2. Lập trình viên ở đây giống như "công nhân thủ công" hơn là "nhân viên tri thức". Bạn biết đấy .. người gõ cả ngày. Bằng cách sử dụng đặc điểm kỹ thuật, tôi có thể đảm bảo bản thân mình rằng tất cả mọi người "loại". Điều này được hỗ trợ bởi bản chất của dự án của tôi. Nó cần nhiều triển khai khác nhau cho cùng một mục đích. Đừng hỏi tôi tại sao.
  3. Sử dụng mẫu thiết kế mang lại cho bạn tính mô đun và tính linh hoạt cao nhất và khả năng kiểm tra của khóa học. Đây là một câu chuyện nhỏ.
    Trong một ngày tốt lành, người bạn đời của tôi nói với tôi rằng ông đã viết một lớp học cho phép chúng tôi tính toán 32 loại cách tính X. Và ông đã thực hiện tất cả những điều đó. Hoho, đó là một chương trình anh hùng như tôi nghĩ.Anh đã dành vài tuần để làm điều đó vào giữa đêm. Anh tin rằng anh là một lập trình viên giỏi nên anh khăng khăng đòi mọi người sử dụng kiệt tác của mình.
    Chúng tôi, vào thời điểm đó, không quan tâm đến thử nghiệm đơn vị nên chúng tôi đã sử dụng kiệt tác của anh ấy. Chuyện gì đã xảy ra? Mã luôn luôn bị hỏng. Vâng, từ thời điểm đó tôi nhận ra tầm quan trọng của bài kiểm tra đơn vị và mô đun.
0

Vâng, đầu tiên tôi muốn viết phương pháp Predicate, ngay cả khi nó chỉ được sử dụng như một chi tiết thực hiện riêng cho hai người kia:

private ICollection<Foo> GetFoosBySpecification(Specification<Foo> spec) 
{ 
    return GetFooByPredicate(f => spec.IsSatisfiedBy(f)); 
} 

Chức năng lập luận tìm kiếm sẽ là một one- tương tự lót.

Ngoài ra, tôi thực sự không thể nói bất cứ điều gì trong tóm tắt. Tôi phải biết thêm về cấu trúc dữ liệu để quyết định cách tốt nhất để tìm kiếm chúng.