2014-04-15 14 views
6

Cho phép giả định rằng tôi có một lớp POCO chứa foosbars:POCOs và tiện ích phương pháp

public class Poco { 
    public IEnumerable<Foo> Foos { get { return foos; } } 
    public IEnumerable<Bar> Bars { get { return bars; } } 

    private List<Foo> foos; 
    private List<Bar> bars; 
} 

Trong ví dụ của tôi, tôi cần để có thể thêm và loại bỏ foosbars:

public class Poco { 
    public IList<Foo> Foos { get { return foos; } } 
    public IList<Bar> Bars { get { return bars; } } 

    private List<Foo> foos; 
    private List<Bar> bars; 
} 

Nhưng cho phép nói rằng tôi cũng cần ràng buộc (tùy ý) rằng phải có một foo trên bar và cũng có một bar mỗi foo.

public class NotAPocoAnyMore { 
    public IEnumerable<Foo> Foos { get { return foos; } } 
    public IEnumerable<Bar> Bars { get { return bars; } } 

    private List<Foo> foos; 
    private List<Bar> bars; 

    public void Add(Foo f, Bar b) {...} 
    public void Remove(Foo f, Bar b) {...} 
} 

Câu hỏi của tôi là: Tôi có cố gắng làm việc để giữ POCO đơn giản và không cung cấp bất kỳ phương pháp tiện ích nào không? Ví dụ đầu tiên POCO là tốt đẹp bởi vì nó là bất biến, và POCO có lợi thế khác. Tuy nhiên, tôi không thể nhìn thấy một cách để giữ cho lớp này là một POCO và vẫn có cách để truy cập và sửa đổi nội dung theo cách được kiểm soát (ít nhất không phải là cách mà dường như không quá giết người).

Một số nghĩ rằng tôi đã có:

Nested class sửa đổi

public class Poco { 
    public IEnumerable<Foo> Foos { get { return foos; } } 
    public IEnumerable<Bar> Bars { get { return bars; } } 
    public PocoModifier Modifier { get { ... } } 

    private List<Foo> foos; 
    private List<Bar> bars; 

    public class PocoModifier { 
    private readonly Poco toModify; 
    public void Add(Foo f, Bar b) {...} 
    public void Remove(Foo f, Bar b) {...} 
    ... 
    } 
} 

Công lớp lồng nhau? Không, cám ơn! Ngoài ra nó thực sự chỉ là giống như lớp không POCO chỉ với một ít làm tổ hơn.

Sử dụng bổ truy cập

public class Poco { 
    public IEnumerable<Foo> Foos { get { return foos; } } 
    public IEnumerable<Bar> Bars { get { return bars; } } 
    public PocoModifier Modifier { get { ... } } 

    internal List<Foo> foos; 
    internal List<Bar> bars; 
} 

public class PocoModifier { 
    private readonly Poco toModify; 
    public void Add(Foo f, Bar b) {...} 
    public void Remove(Foo f, Bar b) {...} 
    ... 
} 

Hơi tốt hơn, nhưng đòi hỏi một đơn vị toàn bộ triển khai cho mỗi POCO.

+1

Cá nhân tôi không ngại có các phương pháp tiện ích trên POCO của bạn (ngay cả khi chúng không thực sự là POCO nữa). Một tùy chọn khác là tạo một thư viện phương thức mở rộng riêng biệt hoặc PocoModifier tĩnh bên ngoài các POCO của bạn (vì vậy bạn không phải là các lớp lồng ghép), nhưng tính khả thi của nó phụ thuộc vào việc bạn đang để lộ POCO của mình cho một máy khách. – NWard

+0

Với tôi nó có vẻ như bạn kéo logic kinh doanh vào thực thể của bạn. Viết logic nghiệp vụ trong một lớp riêng biệt. –

+0

Cảm thấy như bạn đã thiết lập các hạn chế tùy ý cá nhân bạn quyết định ép buộc mã của bạn ... Có thể nếu bạn nghĩ về lý do tại sao bạn làm nó, bạn có thể tự quyết định ... Ghi chú bên: đối tượng đầu tiên của bạn không thực sự bất biến - bạn đang hiển thị danh sách để bắt đầu (yêu cầu truyền, nhưng ai sẽ dừng lại) và không hiển thị bất kỳ phương pháp nào khác ... –

