2009-12-22 40 views
14

Tôi đang xử lý một số tình huống giao tiếp không đồng bộ (phân tích cú pháp XML theo hướng sự kiện, xử lý phản hồi NSURLConnection, v.v.). Tôi sẽ cố gắng giải thích ngắn gọn vấn đề của mình:Truyền thông không đồng bộ mục tiêu-c: mục tiêu/hành động hoặc mẫu ủy quyền?

Trong trường hợp hiện tại của tôi, có một nhà cung cấp dịch vụ (có thể nói chuyện với trình phân tích cú pháp xml hoặc thực hiện một số liên lạc mạng) và khách hàng có thể yêu cầu nhà cung cấp dịch vụ thực hiện một số các nhiệm vụ của nó không đồng bộ. Trong trường hợp này, khi nhà cung cấp dịch vụ hoàn tất việc xử lý của nó, nó phải truyền lại kết quả cho máy khách.

Tôi đang cố gắng để tìm một loại hoa văn hay quy tắc của ngón tay cái để thực hiện các loại của sự vật và tôi nhìn thấy 3 giải pháp khả thi:

1. Sử dụng các mô hình đoàn: khách hàng là các nhà cung cấp dịch vụ của ủy nhiệm và nó sẽ nhận được kết quả khi hoàn thành nhiệm vụ.

2. Sử dụng cách tiếp cận mục tiêu/hành động: Máy khách yêu cầu nhà cung cấp dịch vụ thực hiện tác vụ và chuyển bộ chọn sẽ được nhà cung cấp dịch vụ gọi ra khi hoàn thành tác vụ.

3. Sử dụng thông báo.

(Cập nhật) Sau một thời gian thử giải pháp # 2 (mục tiêu và hành động), tôi đi đến kết luận rằng, trong trường hợp của tôi, tốt hơn là sử dụng phương thức ủy nhiệm (# 1). Dưới đây là những ưu và nhược điểm của từng phương án, như tôi đã nhìn thấy chúng: Cách tiếp cận

Phái đoàn:

  • 1 (+) Mặt tích cực của phương án 1 là chúng ta có thể séc trị giá biên dịch lỗi thời gian vì khách hàng phải triển khai giao thức đại biểu của nhà cung cấp dịch vụ.

  • 1 (-) Đây cũng là một nhược điểm vì nó khiến khách hàng được kết hợp chặt chẽ với nhà cung cấp dịch vụ vì nó phải thực hiện giao thức đại biểu của nó.

  • 1 (+) Nó cho phép lập trình viên dễ dàng duyệt mã và tìm phương thức của máy khách, nhà cung cấp dịch vụ đang gọi để chuyển kết quả của nó.

  • 1 (-) Từ quan điểm của khách hàng, không dễ dàng tìm được phương thức sẽ được nhà cung cấp dịch vụ gọi ra khi nhà cung cấp có kết quả. Nó vẫn còn dễ dàng, chỉ cần đi đến các phương pháp giao thức đại biểu và đó là nó, nhưng cách tiếp cận # 2 là trực tiếp hơn.

  • 1 (-) Chúng tôi phải viết thêm mã: Xác định giao thức đại biểu và triển khai nó.

  • 1 (-) Ngoài ra, mẫu ủy quyền nên được sử dụng để thực hiện hành vi ủy nhiệm. Kịch bản này sẽ không phải là một trường hợp chính xác của phái đoàn, nói ngữ nghĩa.

