Rivisitare l'articolo "Public versus Published Interfaces" di Fowler per quanto riguarda il controllo delle versioni e i microservizi

2

In questo breve articolo Public versus Published Interfacce del 2002, Martin Fowler distingue tra "interfacce pubbliche" facilmente mutevoli e più difficili da cambiare "interfacce pubblicate":

The key difference is being able to find and change the code that uses an interface. For a published interface, this isn’t possible, so you need a more elaborate interface update process.

Indietro dei suoi consigli sulla pubblicazione inclusi:

  1. Non trattare le interfacce come pubblicate a meno che non siano
  2. Non pubblicare interfacce all'interno di un team
  3. Pubblica il meno possibile il più tardi possibile

L'articolo è stato scritto nel 2002 prima che le architetture basate su microservizi diventassero popolari. Nella mia azienda, ci stiamo spostando verso i microservizi e stiamo anche preparando il passaggio da un edificio dal modello sorgente al controllo delle versioni. L'ipotesi è che sia più semplice supportare lo sviluppo in un'organizzazione con un numero crescente di sviluppatori, poiché il controllo delle versioni consente un maggiore controllo su quando si desidera applicare le modifiche al codice, poiché è necessario aumentare attivamente la versione della libreria da cui si dipende .

Quando leggo ora l'articolo di Martin Fowler, trovo i suoi argomenti molto convincenti. D'altro canto, le architetture dei microservizi e anche il controllo delle versioni interno sembrano essere tendenze che portano a più interfacce pubblicate.

Devo ammettere che non ho esperienza con i microservizi. Quando si parla di versioning interno, non mi aspetto molta esperienza per alcuni progetti Javascript più piccoli in cui abbiamo diviso il nostro codice in piccoli progetti e utilizzato npm per gestire le dipendenze. La maggior parte del mio tempo, ho lavorato a progetti Java medio-grandi in cui si costruisce dalla fonte e che aveva per lo più un'architettura monolite. Aspettatevi la comunicazione RMI tra i componenti, la maggior parte delle interfacce potrebbe essere classificata come pubblica (non pubblicata).

Forse mi manca qualcosa, ma vedo alcuni obiettivi contrastanti nelle ultime tendenze e l'articolo di Martin Fowler di 14 anni fa. Ad esempio, "Non pubblicare interfacce all'interno di un team" sembra essere in conflitto con la tendenza che ogni team cerca di suddividere il suo progetto in molti piccoli servizi indipendenti con un'interfaccia "pubblicata" ben definita. Anche l'introduzione della versione semantica di tutte le librerie e dei piccoli progetti API sembra essere una violazione di tale consiglio e rende più difficile il refactoring.

Sono un po 'confuso, quindi volevo chiarire in quali condizioni pubblicare un'interfaccia ha più vantaggi che evitarlo a tutti i costi. Ecco la mia comprensione di entrambe le parti, correggimi se ho sbagliato.

In breve l'argomento di Martin Fowler:

  • Evita le interfacce pubblicate perché impedisce il refactoring

Argomento microservice:

  • Dividi il tuo sistema in piccoli servizi con un'interfaccia ben definita, in quanto è più facile da capire.
  • Invece di refactoring un monolite, tutti i servizi sono così piccoli che possono essere facilmente comunque

L'altro argomento "build from source" vs version management non viene toccato nell'articolo e non è strettamente necessario nelle architetture dei microservizi, ma volevo comunque menzionarlo perché vedo un simile compromesso:

  • Avere accesso a tutto il codice sorgente consente un più facile refactoring al costo di dover lavorare con più codice; le modifiche ad alcune librerie diventano immediatamente visibili ai progetti dipendenti (che possono essere un vantaggio o uno svantaggio)
  • La gestione delle versioni interne consente di eseguire il checkout solo del codice necessario ma rende più difficile il refactoring a meno che gli sviluppatori non abbiano una grande disciplina nell'aggiornare le loro dipendenze regolarmente (altrimenti, le interfacce pubbliche diventano "pubblicate" in modo simile all'esempio strong di proprietà del codice nell'articolo ).
  • Se alcuni progetti non vogliono aggiornare il loro codice, puoi comunque eseguire dei refactoring non retrocompatibili, ma in seguito avrai un lavoro aggiuntivo quando infine aggiornerai gli altri progetti.

