2011-12-20 28 views
5

Giả sử chúng tôi có một dự án sẽ xử lý nhiều dữ liệu (nhân viên, lịch biểu, lịch .... và nhiều hơn nữa). Ứng dụng khách là Windows App, phía máy chủ là WCF. Cơ sở dữ liệu là MS SQL Server. Tôi đang bối rối về cách tiếp cận để sử dụng. Tôi đọc vài bài báo và blog tất cả đều có vẻ đẹp nhưng tôi bối rối. Tôi không muốn bắt đầu với một cách tiếp cận và sau đó hối tiếc không lựa chọn cách khác. Dự án sẽ có khoảng 30-35 loại đối tượng khác nhau. Rất nhiều dữ liệu lấy để cư báo cáo khác nhau ... vvthiết kế nào tốt hơn cho dự án máy khách/máy chủ với nhiều chia sẻ dữ liệu

Cách tiếp cận 1:

// classes that hold data 

public class Employee 
{ 
    public int Id { get; set; } 
    public string FirstName { get; set; } 
    public string LastName { get; set; } 
    ..... 
} 

public class Assignment 
{ 
    public int Id { get; set; } 
    public int UserId { get; set; } 
    public DateTime Date { get; set; } 
    ..... 
} 
..... 

lớp Rồi Helper để đối phó với tiết kiệm dữ liệu và thu lấy:

public static class Employees 
{ 
    public static int Save(Employee emp) 
    { 
     // save the employee 
    } 

    public static Employee Get(int empId) 
    { 
     // return the ugly employee 
    } 
    ..... 
} 

public static class Assignments 
{ 
    public static int Save(Assignment ass) 
    { 
     // save the Assignment 
    } 
    ..... 
} 

FYI, The các lớp đối tượng như Employees và Assignment sẽ nằm trong một Assembly riêng biệt được chia sẻ giữa Sever và Client. Dù sao, với cách tiếp cận này, tôi sẽ có một đối tượng sạch hơn. Các lớp Helper sẽ làm hầu hết công việc.

Phương pháp 2:

// classes that hold data and methods for saving and retrieving 

public class Employee 
{ 
    // constructors 
    public Employee() 
    { 
     // Construct a new Employee 
    } 
    public Employee(int Id) 
    { 
     // Construct a new Employee and fills the data from db 
    } 

    public int Id { get; set; } 
    public string FirstName { get; set; } 
    public string LastName { get; set; } 
    ..... 

    public int Save() 
    { 
     // save the Employee 
    } 
    ..... 
} 

public class Assignment 
{ 
    // constructors 
    public Assignment() 
    { 
     // Construct a new assignment 
    } 
    public Assignment(int Id) 
    { 
     // Construct a new assignment and fills the data from db 
    } 

    public int Id { get; set; } 
    public int UserId { get; set; } 
    public DateTime Date { get; set; } 
    ..... 

    public int Save() 
    { 
     // save the Assignment 
    } 
    ..... 
} 
..... 

Với phương pháp này, Mỗi đối tượng sẽ làm công việc riêng của mình .. dữ liệu vẫn có thể được chuyển từ WCF để khách hàng dễ dàng kể từ WCF sẽ chỉ chia sẻ tài sản.

Cách tiếp cận 3:

Sử dụng Entity Framework .. bên cạnh thực tế là tôi không bao giờ làm việc với nó (đó là tốt đẹp kể từ khi tôi phải học một cái gì đó mới) Tôi sẽ cần phải tạo POCOs để truyền dữ liệu giữa máy khách và WCF ..

Bây giờ, cái nào tốt hơn? lựa chọn khác?

+0

Câu hỏi hay, nhưng có lẽ phù hợp hơn cho người lập trình. – jwiscarson

Trả lời

0

