2009-10-25 29 views
14

Hãy tưởng tượng loại ứng dụng điển hình mà bạn có danh sách các mục có các thuộc tính khác nhau. Ví dụ. chế độ xem cây với 100 mục, mỗi mục có một tên là , một xếp hạng , một xếp hạng trong vòng-the-nóng nhất-mặt hàng-trên-hành tinh vv Có lẽ cũng có nhiều mối quan hệ nhiều giữa mụcmục-catalog, hoặc giữa mụcmục-người sáng tạo vv vvMẫu thiết kế để lọc một tập hợp các mục?

Bây giờ ứng dụng này một cách tự nhiên cần có một hệ thống lọc. Ví dụ. nơi tôi có thể xây dựng các bộ lọc phức tạp với nhiều điều kiện của tất cả các loại, giữa các dữ liệu trong các mối quan hệ khác nhau.

Nhiệm vụ thiết kế viết tính năng lọc như vậy phải là thứ mà nhiều nhà phát triển đã thực hiện và chắc chắn phải có một số kiểu thiết kế phù hợp nhất cho nhiệm vụ.

Bất kỳ ai?

Chỉnh sửa: Đã chuyển sang wiki cộng đồng vì tôi nghi ngờ không có bất kỳ mẫu yếu tố nào được sử dụng cho ngành này. Câu hỏi quá thường xây dựng tôi đoán.

+0

Bất cứ khi nào bạn đang xem xét các thuật toán thay đổi và cách bạn sắp xếp sẽ là một thuật toán (định nghĩa lỏng lẻo), mẫu chiến lược là giải pháp hợp lý, nhưng thực hiện được mở để tranh luận.

+0

