2014-07-12 20 views
5

Tôi có một lớp, chứa một số chi tiết trong cấu trúc dữ liệu lớn, chấp nhận thuật toán để thực hiện một số phép tính trên đó, có phương pháp xác thực đầu vào cho cấu trúc dữ liệu. Nhưng sau đó tôi muốn trả về cấu trúc dữ liệu, để nó có thể được chuyển đổi thành các dạng đầu ra khác nhau (chuỗi/C# DataTable/đầu ra tệp tùy chỉnh) bởi Mô hình Xem.Thiết kế OO - Hiển thị chi tiết triển khai thông qua giao diện

class MyProductsCollection { 
    private IDictionary<string, IDictionary<int, ISet<Period>>> products; 

    // ctors, verify input, add and run_algorithm methods 
} 

Tôi biết rằng bạn có nghĩa vụ phải sử dụng nguyên tắc thiết kế "phụ thuộc vào giao diện không triển khai", vì vậy tôi muốn tạo giao diện cho lớp học.

Làm cách nào để tránh viết giao diện sau? Lý do là nó sẽ hiển thị chi tiết triển khai và ràng buộc bất kỳ triển khai cụ thể nào khác để trả về cùng một biểu mẫu.

interface IProductsCollection { 
    IDictionary<string, IDictionary<int, ISet<IPeriod>>> GetData(); 
    // other methods 
} 

Làm cách nào tôi có thể dễ dàng lặp lại cấu trúc dữ liệu để tạo các loại kết quả đầu ra khác nhau mà không để lộ nó như thế này?

EDIT:

Kể từ khi lớp mất trong IFunc<IDictionary<string, IDictionary<int, ISet<IPeriod>>>> trong constructor để lặp qua các cấu trúc dữ liệu và thực hiện các phép tính, tôi có thể cung cấp nó với IFunc khác, trong đó sẽ xây dựng đầu ra thay vì tính toán chạy. Tuy nhiên, tôi không biết làm thế nào tôi có thể làm điều này ngoài việc xây dựng lớp bê tông.

+0

Sử dụng lớp trừu tượng và phương pháp ảo. Các lớp trừu tượng cũng là * giao diện *. – pasty

Trả lời

2

Cấu trúc của IDictionary<string,IDictionary<int,ISet<Period>>> thực sự rất đáng ngờ - khi bạn thấy từ điển từ điển, cơ hội tốt là bạn đã bỏ lỡ một hoặc hai cơ hội để tạo lớp để đóng gói từ điển bên trong.

Không biết nhiều về miền của vấn đề của bạn, tôi khuyên bạn nên xác định giao diện để đóng gói từ điển bên trong. Nó trông giống như một cái gì đó liên kết một số thành một tập hợp các giai đoạn, do đó bạn sẽ xác định một giao diện như thế này:

interface IYearlyPeriods { 
    bool HasPeriodsForYear(int year); 
    ISet<Periond> GetPeriodsForYear(int year); 
} 

Tôi không có ý tưởng những gì trong các giai đoạn, vì vậy bạn sẽ cần phải chọn một tên miền cụ thể cho giao diện.

Hơn nữa, bạn có thể quấn một tầm cao mới của IDictionary quá:

interface IProductDataSource { 
    IEnumerable<string> ProductNames { get; } 
    IYearlyPeriods GetProductData(string productName); 
} 

Bây giờ bạn có thể định nghĩa một giao diện như thế này:

interface IProductsCollection { 
    IProductDataSource GetDataSource(); 
    // other methods 
} 

Ý tưởng chính là sử dụng giao diện miền cụ thể trong nơi các bộ sưu tập chung chung, để người đọc và người thực hiện mã của bạn sẽ có một số ý tưởng về nội dung bên trong mà không đề cập đến tài liệu.

Bạn có thể đi xa hơn nữa và thay thế IDictionary bằng cấu trúc phức tạp mà bạn giữ bên trong bằng cách thực hiện IDictionary của việc thực hiện IProductPeriods. Nếu bạn muốn giữ IYearlyPeriods rằng bạn tiếp xúc với người dùng không thay đổi, nhưng muốn có thể tự sửa đổi, bạn có thể thực hiện thay đổi có thể thay đổi và giữ nó internal cho lớp triển khai.

+0

Cấu trúc dữ liệu ánh xạ tên sản phẩm (chuỗi) vào một số dữ liệu hàng năm (IDictionary thứ hai). Điều này lần lượt ánh xạ một năm (int) đến một số dấu chấm (bộ). Bản thân các giai đoạn chỉ là một lớp giả với các thuộc tính: số kỳ (int) và số tiền (gấp đôi). – oskarm

0

Tôi khuyên bạn nên giữ riêng tư IDictionary và cung cấp IEnumerable đơn giản trong giao diện.

Trong trường hợp của bạn, đây có thể là một DTO tùy chỉnh ẩn tất cả sự khó chịu của IDictionary<int, ISet<IPeriod>> - vốn khá phức tạp và có thể dễ dàng thay đổi khi bạn cần triển khai các tính năng mới.

Đây có thể là một cái gì đó như:

class ExposedPeriod 
{ 
     public int PeriodIdentifier { get; set; } 
     public IEnumerable<IPeriod> Periods { get; set; } 
} 

Các ExposedPeriodPeriodIdentifier lẽ cần tên tốt hơn mặc dù. Tên tốt có thể được tìm thấy trong từ vựng tên miền của bạn.

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