2013-03-28 38 views
8

Tôi có một giao diện cho một lớp dịch vụ .NET, trong đó, đến lượt nó, sẽ liên lạc với một hệ thống của bên thứ ba thông qua một dịch vụ web. Điều này xử lý một số nhiệm vụ khác nhau liên quan đến chức năng của hệ thống bên thứ ba (nó thực sự là một hệ thống CRM riêng biệt, nhưng khi ngữ cảnh không liên quan, tôi sẽ hoán đổi điều này cho một điều gì đó tầm thường).Generics and convention in C#

Giao diện trông giống như sau:

public interface IMyService 
{ 
    CarModel GetCar(string registration); 
    CarModel AddCar(Car car); 
    PersonModel GetPerson(string personId); 
    PersonModel AddPerson(Person person); 
} 

Bây giờ, mô hình của tôi hiện đang làm việc như sau: Tôi có một BaseResponseModel, từ đó mỗi SomethingModel kế thừa. Mỗi SomethingModel chứa một số đặc tính cơ bản và cũng kết thúc tốt đẹp một Something - như vậy:

mô hình phản ứng cơ sở

public class BaseResponseModel 
{ 
    public List<string> Errors { get; set; } 
    public bool HasErrors 
    { 
     get 
     { 
      return (Errors != null && Errors.Count > 0); 
     } 
    } 
} 

mô hình phản ứng cụ thể

public class CarModel : BaseResponseModel 
{ 
    public Car Car { get; set; } 
} 

public class PersonModel : BaseResponseModel 
{ 
    public Person Person { get; set; } 
} 

Ở đây, CarPerson chỉ đơn giản chứa một loạt các tài sản công cộng. Sau đó, mỗi phương thức của tôi IMyService lấy các đối số của nó, định dạng một yêu cầu đến một dịch vụ web .asmx, phân tích phản hồi thành mô hình phản hồi của nó và trả về cho người gọi (một codebehind .ascx).

Tuy nhiên, số lượng các lớp khác nhau ...Model (chưa kể rằng tất cả chúng đều có tên thuộc tính khác nhau cho các đối tượng được bao bọc của chúng) đang trở nên xấu xí. Tôi của một tâm trí để làm điều gì đó dọc theo dòng trong các cách sau:

public class Car 
{ 
    public string Registration { get; set; } 
} 

public class ServiceResponse<T> 
{ 
    public List<string> Errors { get; set; } 
    public bool HasErrors { ... } 
    public T Result { get; set; } 
} 

public interface IMyService 
{ 
    ServiceResponse<Car> GetCar(string registration); 
    ServiceResponse<Car> AddCar(Car car); 
    ServiceResponse<Person> GetPerson(string id); 
    ServiceResponse<Person> AddPerson(Person person); 
} 

điều khiển ASP.NET của tôi sau đó sẽ nhận được ServiceResponse<T> từ mỗi phương pháp trong IMyService.

Đây có phải là cách sử dụng "thông thường chính xác" của Generics trong C# không? Hoặc là điều này chỉ đơn giản là che giấu các lỗ hổng kiến ​​trúc sâu hơn với giải pháp của tôi? Có một cái gì đó mất tích từ giải pháp đề xuất của tôi (mặc dù lưu ý rằng việc thực hiện các phương pháp khác nhau GetAdd không phải là chung chung như nguyên mẫu làm cho họ có vẻ)?

Tuyên bố từ chối: Xin lỗi nếu câu hỏi này "quá chủ quan", nhưng dường như quá cụ thể là câu hỏi lý thuyết cho Programmers.SE và một chút quá chung chung để trở thành câu hỏi cho CodeReview.SE. Tôi mở để gợi ý về cách cải thiện câu hỏi nếu cần thiết.

+3

Tôi không thấy bất kỳ điều gì sai trái với mẫu. ASP.Net Web API sử dụng một quy ước tương tự cho các thông điệp trả về HTTP mà có thể có một thân của các kiểu khác nhau (xem 'HttpResponseMessage '). –

+0

Có vẻ đúng với tôi. Sử dụng đúng đắn của generics, nơi tốt để sử dụng chúng trong ... yea mà nhìn về bên phải. – Nevyn

Trả lời

2

Tôi không thấy vấn đề với việc sử dụng generics này, trừ khi bạn sẽ có người sử dụng dịch vụ của bạn từ một thứ khác ngoài .NET. Tôi nghĩ rằng nó tạo ra các tên hợp đồng khá xấu cho WSDL.

Vì vậy, đối với trường hợp sử dụng của bạn, tôi muốn nói là không sao. Tôi rất vui vì bạn đã thay đổi từ Model thành Response. Tôi sẽ đề nghị điều đó.

Tùy thuộc vào cách các lỗi được sử dụng, cá nhân tôi muốn tăng ngoại lệ (tổng hợp) cho chúng. Tuy nhiên, nếu bạn sử dụng nó để xác nhận biểu mẫu hoặc một cái gì đó, tôi sẽ nói đó là chấp nhận được.

+0

Cảm ơn bạn đã nhập liệu! Chỉ cần làm rõ, 'IMyService' không phải là một giao diện cho bản thân dịch vụ mà là một lớp * dịch vụ trừu tượng trong ứng dụng của tôi, điều này, chịu trách nhiệm về việc tiêu thụ dịch vụ web thực sự (xin lỗi nếu điều này không rõ ràng ban đầu) , vì vậy tên hợp đồng không bị ảnh hưởng. –

+0

Cảm ơn Thorarin; chúng tôi đã đi với cách tiếp cận này cuối cùng. Lỗi được lưu trữ trong ServiceResponse khi mã của chúng được chuyển đến tham số GET đến trang lỗi. –

0

Có lẽ câu trả lời của tôi cũng bị quá - nhưng tôi khuyên bạn nên tránh tạo phụ thuộc trước khi bạn có hệ thống làm việc ổn định ít nhất trong phiên bản beta. Đặc biệt là khi bạn bắt đầu phát triển. Cũng như thừa kế trong một trong các loại quan hệ mạnh nhất, nó nên được đặt sang một bên càng lâu càng tốt.

Thêm lớp cơ sở hoặc chung chung, trông giống nhau, bạn đặt mình vào một khung hình rất khó khăn.

Điều gì sẽ xảy ra nếu bạn nói đến từ điển hoặc lỗi? Hoặc bạn cần mã phản hồi đặc biệt cho CarRequest? Hoặc loại phản hồi đặc biệt như 'chuyển hướng'?

Vì vậy - đề xuất của tôi là bạn thực hiện một loại phản hồi đặc biệt theo yêu cầu cho đến khi bạn tìm ra một số điểm tương đồng phản hồi sau số lượng phát triển đáng kể.

Nên có GetCarResponse đến GetCar. Bạn đang lên kế hoạch sai sót trong phản ứng? Chỉ cần ném một ngoại lệ. Không tìm thấy? Trả về null. Tìm? Trả lại những gì bạn tìm thấy và không bận tâm với lỗi.

Có thể yêu cầu một chút mã hóa khác, nhưng bạn đã giải phóng được một số hạn chế nhân tạo.