Tôi khuyên bạn nên sử dụng mẫu Entity Framework + Repository. Bằng cách này, các thực thể của bạn là các đối tượng đơn giản mà không có bất kỳ logic nào trong chúng. Tất cả các logic truy xuất được lưu lại trong kho lưu trữ. Tôi có một số kinh nghiệm thành công với việc sử dụng kho lưu trữ chung, được gõ với thực thể, một cái gì đó tương tự được mô tả here (phần lưu trữ chung của bài viết). Bằng cách này bạn chỉ viết mã kho lưu trữ một lần và bạn có thể sử dụng lại nó cho tất cả các thực thể bạn có. Ví dụ:

interface IRepositry<T> 
{ 
T GetById(long id); 
bool Save(T entity); 
} 

public class Repository<T> : IRepository<T> {...} 

var repository = new Repository<MyEntity>(); 
var myEntity = repository.GetById(1); 
var repository2 = new Repository<MySecondEntity>(); 
var mySecondEntity = repository.GetById(1); 

Bất cứ khi nào một thực thể cần một số hoạt động rất cụ thể, bạn có thể thêm hoạt động này cho một người cụ thể gõ thi hành IRepository:

interface IMySuperRepositry : IRepository<MySuperEntity> 
{ 
    MySuperEntity GetBySuperProperty(SuperProperty superProperty); 
} 

public class MySuperEntityRepository : Repository, IMySuperRepository 
{...} 

Để tạo kho nó là tốt đẹp để sử dụng một nhà máy, trong đó dựa trên ví dụ về tệp cấu hình. Bằng cách này, bạn có thể chuyển đổi triển khai các kho lưu trữ, ví dụ: cho kiểm tra đơn vị, khi bạn không muốn sử dụng kho lưu trữ đó thực sự truy cập DB:

public class RepositoryFactory 
{ 
    IRepository<T> GetRepository<T>() 
{ 
    if (config == production) 
    return new Repository<T>(); // this is implemented with DB access through EF 
    if (config == test) 
    return new TestRepository<T>(); // this is implemented with test values without DB access 
} 
} 

}}

Bạn có thể thêm các quy tắc xác nhận để lưu và tiếp tục công phu về vấn đề này. EF cũng cho phép bạn thêm một số phương thức hoặc thuộc tính đơn giản cho các thực thể được tạo ra, vì tất cả chúng đều là các lớp một phần.

Ngoài việc sử dụng POCO hoặc STE (xem sau) có thể có mô hình EDMX DB trong một dự án và tất cả các thực thể của bạn trong dự án khác và do đó phân phối DLL này cho ứng dụng khách (chỉ chứa các thực thể của bạn). Như tôi đã hiểu, đó là những gì bạn cũng muốn đạt được.

Cũng cân nhắc nghiêm túc việc sử dụng Self tracking entities (và không chỉ POCO). Theo tôi, họ rất tuyệt vời khi sử dụng WCF. Khi bạn nhận được một thực thể từ DB và chuyển nó cho khách hàng, khách hàng thay đổi nó và đưa nó trở lại, bạn cần phải biết, nếu thực thể đã được thay đổi và những gì đã được thay đổi. STE xử lý tất cả công việc này cho bạn và được thiết kế đặc biệt cho WCF. Bạn nhận được thực thể từ khách hàng, nói ApplyChanges và Save, đó là nó.

0

Điều gì về việc triển khai phương thức Lưu dưới dạng tiện ích mở rộng? Bằng cách đó, các lớp của bạn được sạch sẽ như trong tùy chọn đầu tiên, nhưng các phương thức có thể được gọi trên đối tượng như trong tùy chọn thứ hai.

public static class Employee 
{ 
    public static int Save(this Employee emp) 
    { 
     // save the employee 
    } 

    public static Employee Get(int empId) 
    { 
     // return the ugly employee 
    } 

} 
2

Có logic tồn tại trong chính đối tượng luôn là ý tưởng tồi.

Tôi sẽ sử dụng aproach đầu tiên. Có vẻ như Repository pattern. Bằng cách này, bạn có thể dễ dàng gỡ lỗi peristing của dữ liệu, bởi vì nó sẽ được tách biệt rõ ràng với phần còn lại của logic của đối tượng.

0

