2011-06-23 35 views
6

Tôi có lớp "Hành động" trừu tượng, có các loại ActionAppointment, ActionCall, ActionEmail và ActionLetter. Tôi đang cố gắng viết một hàm sẽ làm khô lớp dịch vụ của chúng tôi, vì vậy chúng tôi không viết các cuộc gọi CRUD 5 lần nữa.Mẫu C# cho mã cụ thể lớp trừu tượng

tôi có trong lớp dịch vụ của chúng tôi một số logic cập nhật (rất nhiều mã khác bị loại bỏ cho ngắn gọn):.

private IServiceResponse UpdateAction<T>(T action, string originalActionStatus) where T : Action 
{ 
     if (action.GetType() == typeof(Action)) 
     { 
      _actionRepository.Update(action); 
     } 
     else if (action.GetType() == typeof(ActionAppointment)) 
     { 
      _actionAppointmentRepository.Update(action as ActionAppointment); 
     } 
     else if (action.GetType() == typeof(ActionCall)) 
     { 
      _actionCallRepository.Update(action as ActionCall); 
     } 
     else if (action.GetType() == typeof(ActionEmail)) 
     { 
      _actionEmailRepository.Update(action as ActionEmail); 
     } 
     else if (action.GetType() == typeof(ActionLetter)) 
     { 
      _actionLetterRepository.Update(action as ActionLetter); 
     } 
} 

Thật không may, cách kho của chúng tôi được thiết lập, tôi phải sử dụng các kho đặc biệt được đặt tên (tức là tôi không thể cập nhật ActionLetter thông qua _actionRepository ngay cả khi nó xuất phát từ Hành động)

Tôi đã đọc trên các mẫu khác nhau và có vẻ giống như một Mẫu Nhà máy, nhưng tôi không thể thấy cách làm cho nó hoạt động.

Tôi có thiếu gì đó ngu ngốc không?

+1

Bạn có thể xem xét mẫu * Visitor * (http://en.wikipedia.org/wiki/Visitor_pattern). –

+2

Có một mẫu nhà máy là một giải pháp. Kho lưu trữ của bạn phải có lớp cơ sở chung hoặc triển khai giao diện. Tất cả chúng đều phải có phương thức Update chấp nhận đối tượng được gõ là Action. Nhà máy chấp nhận kiểu như một tham số (trong bất kỳ hình thức, tên, loại, enum nếu có sẵn) và trả về kho lưu trữ chính xác. Đó là khá nhiều đó. Có một điểm cụ thể của sự nhầm lẫn về cách thực hiện Nhà máy? – Sisyphus

+0

Tôi không chắc chắn cách triển khai mẫu nhà máy cho mẫu này, vì IRepository là chung dựa trên từng đối tượng mô hình miền. – mandreko

Trả lời

11

Bạn không thể chỉ viết quá tải phương thức đó cho từng loại hành động? Hãy quên đi các công cụ <T>typeof - những gì bạn đang làm là triển khai tính năng ngôn ngữ được tích hợp (quá tải phương thức) bằng tay và theo cách dễ vỡ.

+3

Vâng, đó là chính xác những gì đa hình và thừa kế là tất cả về. –

+0

Mã này trước đây được viết dưới dạng phương thức cho từng loại Hành động. Tôi chỉ cố gắng để DRY nó lên một số, nhưng tôi đoán có lẽ tôi có thể DRY lên một số các thành phần được chia sẻ, nhưng có mã số kho cụ thể trong mỗi một. – mandreko

+0

@Matt: Nếu contraption khác của bạn không làm cho mã bất kỳ DRYer, đó là chắc chắn. –

-2

Hãy inverse logic ở đây:

abstract class Action { 
    protected abstract Repository GetRepository(); 
    protected void Update(){ 
     this.GetRepository().Update(this); 
    } 
} 

Tất cả bạn phải làm là ghi đè lên GetRepository trong mỗi lớp học bắt nguồn. Ví dụ:

class ActionAppointment : Action { 
    protected override Repository GetRepository() { 
     return _actionAppointmentRepository; 
    } 
} 
+1

không phải là một ý tưởng rất tốt cho một lớp mô hình để biết về cách nó được lưu trữ. –

+2

-1, Các dịch vụ tiêm (thậm chí cả kho lưu trữ) vào các đối tượng miền là một thực tế không tốt. – smartcaveman

+0

Đồng ý với smartcaveman. Nó vi phạm các quy tắc của chúng tôi để có loại phụ thuộc đó. – mandreko

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