2009-04-22 71 views
6

Tôi đang làm việc trên một dự án giáo dục nhỏ để thực hiện perst.net.Nhiều đối tượng để quan hệ đối tượng trong C#

Chúng tôi có một vấn đề thiết kế nhỏ, đó là cách giải quyết tốt nhất mối quan hệ giữa hai loại đối tượng, đó là người tham giachức vô địch. Đó là quan hệ nhiều với nhiều người tham gia có thể tham gia vào nhiều giải vô địch chức vô địch có thể có nhiều người tham gia .

Hãy tư vấn cách thực hiện điều này tốt nhất trong C#, tôi có nên sử dụng lớp 'kỹ thuật quan hệ DB như' không?

Trả lời

1

Tôi không chắc chắn nếu điều này làm cho thiết kế hoặc yêu cầu của bạn, nhưng nó có thể là có thể ...

Rõ ràng là một mối quan hệ nhiều-nhiều là dễ nhất để đại diện với một đối tượng thứ ba quản lý các mối quan hệ . Trong trường hợp của bạn, nó sẽ là championshipparticipant. Thay vì có một bộ sưu tập trong lớp người tham gia của bạn mà giữ chức vô địch và ngược lại, họ đã giữ một ví dụ cho lớp thứ ba này. Đối tượng championshipparticipant quản lý mối quan hệ này. Sau đó nó có thể được nối tiếp tới cơ sở dữ liệu trực tiếp dưới dạng bảng nối.

4

Bạn có thể có bất kỳ mối quan hệ nào mà một mục cụ thể có thể có nhiều mục được liên kết với nó bằng các thuộc tính IEnumerable (hoặc một số bộ sưu tập khác). Trong ví dụ của bạn, điều này sẽ trông như sau:

class Participant { 
    public IEnumerable<Championship> Championships { 
     get { 
     return _championships; 
     } 
    } 
    private List<Championship> _championships; 
} 

Một số điều quan trọng cần lưu ý:

  • Luôn chắc này một thuộc tính chỉ đọc. Điều này đôi khi gây nhầm lẫn cho mọi người, đặc biệt là nếu bạn có một cái gì đó có thể sửa đổi như một ICollection trả lại chứ không phải là một IEnumerable. Việc chỉ đọc thuộc tính không ngăn thay đổi bộ sưu tập nhưng sửa đổi toàn bộ danh sách toàn bộ danh sách.

  • Tải chiến lược - Bạn sẽ nhận thấy trong ví dụ ở trên bộ sưu tập không được initalized. Bạn thường làm điều này hoặc trong hàm khởi tạo hoặc khi thuộc tính được truy cập lần đầu tiên (gọi là instantiation lazy) - nói chung sự chậm trễ thêm một số phức tạp nhưng có thể tăng hiệu suất, đặc biệt nếu bộ sưu tập này không được sử dụng thường xuyên hoặc bạn có rất nhiều loại tính chất.

  • Nói chung, bạn nên chọn một lớp để "giữ" lớp khác trong trường hợp nhiều người (tức là người tham gia có đặc tính vô địch nhưng giải vô địch không có thuộc tính người tham gia hoặc ngược lại). Điều này giảm bớt số lượng mã bạn phải viết, và làm giảm độ phức tạp và diện tích bề mặt của bạn với cơ sở dữ liệu của bạn. Nếu một cuộc gọi là cần thiết cho các hướng khác, hãy xem xét một cuộc gọi phương pháp chứ không phải là một tài sản. Hãy nhớ rằng, nhiều người từ quan hệ quan hệ không nhất thiết có nghĩa là trường hợp sử dụng phổ biến (Là người dùng, tôi chỉ muốn thêm người tham gia vào giải vô địch chứ không phải giải vô địch cho người tham gia)

  • Nếu bộ sưu tập của bạn là có thể sửa đổi, hãy nhớ rằng việc gửi Lưu ngụ ý rằng các bộ sưu tập bên dưới nó cũng phải được sửa đổi nếu chúng được thay đổi.Điều này có thể làm tăng thêm sự phức tạp (Trong quá khứ, tôi đã sử dụng danh sách nội bộ để lưu trữ các mục đã thêm/xóa)

+0

Wow. Great anwser. –

8

Nếu bạn đang tìm cách tiếp cận hướng đối tượng (hoặc thiết kế theo tên miền) một đối tượng thứ ba để xử lý 'tham gia' là hoàn toàn sai lầm để đi về điều này. Bạn có thể sử dụng ILists/Enumerables với các phương thức Thêm ... để xử lý việc này như sau:

public class Participant 
{ 
    private readonly IList<Championship> _championships = new List<Championship>(); 

    public IEnumerable<Championship> Championships 
    { 
     get { return _championships; } 
    } 

    internal void AddChampionship(Championship championship) 
    { 
     if (!_championships.Contains(championship)) 
      _championships.Add(championship); 
    } 
} 

public class Championship 
{ 
    private readonly IList<Participant> _participants = new List<Participant>(); 

    public IEnumerable<Participant> Participants 
    { 
     get { return _participants; } 
    } 

    public void AddParticipant(Participant participant) 
    { 
     if (_participants.Contains(participant)) return; 
     _participants.Add(participant); 
     participant.AddChampionship(this); 
    } 
} 

Chìa khóa ở đây là đảm bảo bạn quản lý mối quan hệ từ một phía - ví dụ: trong trường hợp này sẽ là bằng cách gọi championship.AddParticipant()

+1

Câu trả lời hay! Tuyên bố cuối cùng là rất quan trọng ... bạn nên làm cho nó táo bạo phải đối mặt! +1 – Cerebrus

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