La mia conclusione attuale è che la tendenza è incoraggiare le interfacce di pubblicazione al fine di separare i servizi il più possibile. In altre parole, la raccomandazione nell'articolo per lo più non si applica più alle odierne architetture di sistema preferite. Si applica ancora all'implementazione di un microservizio internamente, ma quando sono abbastanza piccoli non rimangono troppe interfacce non pubblicate. Quindi il consiglio era più pertinente nel 2002, dove i monoliti erano più comuni.

Saresti d'accordo? (Disclaimer: Come ho detto, sono abbastanza un novizio su questo argomento.)

    
posta Philipp Claßen 03.06.2016 - 19:28
fonte

2 risposte

1

Il punto di Fowler è essenzialmente che una volta che hai "pubblicato" un'interfaccia, sei bloccato con esso. Essenzialmente sei diventato dipendente da qualcosa al di fuori del tuo controllo e più la tua interfaccia è popolare, più è difficile capire l'impatto di cambiarlo. Questo è solo un aspetto fondamentale della realtà.

In definitiva, ecco cosa succede: crei alcuni servizi. Le persone trovano valore in quei servizi e creano dipendenza da loro nei loro sistemi e passano a lavorare su altre cose. Quindi, decidi di voler cambiare il tuo servizio. È assolutamente possibile ma quando lo fai rompi questi sistemi e molto probabilmente li fa arrabbiare. Meno conosci i tuoi consumatori, più è difficile mitigarli. Quindi devi capire quanto ti preoccupi di creare problemi per questi utenti.

Se ti interessa, devi pianificare di essere in grado di mantenere più versioni dello stesso servizio. Questo ti permette di andare avanti.

Qui è un altro articolo di Fowler che indirizza direttamente i microservizi e penso che sia superiore a quello che fai riferimento qui. È la spiegazione più completa e ben scritta dei microservizi che ho visto. A mio avviso, i microservizi riguardano meno la struttura dell'interfaccia rispetto al modo in cui vengono distribuiti e il problema che si pone è ortogonale alla questione delle piattaforme di servizio monolitiche rispetto ai microservizi.

    
risposta data 03.06.2016 - 22:25
fonte
1

Nel suo articolo sui microservizi del 2014, Martin Fowler elenca l'aspetto del refactoring come un inconveniente, ma conclude che i vantaggi di i microservizi pesano più pesantemente:

There are certainly reasons why one might expect microservices to mature poorly. In any effort at componentization, success depends on how well the software fits into components. It's hard to figure out exactly where the component boundaries should lie. Evolutionary design recognizes the difficulties of getting boundaries right and thus the importance of it being easy to refactor them.

But when your components are services with remote communications, then refactoring is much harder than with in-process libraries. Moving code is difficult across service boundaries, any interface changes need to be coordinated between participants, layers of backwards compatibility need to be added, and testing is made more complicated.

... So we write this with cautious optimism. So far, we've seen enough about the microservice style to feel that it can be a worthwhile road to tread. We can't say for sure where we'll end up, but one of the challenges of software development is that you can only make decisions based on the imperfect information that you currently have to hand.

L'argomento del versioning esplicito rispetto a building from source potrebbe essere una questione di supporto per gli strumenti alla fine. Sembra essere opinione condivisa che la gestione delle dipendenze con il controllo delle versioni esplicito non abbia implicazioni sul fatto che le API siano considerate pubblicate.

Al lavoro, il passaggio a versioni esplicite al momento interrompe il supporto degli strumenti. Ad esempio, i refactoring come i metodi o le classi di rinomina non sono più supportati, in quanto l'IDE non può tracciare come viene usato il codice. A meno che non venga utilizzato nei test, IntelliJ contrassegna le API come codice morto, ora. I riferimenti di ricerca funzionano solo se li si applica alle classi nel jar.

Può essere mitigato passando temporaneamente tutte le dipendenze alle dipendenze dello snapshot (stiamo usando Maven). Quindi, l'IDE capisce di nuovo chi usa l'interfaccia e quindi può applicare automaticamente le modifiche.

Quindi, presumo che sia tecnicamente possibile configurare un ambiente se si hanno entrambi (versione esplicita e supporto per il refactoring). In questo senso, è una decisione indipendente dalla discussione sulle interfacce "public vs public".

    
risposta data 15.06.2016 - 19:51
fonte