[Mẫu thiết kế bộ lọc có ví dụ] (http://www.singhajit.com/filter-design-pattern/) –

Trả lời

6

Hơi khó để chỉ ra những gì bạn muốn, vì vậy tôi sẽ đưa ra các giả định của riêng mình.

  1. Bộ sưu tập cơ bản nên không thay đổi sau khi lọc
  2. Kết quả là không dai dẳng

Một cách tiếp cận cổ điển là việc sử dụng xem. Đây là cơ bản lập trình lười biếng, nơi bạn tạo một đối tượng có thể truy cập bộ sưu tập gốc và biết bộ lọc để áp dụng nhưng sẽ không thực hiện bất kỳ tính toán nào miễn là không cần thiết.

Trên bộ sưu tập, lượt xem thường được triển khai với trình lặp và để lọc, tất nhiên là một Mẫu chiến lược đã được chỉ ra.

Ví dụ:

Collection myCollection; 
Predicate myFilter; 

// Nothing is computed here 
View<Predicate> myView(myCollection, myFilter); 

// We iterate until we find the first item in the collection that satisfies 
// the Predicate, and no more, to initialize `begin` 
View<Predicate>::Iterator begin = myView.begin(), end = myView.end(); 

Ưu điểm cuối cùng là nếu bạn (nói) chỉ cần 10 mục đầu tiên, sau đó bạn sẽ chỉ áp dụng vị càng nhiều càng cần thiết để tìm những 10 đầu tiên, và không còn nữa.

Ngoài ra, không có bản sao của các yếu tố liên quan và quan điểm của bạn được đảm bảo được cập nhật ngay cả khi bạn sửa đổi myCollection, mặc dù điều này có thể ảnh hưởng đến tính hợp lệ của các trình lặp (như thường lệ).

Vấn đề là (trừ khi bạn triển khai bộ nhớ đệm), kết quả sẽ được tính mỗi lần.

Nếu bạn muốn có kết quả ổn định hơn, thì bạn nên xây dựng một bộ sưu tập mới chỉ chứa các mục được lọc (hoặc tham chiếu đến chúng). Không có mô hình chung ở đây cho nó phụ thuộc vào cách bạn muốn sử dụng danh sách 'đã lọc'.

Đối với Mẫu chiến lược được đề xuất, bạn thường có thể tạo bộ lọc của mình theo khối bằng cách sử dụng Mẫu tổng hợp và sau đó chuyển đối tượng được xây dựng làm chiến lược.

Mẫu hỗn hợp đặc biệt phù hợp để biểu thị kết quả của một biểu thức được phân tích cú pháp, ví dụ, bạn có thể muốn xem các cây biểu thức để có ý tưởng.

+1

Tôi thực sự thích ý tưởng kết hợp mẫu Composite và Chiến lược, cảm ơn! – sharkin

0

Nếu các mối quan hệ này dễ thấy như RDF và OWL, bạn có thể sử dụng công cụ có điểm cuối SPARQL (chẳng hạn như Jena) hoặc một bộ phận lý luận như Pellet. Nhưng không có thêm chi tiết thì không rõ ràng đây là cách tiếp cận tốt nhất.

1

Tôi không biết về mẫu thiết kế, nhưng bạn có thể xem một số phương pháp đã được thực hiện để sắp xếp và sẽ hữu ích nếu bạn giải thích một số lý do và lý do bạn không thích chúng như một ví dụ.

Ví dụ: LINQ có cách tốt để thực hiện sắp xếp, sử dụng cây Biểu thức.

Bạn cũng có thể xem xét phân loại được thực hiện bằng các ngôn ngữ chức năng, nơi bạn có thể chuyển vào hàm để thực sự sắp xếp, thay vì mã hóa cứng bất kỳ loại cụ thể nào.

Nếu bạn đang làm việc trong một cái gì đó như javascript thì chức năng sắp xếp có thể được tạo khi đang di chuyển.

+0

Mẫu chiến lược có thể là một mô hình tốt để xem xét, như là một điểm khởi đầu. –

1

Bạn đang tìm kiếm cơ sở dữ liệu quan hệ, từ đó bạn có thể sử dụng SQL. Bạn có thể đứng lên đầy đủ và kết nối với nó từ ứng dụng của bạn, hoặc bạn có thể làm điều gì đó ở giữa một cơ sở dữ liệu đầy đủ và các đối tượng thẳng. Trong Java, ví dụ, bạn có thể sử dụng một cơ sở dữ liệu trong bộ nhớ như HSQLDB/JavaDB và sử dụng các thành phần đó. Bạn cũng có thể sử dụng JoSQL để cho phép bạn hoạt động trong SQL trực tiếp trên các đối tượng của mình mà không có cơ sở dữ liệu.

Hoặc, nếu bạn muốn tự mình lập chương trình, bạn sẽ bắt đầu bằng cách giữ 2 bản sao dữ liệu của mình. Một là toàn bộ dữ liệu của bạn, cái còn lại là chế độ xem dữ liệu của bạn sau khi lọc. Sau đó, bạn sẽ tạo một chỉ mục trên dữ liệu của bạn cho mỗi cột, bằng cách sắp xếp dữ liệu và giữ vị trí của nó trong danh sách được sắp xếp. Cùng một thiết lập hoạt động cho một bộ lọc phù hợp. Nếu một cái gì đó phù hợp với một bộ lọc cho một cột, cho nó một 1, hoặc 0 nếu không. Sau đó, khi ai đó chuyển thứ tự sắp xếp, bạn sao chép dữ liệu của mình từ danh sách đầy đủ vào danh sách chế độ xem hoặc khi thay đổi thông tin bộ lọc, bạn sẽ chỉ lấy dữ liệu phù hợp.

+0

Tôi thích ý tưởng sử dụng các biểu thức SQL làm cơ sở cho cơ chế lọc. Nếu không, tôi cảm thấy cách tiếp cận này sẽ cấm tôi trừu tượng cơ sở dữ liệu dưới dạng lớp lưu trữ ẩn danh và có thể hoán đổi cho nhau. Đúng nếu tôi sai. – sharkin

1

Tôi thích bộ lọc với biến vị ngữ của Google Collections và tôi sẽ triển khai một cái gì đó rất giống nhau nếu tôi không thể sử dụng nó.Bạn có thể muốn kiểm tra this answer cho một câu hỏi tương tự cho ví dụ triển khai. Việc thực hiện là trong Java nhưng, tốt, bạn sẽ thấy mẫu.

+0

Rất thú vị. Điều đó có vẻ giống như một hình thức của mô hình chiến lược, cũng được chỉ ra bởi James Black. – sharkin

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