2010-11-15 32 views
5

Tôi có một tập các lớp, mỗi lớp cần quyết định tại một số điểm nào đó trong hai hoặc ba phương pháp tiếp cận mà chúng nên sử dụng nội bộ để thực hiện cùng chức năng bên ngoài. Lý tưởng nhất, điều này nên bao gồm chức năng dự phòng, trong trường hợp nếu phương pháp tiếp cận không thành công, nó rơi qua để thử phương pháp ApproachB (và có lẽ là phương pháp tiếp cận C, D, v.v.). Cho đến bây giờ, tôi đã chỉ sử dụng mã hóa như if (!success) { ApproachB code }. Vấn đề với điều này là một số phương pháp sau này cũng cần phải nhận thức được cách tiếp cận nào đã được chọn và tất cả chúng cũng phát triển các câu lệnh if (MethodChosen) { } else { } của riêng chúng. Tôi thực sự muốn giải quyết vấn đề với một cái gì đó ít khó sử dụng hơn ... ngoại trừ không có các tùy chọn khác mà tôi đã xem xét có vẻ như tất cả những gì "wieldy". Dưới đây là ba cách tiếp cận mà tôi đã nghĩ đến:Thực hiện các lớp "Dự phòng"

  1. Thực hiện một phương pháp tĩnh. Tạo ra hai lớp có giao diện sao lưu chúng. Điểm bất lợi của điều này là bạn đang viết rất nhiều mã giống nhau hai lần, và nó không thực sự tạo ra một "dự phòng" vì nó buộc tất cả các quyết định phải được thực hiện phía trước trong phương thức .Create. Điều này sẽ làm việc 9/10 lần, nhưng sẽ có 1/10 lần khác mà tôi muốn dự phòng để đá chỉ khi chính đã cố gắng và thất bại.
  2. Giống như trên, nhưng với lớp cơ sở hoặc lớp trừu tượng có liên quan, hoặc là lớp ủng hộ cho cả hai hoặc với lớp chính làm lớp cơ sở cho dự phòng. Điều này có cùng một nhược điểm dự phòng, nhưng ít nhất có ít hoặc không có mã lặp lại.
  3. Thực hiện một lớp trừu tượng bình thường-xây dựng với lớp trẻ mà có thể thay đổi thời gian chạy: ví dụ:

    public void SomeMethodOrConstructor() 
    { 
        if (someConditions) 
         MyChild = ChildClassA; 
        else 
         MyChild = ChildClassB; 
    } 
    
    
    public void Execute() 
    { 
        MyChild.Execute(); 
    } 
    

Vấn đề với lựa chọn 3 đang chuyển dữ liệu giữa hai khi cần thiết. Vì một số phương pháp này đang mô hình hóa các đối tượng bên ngoài, điều này sẽ khá thường xuyên. Các lớp lồng nhau có chia sẻ dữ liệu với lớp cha của chúng tự động không? Hoặc tôi sẽ phải vượt qua tất cả với mọi cuộc gọi?

Bất kỳ điều gì khác mà tôi nên cân nhắc?


Cập nhật: Lớp đầu tiên được thiết lập và hoạt động với Chuỗi trách nhiệm. Hiện tại, tôi đã chọn không sử dụng Mẫu chiến lược hoặc dự phòng trong khi thực thi phương pháp, vì tôi tin rằng cuối cùng có thể không cần thiết. Tôi nghĩ rằng hầu hết những thất bại thực hiện như vậy sẽ thực sự tốt hơn bằng cách ở trong các lớp học của riêng họ, vì sẽ không có thay đổi hoàn toàn về gameplan, chỉ cần một vài chỉnh sửa nhỏ để giải quyết. Nếu điều đó không đúng, tôi ít nhất biết tôi cần điều tra điều gì bây giờ.

Nhờ tất cả những người đã giúp giải pháp tối ưu!

