Přidání chování pomlku třídy s baňky, pouzdro pro plány?

hlasů
11

Zabývám se žádostí o python, který se skládá z několika distribuovaných lehkých prvků, které spolu komunikují pomocí RabbitMQ & kombu .

Součástí poslouchá na dvou frontách a může přijímat různé typy zpráv v každé frontě. Podtřídy lze přepsat, jak je každý typ zprávy zpracovány pomocí registrace vlastní rutiny. To vše funguje dobře.

Teď mají další požadavek, aby každá složka musí mít základní REST / HTML rozhraní. Představa, že ukážete prohlížeče na pojížděcí části a získat v reálném čase informace o tom, co je v současné době dělá (jaké zprávy je zpracování, využití cpu, state info, log, atd.)

To musí být lehká, takže po delším zkoumání jsem se usadil na Baňka (ale jsem otevřený návrhům). V pseudokódu to znamená odběr:

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):
     ...

   ...

a přidá řadu zobrazení metod:

   @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

   ...

Nicméně, vybíhání webové rozhraní na třídě, jako je tato zlomí SOLID zásady a přináší problémy s dědictvím (podtřída může chtít zobrazit více / méně informací). Dekoratérů nejsou zděděné takže každý způsob pohledu by bylo třeba explicitně přepsána a vymalovaný. Možná použití mixin + reflexi by mohlo fungovat tak nějak, ale to je hackish.

Místo toho, s použitím složení by mohlo fungovat: dát webové věci v samostatné třídě, která deleguje na url cesty na pevnou, předem definovaných polymorfních metod na vnořené komponenty. Tímto způsobem komponenty zůstávají nevědomý Baňka za cenu určité ztráty flexibility (sady dostupných metod je pevná).

Nyní jsem zjistil, baňky plány a aplikací dispečinku a vypadá to, že by mohla přinést lepší, rozšiřitelné řešení. Nicméně, ještě jsem se zabalit hlavu kolem nich.

Mám pocit, že jsem chybí návrhový vzor tady a doufám, že někdo s větší baňky-fu nebo zkušenosti s tímto typem problému může vyjádřit.

Položena 31/08/2011 v 13:27
zdroj uživatelem
V jiných jazycích...                            


1 odpovědí

hlasů
11

Něco jiného byl tiše představil v baňce 0.7, které by mohly být pro vás zajímavé - Zásuvné pohledů . Jedná se o třídu založeny nikoli koncových bodů založených na funkčních - takže můžete použít dispatch_requestmetodu pro správu státní přechody (pouze jej přepsáním v případě potřeby).

Přínosem dělat to tímto způsobem, ve srovnání s použitím aplikace dispečink, je, že dostanete url_forpodporu celé aplikace (na rozdíl od nutnosti pevný kód v URL, které překračují hranice aplikací.) Budete se muset rozhodnout, zda je to něco, že je pravděpodobné, že bude problém pro vaši aplikaci.

V pseudo-kódu:

# 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)

Vy můžete přidat plány do mixu, pokud máte řadu komponent, které jsou logicky spojeny dohromady a vy nechcete mít na paměti, aby /prefixv přední části každého něčí add_url_rulevolání. Ale stačí, pokud řadu komponent, které jsou většinou na sobě nezávislé, je to vzor bych použít *.

*. Na druhou stranu, v případě, že je třeba izolovat od sebe bych použít Application Dispatch vzor doporučenou v docs.

Odpovězeno 31/08/2011 v 18:23
zdroj uživatelem

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more