2011-08-31 25 views
11

Tôi đang xử lý ứng dụng python bao gồm nhiều thành phần trọng lượng nhẹ được phân phối giao tiếp sử dụng RabbitMQ & Kombu.Thêm hành vi REST vào một lớp với bình, trường hợp cho bản thiết kế?

Một thành phần lắng nghe trên hai hàng đợi và có thể nhận nhiều loại thông báo trên mỗi hàng đợi. Các lớp con có thể ghi đè cách mỗi loại thông báo được xử lý bằng cách đăng ký trình xử lý tùy chỉnh. Tất cả điều này hoạt động tốt.

Tôi hiện có yêu cầu thêm rằng mỗi thành phần phải có giao diện REST/HTML cơ bản. Ý tưởng là bạn trỏ trình duyệt của mình tại thành phần đang chạy và nhận thông tin thời gian thực về nội dung hiện đang thực hiện (thông báo nào đang xử lý, sử dụng cpu, thông tin trạng thái, nhật ký, v.v.)

Nó cần phải có trọng lượng nhẹ sau khi một số nghiên cứu tôi đã giải quyết trên Flask (nhưng đang mở để gợi ý). Trong giả này có nghĩa là thực hiện:

class Component: 
    Queue A 
    Queue B 
    ... 
    def setup(..): 
    # connect to the broker & other initialization 

    def start(..): 
    # start the event loop and wait for work 

    def handle_msg_on_A(self,msg): 
    # dispatch a msg to a handler depending on the msg type 

    def handle_msg_on_B(self,msg): 
    ... 

    ... 

và thêm một số quan điểm phương pháp:

@app.route('/') 
    def web_ui(self): 
     # render to a template 

    @app.route('/state') 
    def get_state(self): 
     # REST method to return some internal state info as JSON 

    ... 

Tuy nhiên, sự bỏ rơi một giao diện web vào một lớp học như thế này phá vỡ SOLID nguyên tắc và mang lại vấn đề với thừa kế (một lớp con có thể muốn hiển thị nhiều thông tin hơn/ít hơn). Trang trí không được kế thừa vì vậy mọi phương pháp xem sẽ cần phải được ghi đè rõ ràng và được trang trí lại. Có thể sử dụng mixin + reflection có thể làm việc bằng cách nào đó nhưng nó cảm thấy bị hack. Thay vào đó, việc sử dụng bố cục có thể hoạt động: đặt nội dung web trong một lớp riêng biệt ủy quyền cho các tuyến đường url đến một tập hợp các phương pháp đa hình được xác định trước trên thành phần lồng nhau. Thành phần cách này vẫn không nhận thức được Flask với chi phí mất mát linh hoạt (tập hợp các phương pháp sẵn có được sửa).

Tôi hiện đã phát hiện Flask blueprintsApplication Dispatching và có vẻ như họ có thể mang lại giải pháp tốt hơn, dễ mở rộng hơn. Tuy nhiên, tôi vẫn chưa quấn quanh đầu họ.

tôi cảm thấy như tôi đang thiếu một mẫu thiết kế ở đây và hy vọng ai đó có nhiều bình-fu hoặc kinh nghiệm với loại vấn đề có thể bình luận.

Trả lời

11

Cái gì khác đã lặng lẽ giới thiệu trong Flask 0.7 mà có thể quan tâm đến bạn - Pluggable Views. Đây là các lớp dựa trên chứ không phải là điểm cuối dựa trên chức năng - vì vậy bạn có thể sử dụng phương thức dispatch_request để quản lý quá trình chuyển đổi trạng thái của mình (chỉ ghi đè khi cần).

Lợi ích của việc thực hiện theo cách này, trái ngược với việc sử dụng Gửi ứng dụng, là bạn nhận được url_for hỗ trợ tất cả trên ứng dụng của bạn (trái ngược với việc phải mã cứng trong các URL vượt qua ranh giới ứng dụng). quyết định xem đây có phải là vấn đề có thể gây ra cho ứng dụng của bạn hay không.

Trong pseudo-code:

# File: Components.py 
from flask.views import View 

class Component(View): 
    # Define your Component-specific application logic here 

    dispatch_request(self, *url_args, **url_kwargs): 
     # Define route-specific logic that all Components should have here. 
     # Call Component-specific methods as necessary 

class Tool_1(Component): 
    pass 

class Tool_2(Component): 
    # Override methods here 

# File: app.py 
from flask import Flask 
from yourapplication import Tool_1, Tool_2 

app = Flask() 

# Assuming you want to pass all additional parameters as one argument 
app.add_url_rule("/tool_1/<path:options>", "tool1", view_func=Tool_1.as_view()) 

# Assuming you want to pass additional parameters separately 
tool_2_view = Tool_2.as_view() 
app.add_url_rule("/tool_2/", "tool2", view_func=tool_2_view) 
app.add_url_rule("/tool_2/<option>", "tool2", view_func=tool_2_view) 
app.add_url_rule("/tool_2/<option>/<filter>", "tool2", view_func=tool_2_view) 

Bạn thể thêm bản thiết kế để trộn nếu bạn có một loạt các thành phần đó đều được kết nối với nhau một cách hợp lý và bạn không muốn phải nhớ đặt số /prefix trước cuộc gọi add_url_rule của mỗi người. Nhưng nếu bạn chỉ có một loạt các thành phần là chủ yếu là độc lập với nhau, đây là mẫu tôi muốn sử dụng *.

*. Mặt khác, nếu chúng cần phải là bị tách biệt với nhau, tôi sẽ sử dụng mẫu Công văn ứng dụng được đề xuất trong tài liệu.

+0

Tuyệt vời, cảm ơn câu trả lời, chắc chắn sẽ xem xét và phê duyệt câu trả lời nếu nó hoạt động ra – dgorissen

+0

Đã làm việc @dgorissen –

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