Action/Mục tiêu tiếp cận

  • 2 (+) Mặt tích cực của phương án 2 là khi các phương pháp cung cấp dịch vụ đang được gọi, @selector quy định cụ thể các hành động gọi lại phải cũng được xác định, vì vậy lập trình viên biết ngay phương thức nào sẽ được gọi lại để xử lý các kết quả.

  • 2 (-) Ngược lại điều này, thật khó để tìm ra phương thức nào sẽ được gọi lại trong ứng dụng khách khi duyệt mã nhà cung cấp dịch vụ. Lập trình viên phải đi đến lời gọi dịch vụ và xem @selector nào đang được truyền đi.

  • 2 (+) Đó là giải pháp năng động hơn và ít khớp nối hơn giữa các bộ phận.

  • 2 (-) Có lẽ một trong những điều quan trọng nhất: Nó có thể gây ra lỗi run-time và tác dụng phụ, như khách hàng có thể vượt qua một selector không tồn tại để cung cấp dịch vụ.

  • 2 (-) Sử dụng phương pháp đơn giản và tiêu chuẩn (#performSelector: withArgument: withArgument :) nhà cung cấp dịch vụ chỉ có thể vượt qua 2 đối số.

Notifications:

  • Tôi sẽ không chọn thông báo bởi vì tôi nghĩ rằng họ có nghĩa vụ phải được sử dụng khi có nhiều hơn một đối tượng cần phải được cập nhật. Ngoài ra, trong tình huống này, tôi muốn nói trực tiếp với đại biểu/đối tượng mục tiêu phải làm gì sau khi các kết quả được xây dựng.

Kết luận: Tại thời điểm này, tôi sẽ chọn cơ chế ủy quyền. Cách tiếp cận này cung cấp sự an toàn hơn và cho phép dễ dàng duyệt mã để theo dõi hậu quả của việc gửi đại biểu kết quả của các hành động của nhà cung cấp dịch vụ. Những khía cạnh tiêu cực về giải pháp này là: nó là giải pháp tĩnh hơn, chúng ta cần viết nhiều mã hơn (giao thức liên quan đến công cụ) và ngữ nghĩa, chúng ta không nói thật về phái đoàn vì nhà cung cấp dịch vụ sẽ không ủy nhiệm bất cứ điều gì .

Tôi có thiếu gì đó không? bạn đề nghị gì và tại sao?

Cảm ơn!

Trả lời

0

Câu hỏi rất hay.

Tôi không nghĩ mình đủ tiêu chuẩn, chỉ là (vì tôi là người mới), để nhận xét về mẫu thiết kế nào tốt hơn mẫu kia. Nhưng chỉ muốn nhấn mạnh rằng, nhược điểm bạn nêu tại điểm 2 (ngoại trừ thời gian chạy) có thể tránh được bằng cách

if([delegate respondsToSelector:callback]){ 
    //call to callback here 
} 

Hy vọng rằng sẽ giúp cân nhắc các lựa chọn

+0

Cảm ơn Mihirsm, Bạn nói đúng, điều đó sẽ ngăn chặn lỗi thời gian chạy. Nhưng vẫn còn, thực tế là các lập trình viên sử dụng một bộ chọn sai sẽ không được hiển thị cho đến khi thời gian chạy. Điều đó có thể tạo ra các tác dụng phụ: S. Một lần nữa, một dấu cộng cho cơ chế ủy quyền, tĩnh hơn nhưng an toàn hơn. Chúc mừng! – Lio

+1

Bạn có thể làm điều này an toàn hơn một chút bằng cách thực hiện một @protocol, và yêu cầu người được ủy quyền tuân theo giao thức này. Điều này sẽ đảm bảo rằng lớp đại biểu thực hiện các phương thức cần thiết. Bạn cũng có thể thêm một xác nhận vào phương thức setDelegate: để kiểm tra xem đối tượng mới có tuân thủ giao thức hay không. –

+0

Cách mặc định cho các phương thức được khai báo trong các giao thức là chúng là '@ optional', vì vậy' [delegate respondsToSelector: callback] 'vẫn còn cần thiết. Bạn có thể sử dụng '@ required' trong giao thức của mình, nhưng tôi thấy hầu hết mọi người không làm điều đó. Giải pháp của tôi là tạo một trampoline 'NSProxy' được trả về bởi phần mở rộng' NSObject', '- [NSObject ifResponds]'. Chỉ cần cú pháp đường cho phép bạn không có tất cả những gì 'if' vô nghĩa. –

3

Bạn đã bỏ lỡ một lựa chọn thứ ba - thông báo.

Bạn có thể yêu cầu khách hàng quan sát thông báo từ nhà cung cấp dịch vụ cho biết rằng họ có dữ liệu mới. Khi khách hàng nhận được thông báo này, nó có thể tiêu thụ dữ liệu từ nhà cung cấp dịch vụ.

Điều này cho phép khớp nối lỏng lẻo đẹp; một số quyết định là chỉ xuống cho dù bạn muốn có một hệ thống push/pull mặc dù.

+0

Cảm ơn Ciarán, Tôi không cân nhắc Thông báo chỉ vì tôi nghĩ rằng chúng nên được sử dụng khi nhiều hơn một đối tượng cần được thông báo. Hơn nữa, tôi nghĩ rằng trong tình huống này, tốt hơn là có thể nói chuyện trực tiếp với khách hàng (từ quan điểm của nhà cung cấp dịch vụ) để thông báo rằng hoạt động đã kết thúc. Nhưng chắc chắn, Thông báo là một cách khác để xử lý việc này. Có lẽ tôi sẽ cập nhật các câu hỏi sau này bao gồm các thông báo, nhưng bây giờ tôi muốn xem những gì sẽ xảy ra .. : D Cảm ơn một lần nữa! – Lio

0

Một nhược điểm khác cho phương pháp ủy quyền: Nhà cung cấp dịch vụ chỉ có thể có một đại diện. Nếu nhà cung cấp dịch vụ của bạn là một singleton và bạn có nhiều khách hàng, mẫu này không hoạt động.

Điều này khiến tôi đi theo phương pháp Hành động/Mục tiêu. Nhà cung cấp dịch vụ của tôi giữ trạng thái và được chia sẻ giữa nhiều khách hàng.

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