Đối với người hiếu, giải pháp cuối cùng của tôi làm việc gần như thế này:

  • Tạo Handler lớp trừu tượng, khá nhiều như được nêu trong bài viết Wikipedia, nhưng với một hàm public abstract Handler GetHandler(), và thêm các phương pháp trừu tượng khác như Load, Lưu, vv
  • Triển khai các lớp con xử lý riêng cho lớp cha (chúng cũng có thể là lớp con, vì chúng sẽ chỉ xử lý mọi thứ cho lớp cụ thể đó ... tránh các vấn đề đặt tên sau này). Các lớp con tất cả lấy một tham số kiểu của đối tượng cha mẹ trong hàm tạo của chúng, do đó chúng có thể truy cập dễ dàng vào dữ liệu của cha mẹ.
  • Từ hàm khởi tạo của lớp cha, hãy thiết lập trình xử lý/người kế thừa chuỗi (một lần nữa, giống như ví dụ), sau đó gọi FirstHandler.GetHandler(this) và lưu kết quả để lớp đó biết trình xử lý nào sẽ sử dụng trong tương lai.
  • Các phương pháp được xử lý nhiều nhất sau đó chỉ cần giảm xuống Handler.MethodName().
+2

Bạn có thể đặt mã trong danh sách được đánh số bằng cách thụt lề bằng dấu cách _eight_. – SLaks

+0

Cảm ơn bạn đã có mẹo định dạng, điều đó đã giúp tôi vượt tường! – RobinHood70

Trả lời

5

Sử dụng Chain of Responsibility.

chuỗi-of-trách nhiệm mô hình là một mô hình thiết kế bao gồm một nguồn của các đối tượng lệnh và một loạt các đối tượng xử lý. Mỗi đối tượng xử lý chứa một tập hợp các logic mô tả các loại đối tượng lệnh rằng nó có thể xử lý, và làm thế nào để vượt qua khỏi những người mà nó không thể xử lý đến đối tượng xử lý tiếp theo trong chuỗi. Cơ chế cũng tồn tại để thêm đối tượng đang xử lý mới vào cuối chuỗi này.

Điều này hoàn toàn phù hợp với những gì bạn cần làm.

+0

Tôi sẽ chơi với nó chiều nay, nhưng tôi khá chắc chắn đây là câu trả lời tôi đang tìm kiếm! – RobinHood70

+0

Bất cứ điều gì, chỉ cần cho tôi một tiếng hét. – Aliostad

+0

Bất kỳ mẹo nào về cách triển khai điều này về các cuộc gọi sau này? Để đưa trường hợp cụ thể của tôi vào một ví dụ chung chung hơn, giả sử tôi có một phương thức Tải và Lưu, trong đó Load xử lý các tệp XML hoặc TXT. Lưu không cần phải "tìm lại nó", Tải đã xác định những gì nó xử lý. Tôi nghĩ rằng lớp cha mẹ chỉ cần có một thuộc tính Handler cho biết xử lý nào cuối cùng đã xử lý sự kiện, nhưng tôi không chắc chắn về cách tốt nhất để thực hiện điều đó. – RobinHood70

0

tôi nghĩ rằng bạn cần Task/Task<T>, đặc biệt là phương pháp ContinueWith(Action<Task>) và 4 thuộc tính: IsCanceled, IsCompleted, IsFaultedResult.

1

Tôi có thể sử dụng mẫu chiến lược ở đây.

http://en.wikipedia.org/wiki/Strategy_pattern

Bạn chỉ cần chuyển delgates thay vì toàn bộ lớp học. Nếu tất cả các phương thức đều sử dụng cùng một thông tin để xử lý, điều này có thể hữu ích.

+0

Đây cũng là một giải pháp tốt, mặc dù nếu tôi hiểu chính xác, nó sẽ không có hành vi bỏ qua mà tôi đang tìm kiếm. – RobinHood70

+0

Có vẻ như mô hình chiến lược của bạn sẽ được phát triển. :) Cảm ơn! – RobinHood70

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