Soluzione di progettazione per la comunicazione tra più livelli

6

Stiamo sviluppando un framework che ha diversi livelli e che verrebbe distribuito in un ambiente multi-thread. Ogni livello può avere il proprio tipo di dati di input / output. Il livello superiore prende l'input, esegue alcune azioni sui dati e lo passa al livello successivo. In base all'output del livello successivo, il livello superiore eseguirà un'altra serie di operazioni sui dati. Interazioni simili si verificano tra altri livelli.

Ci sono due casi d'uso che non abbiamo incorporato nella progettazione originale:

  1. Generazione di metriche sulle operazioni eseguite da ciascun livello sui dati.

  2. La modifica dei dati in un livello influisce sulle operazioni in un altro livello, le modifiche dovrebbero essere registrate e ogni livello dovrebbe avere la capacità di recuperare l'elenco delle modifiche.

Dopo un po 'di riflessione abbiamo trovato due approcci per soddisfare questi requisiti nel progetto esistente:

  1. Usa il pattern di osservatore e lascia che ogni layer riporti le sue modifiche. Queste modifiche possono essere quindi tirate dal livello che deve utilizzarlo.

    Pro:

    • Poiché abbiamo già creato un progetto per il framework e gran parte del lavoro è completo. Questo approccio non richiederebbe modifiche significative al design esistente, se esiste.

    Contro:

    • Diventa difficile gestire (registrare e riportare) le modifiche corrispondenti a ciascun livello.
    • Esiste una classe centrale che aggrega tutti i dati per ogni richiesta. Questa classe si comporta come una variabile globale. Deve essere inizializzato e cancellato dal livello superiore. L'aggiunta di un altro strato superiore potrebbe essere soggetta a errori.
  2. Estendere le classi di dati correnti usando un'interfaccia equivalente a EventContainer. In questo modo tutti i layer registreranno le loro modifiche e le sputeranno nel loro output.

    Pro:

    • Questo approccio è molto più pulito ed estendibile rispetto al modello di osservatore.

    Contro:

    • Richiederebbe modifiche di progettazione significative.
    • Anche il concetto di dati con eventi unisce due preoccupazioni separate in una e non sembra una buona idea.

Vorremmo sapere se esiste un modello di progettazione o qualsiasi altra soluzione che risolva questo problema?

Quale delle due soluzioni di cui sopra dovrebbe essere data maggiore preferenza considerando che vorremmo una soluzione flessibile, estensibile e più pulita?

    
posta intoTHEwild 25.12.2014 - 14:08
fonte

3 risposte

4

We would like to know if there is a design pattern or any other solution that solves this problem?

Per me questo sembra il tipo di problema che Enterprise Integration Patterns risolve utilizzando i canali di comunicazione e il passaggio dei messaggi.

Gli schemi possono essere utilizzati per disaccoppiare la comunicazione tra le applicazioni, tra i livelli o tra i componenti.

Esistono numerosi framework che possono essere utilizzati per implementare questo tipo di applicazioni come Spring Integration , Apache Camel e Mule

Ciò che descrivi mi sembra un Attivatore di servizio . Uno dei molti diversi tipi di endpoint dei messaggi (ME). La comunicazione tra i tuoi componenti avverrà tramite canali dei messaggi .

I componenti / gli attivatori di servizi sono totalmente inconsapevoli l'uno dell'altro e i canali definiscono la pipeline che trasporta i messaggi tra di loro.

La maggior parte dei framework, come Spring Integration, ti fornisce interceptor per avere la possibilità di fare qualcosa con i messaggi mentre fluiscono attraverso la pipeline (equivalente al tuo pattern di osservatore).

Le metriche interessanti possono anche essere acquisite sotto forma di MXBeans come flusso di messaggi attraverso la pipeline.

+----+ channel +----+ channel +----+ | |---------------| |---------------| | | ME | <-message-> | ME | <-message-> | ME | | |---------------| |---------------| | *----+ +----+ +----+

In questo tipo di framework l'astrazione del canale ti dà un sacco di energia. Il canale può essere canali diretti o pubblicare canali di sottoscrizione e la consegna del messaggio può essere sincrona o asincrona. Quindi hai il controllo totale del flusso di messaggi, dell'ampiezza delle transazioni, ecc.

    
risposta data 25.12.2014 - 18:26
fonte
0

Non ho suggerimenti concreti, ma ho alcune domande che potrebbero aiutare a chiarire la situazione.

Che cosa deve essere catturato?

  • Solo lo stato dei dati (corrente) finale; cioè circa i risultati, non i processi.
  • Istantanee degli stati dei dati in vari punti temporali.
  • Una descrizione abbreviata dei processi applicati.
    "abbreviato" come in: ridotto, riassunto; al contrario della "perfetta cattura" descritta in seguito.
  • Una perfetta cattura dei parametri di ogni singolo processo che sia mai accaduto;
    "perfetto" come abilitare un perfetto "record-replay" di tutte le trasformazioni di dati in un secondo momento;
    come in data provenance nella gestione dei dati scientifici.

