Perché i quadri per gli ombrelli sono scoraggiati?

Voglio distribuire Framework A. Framework A dipende dal Framework B. Voglio che un utente del mio framework abbia solo bisogno di includere il Framework A, ma ha comunque accesso programmatico al Framework B.

Apple fa tutto il tempo usando il concetto di “Umbrella Frameworks”, ma c’è questo argomento nei documenti:

Non creare framework per ombrelli

Mentre è ansible creare framework di ombrelli usando Xcode, farlo non è necessario per la maggior parte degli sviluppatori e non è raccomandato. Apple utilizza i framework di ombrelli per mascherare alcune delle interdipendenze tra le librerie nel sistema operativo. In quasi tutti i casi, dovresti essere in grado di includere il codice in un unico pacchetto di framework standard. In alternativa, se il tuo codice fosse sufficientemente modulare, potresti creare più framework, ma in quel caso le dipendenze tra i moduli sarebbero minime o inesistenti e non dovrebbero garantire la creazione di un ombrello per loro.

Perché questo approccio è scoraggiato? Cosa lo rende una buona soluzione per il problema dei quadri interdipendenti di Apple ma non per il mio?

I framework per gli ombrelli hanno senso solo se sei l’unico distributore di tutti i framework coinvolti e dovrai impacchettare tutti i framework insieme come un singolo pacchetto con versione che verrà aggiornato insieme. Se questa è la tua situazione, allora va bene, ma questa è una situazione molto insolita. Nel mondo dello sviluppo Cocoa, è estremamente insolito per chiunque, tranne Apple, trovarsi in questa situazione.

Per quanto riguarda il primo punto, i framework ad ombrello hanno senso solo se sei l’unico distributore dei framework dati. Ad esempio, supponi di volere includere libcurl come parte del tuo framework di ombrelli. Ora alcuni altri packager vogliono anche includere libcurl come parte del suo framework ombrello. Ora abbiamo una collisione link-time che può portare a errori di link o comportamento di runtime peggiore, non definito. Li ho inseguiti personalmente. Sono estremamente sgradevoli. L’unico modo per evitare questo è che ci sia solo una singola versione di ogni framework / libreria. Le strutture a ombrello incoraggiano il contrario.

Anche se stai semplicemente suddividendo il tuo codice in sottopezze, ciò significa che altri fornitori potrebbero utilizzare i tuoi sub-framework nei loro stessi framework, portando allo stesso problema. Ricorda, se dici che per te è una terza parte usare i framework di ombrelli, allora va bene anche per altri fornitori.

Per il secondo punto, i framework ad ombrello hanno senso solo se si controlla il controllo delle versioni di tutti i sub-framework. La mia esperienza di patch su un pezzo di un insieme di strutture interdipendenti è quasi sempre un disastro.

Il fornitore del sistema operativo ha una situazione insolita a causa delle dimensioni e dell’ubiquità del loro sistema. Le cose che hanno senso in una scala spesso non hanno senso in un’altra. NSResponder è completamente corretto su questo. I compromessi sono diversi quando si fornisce un ambiente di pacchetto completo e plurimila che è la base di ogni programma scritto per la piattaforma. Ma anche Apple ha solo una manciata di grandi framework di ombrelli, e sono sempre wrapper attorno alle librerie che forniscono e controllano la versione di. Questo è principalmente per semplificare il lavoro degli sviluppatori che altrimenti avrebbero dovuto inseguire dozzine di librerie e framework per ottenere qualcosa da compilare. Nessuna terza parte ha questa situazione, quindi è molto raro che una terza parte abbia bisogno di questa soluzione. Chiedere al cliente di colbind due librerie è completamente diverso, chiedendo loro di collegarsi 20. Se stai fornendo 20 framework che funzionano tutti insieme e tu controlli, allora forse dovresti usare un ombrello, ma forse hai troppi framework per un terzo.

La maggior parte della mia discussione qui è in termini di OS X. Su iOS è un non-problema per terze parti. Le librerie statiche non devono mai colbind altre librerie statiche a causa delle collisioni che si verificheranno.

In teoria, la maggior parte dei problemi che ho discusso qui sono un limite fondamentalmente tecnico del linker. Il linker non ha un buon modo per gestire più versioni di librerie e quindi le collisioni sono un problema serio. Gli assembly .NET cercano di fornire maggiore flessibilità attorno a questo. Non conosco abbastanza bene lo sviluppo di .NET per dire se questo ha avuto successo o meno. La mia esperienza con i sistemi multicomponenti di grandi dimensioni è che soluzioni più semplici e meno flessibili sono le migliori per la maggior parte dei problemi. (Ma poi, l’erba è sempre più verde ….)

Un problema è che la versione del framework B è ora legata alla versione del framework A. Questo potrebbe essere ciò che si desidera in alcuni casi e non in altri. Se il framework B è probabile che venga utilizzato indipendentemente da un’app che vuole utilizzare il framework A, l’app potrebbe trovarsi in una situazione in cui la versione di B inclusa in A non è la versione di cui ha bisogno o che desidera.

Il framework B è un framework che un’app potrebbe utilizzare indipendentemente da A? Se è così allora potresti imbatterti in questo scenario. Se B è un framework che non è disponibile al di fuori di A, non dovresti imbatterti in questo scenario.

Nel caso di Apple, stanno offrendo un’enorme quantità di codice e questi sottoprogrammi sono spesso rivisti separatamente. Se stai consegnando diversi concerti di quadri, allora potresti voler andare avanti e creare un quadro a ombrello. In caso contrario, probabilmente non ti serviranno problemi.