Trả lời

12

Có vẻ như dữ liệu của bạn sẽ được mô hình hóa tốt hơn theo thứ gì đó tự nhiên ghép nối Foo với Bar.

public class Poco { 
    public IList<Tuple<Foo, Bar>> FooBars { get { return fooBars; } } 

    private List<Tuple<Foo, Bar>> fooBars; 
} 

Trừ khi vì một lý do kỳ lạ các Foo s và Bar s là hoàn toàn riêng biệt trừ các yêu cầu mà đếm của họ là như nhau. Sau đó, tôi thích ví dụ thứ ba của bạn ...

public class NotAPocoAnyMore { 
    public IEnumerable<Foo> Foos { get { return foos; } } 
    public IEnumerable<Bar> Bars { get { return bars; } } 

    private List<Foo> foos; 
    private List<Bar> bars; 

    public void Add(Foo f, Bar b) {...} 
    public void Remove(Foo f, Bar b) {...} 
} 

PocoModifier bổ sung thêm sự phức tạp không cần thiết, theo ý kiến ​​của tôi. Và các lớp lồng nhau thường không được công khai (vì vậy nếu bạn có lớp học ở tất cả, làm cho nó riêng biệt như trong ví dụ cuối cùng của bạn).

Nếu bạn cần một POCO để làm việc với cũng như (ví dụ như để lộ rằng công khai cho người dân sử dụng mã của bạn như một thư viện, trong khi vẫn giữ logic khác nội bộ), bạn có thể tạo một POCO đồng bằng và sau đó bản đồ nó để NotAPocoAnyMore với AutoMapper (hoặc tương tự).

public class Poco { 
    public IList<Foo> Foos { get; set; } 
    public IList<Bar> Bars { get; set; } 
} 
0

Tôi đi với kho lưu trữ để xử lý POCO bền vững (sử dụng EF).Dưới đây là một ví dụ về một kho lưu trữ chung:

public interface IRepository<T> 
{ 
    void Add(T entity); 
    void Remove(T entity); 
    ... 
} 

public class Repository<T> : IRepository<T> 
{ 
    // dbset or list or whatever you're persisting to 

    public void Add(T entity) { 
     // add to dbSet 
    }  
    public void Remove(T entity) { 
     // remove from dbSet 
    } 
} 

Và đó là sử dụng

var repo = new Repository<User>(); 
repo.Add(new User()); 

Bạn đang không làm lẫn lộn lên POCOs của bạn và có một đối tượng thiết kế đặc biệt để kéo dài POCO của bạn. Tôi không phải là một fan hâm mộ của kho chung - là tốt cho một ví dụ nhanh chóng. Bạn có thể tạo kho lưu trữ cụ thể cho từng thực thể với các phương thức truy xuất cụ thể hơn.

2

POCO chỉ đại diện cho một đơn vị dữ liệu/thông tin. Khi bạn bắt đầu thực thi các quy tắc hoặc là một ràng buộc hoặc như một cách để tổ chức tốt hơn dữ liệu của bạn, bạn bắt đầu xác định hành vi của dữ liệu của bạn. Đột nhiên, bạn không phải đối phó với POCO nữa và nó trở thành một cấu trúc dữ liệu đầy đủ thổi.

Cách bạn triển khai điều này tùy thuộc vào bạn. Nếu bạn muốn làm việc với POCO, bạn có thể tách riêng dữ liệu và hành vi bằng cách sử dụng Helpers/Extensions hoặc bất kỳ thứ gì bạn ưa thích hoặc bạn có thể xây dựng Cấu trúc dữ liệu của riêng mình bằng cách kết hợp dữ liệu và hành vi của nó trong một thực thể duy nhất.

Không có gì sai với một trong số chúng và trong khi một số người thích làm việc với POCO, tôi thường thích làm việc với Cấu trúc dữ liệu bao gói dữ liệu và hành vi của nó trong một thực thể duy nhất.

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