bạn đang suy nghĩ về điều này. cố gắng áp dụng công nghệ và các mẫu "chỉ vì" hoặc "đó là những gì họ nói" chỉ làm cho giải pháp phức tạp. Điều quan trọng là thiết kế ứng dụng để nó có thể dễ dàng thích ứng với thay đổi. đó có thể là một câu trả lời mơ hồ, nhưng đó là tất cả những gì nó xảy ra. cần bao nhiêu nỗ lực để duy trì và/hoặc sửa đổi cơ sở mã.

hiện tại có vẻ như các mẫu và thực tiễn là kết quả cuối cùng, thay vì phương tiện để kết thúc.

+0

Tôi dự định sẽ nghĩ về nó .. Suy nghĩ thường không tệ.Nó dẫn đến việc học những điều mới .. Bất kỳ cách nào quan điểm của bạn về nỗ lực cần thiết để duy trì mã là điểm chính .. nhưng vẫn cố gắng cái gì đó mới cũng là một điểm .. –

0

Khuôn khổ thực thể là một công cụ tuyệt vời nhưng không nhất thiết phải là lựa chọn tốt nhất trong mọi trường hợp. Nó sẽ phụ thuộc vào bao nhiêu bạn mong đợi để đọc/ghi từ cơ sở dữ liệu so với bao nhiêu bạn mong đợi để đọc/ghi vào các dịch vụ WCF của bạn. Có lẽ ai đó tốt hơn trong thế giới tuyệt vời của EF sẽ có thể giúp bạn.Để nói từ kinh nghiệm, tôi đã sử dụng LINQ-TO-SQL trong một ứng dụng có các điểm cuối dịch vụ WCF và không có vấn đề gì (và trên thực tế đã đến với LOVE LINQ-To-Sql như một ORM).

Có nói rằng, nếu bạn quyết định rằng EF không phải là lựa chọn phù hợp với bạn, có vẻ như bạn đang đi đúng hướng với Phương pháp tiếp cận 1. Tuy nhiên, tôi khuyên bạn nên triển khai DataAccessLayer. Tức là, thực hiện phương thức Persist trong các lớp nghiệp vụ của bạn, sau đó gọi các phương thức trong một DAO riêng biệt (Đối tượng truy cập dữ liệu hoặc một lớp được sử dụng để lưu dữ liệu từ một đối tượng nghiệp vụ) để lưu nó vào cơ sở dữ liệu của bạn.

Một thi mẫu có thể trông như thế này:

public class Employee 
{ 
    public int Id { get; set; } 
    public string FirstName { get; set; } 
    public string LastName { get; set; } 

    public void Persist() 
    { 
     EmployeeDAO.Persist(this); 
    } 
} 

public class Assignment 
{ 
    public int Id { get; set; } 
    public int UserId { get; set; } 
    public DateTime Date { get; set; } 

    public void Persist() 
    { 
     AssignmentDAO.Persist(this); 
    } 
} 

public static class EmployeeDAO 
{ 
    public static int Persist(Employee emp) 
    { 
     // insert if new, else update 
    } 

    public static Employee Get(int empId) 
    { 
     // return the ugly employee 
    } 
    ..... 
} 

public static class AssignmentDAO 
{ 
    public static int Persist(Assignment ass) 
    { 
     // insert if new, else update 
    } 
    ..... 
} 

Lợi ích đối với một mô hình như thế này là bạn có được để giữ cho lớp doanh nghiệp của bạn sạch sẽ, logic dữ liệu truy cập của bạn riêng biệt, trong khi vẫn đem lại cho các đối tượng là cú pháp dễ dàng để có thể viết new Employee(...).Persist(); trong mã của bạn.

Nếu bạn thực sự muốn đi các loại hạt, bạn thậm chí có thể xem xét thực hiện các giao diện trên lớp persistable của bạn, và có DAO của bạn (s) chấp nhận những IPersistable trường hợp như các đối số.

+0

Cách tiếp cận của bạn rất hay, Có vẻ như "Cách tiếp cận 1" và "Cách tiếp cận 2" đã kết hôn và có phương pháp tiếp cận của bạn khi còn nhỏ .. Tôi sẽ đợi thêm tùy chọn và ý kiến ​​.. –

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