Qual è il paradigma generale del sistema?

Questa domanda non riguarda i linguaggi di programmazione o lo stile di codifica; chiede come vengono propagate le modifiche dei dati nel sistema.

  • Imperativo / comando-e-controllo
  • Basato su evento / basato su regole / attivato / logico / reattivo
  • Pull-based / functional / Lazy-evaluation / on-demand
  • Basato su obiettivo / ottimizazionale / algoritmico

imperativo

Descrizione del campione: una classe upper-echelon (boss) invia uno o più comandi di elaborazione a un numero di classi di livello inferiore (subordinato). Ciascuna classe lower-echelon suddivide il comando ricevuto e invia quei sottocomandi a peon (worker) di livello inferiore per l'elaborazione.

Basato sugli eventi

Descrizione del campione: sono registrate numerose condizioni di attivazione: "se QUESTO succede allora fai QUI ". Ogni volta che i dati vengono modificati, vengono verificate le condizioni di attivazione; se ci sono corrispondenze, vengono eseguite le azioni registrate. Dopo aver eseguito le azioni registrate, potrebbero essere attivati più trigger, dando luogo a una reazione a catena.

Pull-based

All'inizio, tutto ciò che viene definito è un insieme di segnaposti (identificatori) per ogni parte di dati, insieme a caselle nere che trasformano alcune parti di dati in altre porzioni di dati.

Il consumatore finale (definitivo) di una parte di dati effettua la richiesta al sistema. Il sistema controlla se i dati sono disponibili; se non lo è, cerca le scatole nere che sarebbero in grado di produrre quei dati. Una volta trovato, controlla se la scatola nera ha tutti i dati prerequisiti da avviare. In caso contrario, il sistema tenta di eseguire nuovamente la ricerca di black box a monte che preparano i prerequisiti mancanti. In definitiva, la ricerca avrebbe colpito alcuni dati preesistenti nel datastore e pertanto la pipeline di elaborazione può essere avviata.

Goal-based

L'utente del sistema specifica lo stato obiettivo desiderato o la metrica dell'ottimalità, come ad esempio le funzioni di costo da minimizzare, o altre metriche di prestazione da misurare sui dati. WHAT è specificato; il HOW non è specificato. Cioè, come il sistema raggiunge quell'obiettivo (o, se tale obiettivo è raggiungibile o meno) non è specificato dall'utente. Il sistema dovrebbe in qualche modo risolvere quel mistero.

Tali sistemi fanno un uso pesante della ricerca in informatica, algoritmo e teoria matematica. Questi sistemi sono altamente specializzati nel tipo di soluzioni che possono cercare.

A causa della natura di tali sistemi, lo stato generale corrente è solitamente in bella vista da ogni componente all'interno del sistema. Nell'attuazione viene utilizzata un'ampia varietà di approcci (paradigmi); tutti i paradigmi summenzionati (imperativo, basato sugli eventi, pull-based, algoritmico, iterativo) possono essere utilizzati in combinazione per raggiungere l'obiettivo.

    
risposta data 25.12.2014 - 20:18
fonte
0

Rendere probabilmente l'intera comunicazione tra i tuoi livelli basata sugli eventi potrebbe risolvere i tuoi problemi. Ma invece di aggiungere la meccanica degli eventi ai percorsi di comunicazione esistenti (che potrebbero unire due preoccupazioni distinte, come hai scritto), potresti sostituire il modo di comunicare esistente completamente un sistema basato su eventi.

Se ciascuno dei tuoi livelli comunica con gli altri livelli solo per gli eventi, in genere sarà solo un piccolo passaggio per rendere questi livelli indipendenti gli uni dagli altri, il che aiuterà a ridurre l'accoppiamento complessivo in fase di compilazione nel tuo sistema, con vantaggi come test più semplici, monitoraggio più facile, registrazione degli eventi più semplice.

Due modelli architettonici che possono aiutarti a raggiungere questo obiettivo sono Comando Segregazione di responsabilità delle query (CQRS) e Sourcing di eventi . Soprattutto il secondo persisterà ogni evento interessante, che renderà molto facile risolvere esattamente i due problemi che hai menzionato all'inizio della tua domanda.

Naturalmente, come hai correttamente notato da solo, questo potrebbe essere un significativo cambiamento di progettazione, e devi decidere da solo se ciò è fattibile nella tua situazione attuale.

    
risposta data 27.12.2014 - 11:03
fonte

Leggi altre domande sui tag