Ingegneria interna di un framework RAD... come sviluppatore PHP con Nooku
Pubblicato: 2022-03-11Ognuno ha il proprio set di strumenti. Come sviluppatore PHP, uno dei miei preferiti è un framework di sviluppo rapido di applicazioni chiamato "Nooku". Nelle parole del gruppo di sviluppo: "Nooku è più un toolkit di sviluppo web che un framework".
Nel caso non lo conoscessi, dai un'occhiata. È un progetto open source che fa un uso massiccio di modelli di progettazione accettati dal settore per produrre applicazioni altamente componentizzate che sono facilmente estensibili e riutilizzabili (inizialmente create da uno dei principali sviluppatori Joomla!). Immediato, Nooku ti offre una grande quantità di strumenti di sviluppo rapido di applicazioni per aiutare a far decollare i progetti più velocemente. Un piccolo, ma forte campione:
- Un'implementazione predefinita di MVC in cui tutto ciò che devi fare è scrivere il layout (questo è ciò che mi ha agganciato)
- Disponibilità immediata di HMVC
- Supporto per diversi formati di output come JSON e XML per tutti i tuoi dati (ad esempio, esponi la tua API in pochi minuti)
- Implementazioni amministrative e front-end predefinite
Al centro di Nooku c'è il principio di progettazione "Composizione sull'ereditarietà" (in effetti, è il primo concetto nella pagina introduttiva di Nooku. In una riga: dovresti mirare a comporre (o sommare) le funzionalità di più oggetti per creare alcuni sorta di oggetto composito, piuttosto che fare affidamento sulla sottoclasse.
Questo principio ti consente di scrivere meno codice e spesso porta ad alcune soluzioni piuttosto eleganti. Quindi, come viene esattamente promosso? Ebbene, a livello di codice, i migliori esempi vengono dall'uso di Mixin e Identificatori di risorse/servizi. Diamo un'occhiata.
Il Mixin
Prima di PHP 5.4, il linguaggio non aveva il concetto di Traits . Si tratta di strutture simili a classi che, quando "utilizzate" da un oggetto, forniscono un qualche tipo di funzionalità (simile all'ereditarietà multipla). Nooku risolve questo problema da anni (da PHP 5.2) con Mixin .
Il Mixin non solo ti consente di comporre oggetti insieme, ma aggiunge anche i metodi di ogni oggetto misto all'interfaccia dell'oggetto composto. L'oggetto che utilizza il mixin sembra "ereditare" i metodi dell'oggetto misto.
/** * Mixin an object * * When using mixin(), the calling object inherits the methods of the mixed * in objects, in a LIFO order. * * @param KMixinInterface $object An object that implements KMinxInterface * @return KObject */ public function mixin(KMixinInterface $object) { $methods = $object->getMixableMethods($this); foreach($methods as $method) { $this->_mixed_methods[$method] = $object; } // Set the mixer $object->setMixer($this); return $this; }
Quasi tutti gli oggetti in Nooku hanno questa capacità perché estendono la classe base KObject che ha definito il metodo mixin .
Anche le classi principali nell'architettura del controller di Nooku discendono da KObject. Il controller astratto è la classe KControllerAbstract e da un'ispezione puoi vedere che sfrutta subito l'abilità Mixing. Ogni volta che viene creata un'istanza di questa classe, le funzionalità KMixinCommand e KMixinBehavior vengono immediatamente aggiunte alla sua interfaccia. Di conseguenza, ogni controller in Nooku è composto da funzionalità di Command Chain e Behavior management attraverso i rispettivi oggetti.
Perché la K davanti a tutti i nomi delle classi? La libreria principale di Nooku è denominata in codice "Koowa".
Tornando al controller Nooku: la classe KMixinBehavior contiene tutti i pezzi per dare a KControllerAbstract la possibilità di caricare comportamenti specifici in fase di esecuzione. Le strategie comportamentali sono classi che descrivono un processo o una logica che può essere separata e utilizzata da altre classi (ad esempio, modificabile, ordinabile). KMixinBehavior è abbastanza semplice e ha solo quattro metodi: getBehavior, hasBehavior, addBehavior e getBehaviors. E questo è tutto ciò di cui abbiamo bisogno per dare a un oggetto la capacità di gestire e incapsulare diverse strategie comportamentali.
Allo stesso modo, KMixinCommand ha solo tre metodi: getCommandContext, getCommandChain, setCommandChain. Se non avevi indovinato, questi tre metodi forniscono a KControllerAbstract la possibilità di implementare una catena di comandi, ma lo consentono in fase di esecuzione.
Puoi pensare a questa miscelazione come a una semplice aggiunta aritmetica:
Ci fornisce un'interfaccia simile a questa:
Per definizione le classi astratte sono pensate per essere estese e quindi, grazie alla magia dell'ereditarietà, tutti gli oggetti che sono figli o istanze di KControllerAbstract ottengono anche la capacità di aggiungere comportamenti e una catena di comandi in fase di esecuzione.
Figo. Ma cosa significa in realtà? In breve, Nooku fornisce funzionalità componenti; ovvero, Nooku ti consente di modulare le tue funzionalità e comporre funzionalità tra i moduli in fase di esecuzione.
Questi due esempi servono a dimostrare la composizione. Servono anche a dimostrare il supporto del framework Nooku RAD per un'ulteriore composizione al suo interno. Questo è un vantaggio importante. I metodi aggiunti a KControllerAbstract sopra supportano lo "Strategy Design Pattern" fornendo agli sviluppatori gli strumenti per incapsulare ciò che varia prima che una riga di codice sia stata scritta. Il fatto che il metodo mixin() sia parte di ogni estensione di KObject significa che puoi facilmente definire e aggiungere altre interfacce di gestione comportamentale alla maggior parte degli oggetti in fase di esecuzione.

Identificatori e localizzatori di servizi e risorse: separa il nome della mia classe dal mio oggetto
Gli identificatori e i localizzatori di servizi e risorse in Nooku forniscono anche un potente supporto per la separazione delle preoccupazioni.
Di nuovo, diamo un'occhiata a KObject, ma anche a KService. Possiamo trattare la maggior parte delle cose in Nooku come un servizio o una risorsa, e come tali istanziarle e interrogarle esattamente allo stesso modo.
Pensa a un servizio come a qualcosa da cui ottieni una risorsa. Tutti i servizi sono risorse ma non tutte le risorse sono servizi
Quando vai in un negozio di alimentari e acquisti un prodotto, pensa al negozio come al Servizio, cioè a una raccolta di articoli che puoi selezionare ; e il prodotto come Risorsa, ovvero un unico oggetto/soluzione logica che può essere:
- guardato in modo specifico ( Leggi ) (es. guardando una lattina di zuppa di pomodoro)
- spostato nel negozio ( E dited) (ad esempio, spostare la zuppa nel corridoio dei prodotti)
- aggiunto o rimosso dall'inventario del negozio (Aggiungi ed Elimina ) (ad es. aggiungi un nuovo tipo di zuppa ed elimina il pomodoro)
Prendendo questo esempio ancora più in là, immagina che il negozio di alimentari abbia un reparto in franchising e tu voglia essere in affari. In quella situazione, il Servizio è il dipartimento in franchising e la risorsa è il negozio di alimentari che acquisti. È molto una classificazione contestuale. Nel complesso, questo è noto come modello di azione BREAD (vedrai ognuno di questi rappresentato tra KControllerService e KControllerResource anteposto con '_action', cioè _actionRead()).
Un modello può essere un servizio, un oggetto tabella può essere considerato un servizio, una specifica triade MVC viene istanziata come una risorsa o un servizio, mentre un record specifico risultante dall'interrogazione del servizio può essere considerato una risorsa.
Ogni oggetto in Nooku è una composizione di oggetti in quanto ognuno di essi contiene un riferimento ai servizi istanziati dell'intera applicazione in un "contenitore di servizi" e un metodo per accedere ai servizi chiamato getService(). Tutto ciò che è richiesto dal metodo KObject::getService() è che passiamo un identificatore di risorsa valido e restituirà un servizio istanziato pronto per l'uso.
Nello sviluppo rapido di applicazioni PHP, gli identificatori di risorse forniscono un modo efficace per disaccoppiare l'istanziazione di un oggetto dal nome della sua classe e quindi fornire alias per tale identificazione. Ciò ha importanti implicazioni sulla manutenibilità di un'applicazione. Attraverso l'alias uno sviluppatore può cambiare la classe usata da ogni oggetto che viene istanziato con un dato identificatore aggiungendo una riga di codice con KService::addAlias().
Un esempio di identificatore di risorsa che conosciamo è l'URI o Uniform Resource Identifier:
Queste sono tutte le informazioni necessarie a KService per individuare e caricare la classe appropriata. Questi pezzi corrispondono alle convenzioni di denominazione e posizionamento delle classi di Nooku che forniscono prevedibilità del posizionamento e dell'istanza. L'esempio di identificatore di cui sopra (com://site/user.database.table.user) tenta di caricare il file /components/com_user/databases/tables/user.php, che ha un nome di classe ComUserDatabaseTableUser. Per inciso, se il file non esiste, il framework ti darà un oggetto tabella predefinito e lo costruirà in base alla denominazione del database e alle convenzioni dello schema id (questo mi ha catturato ancora di più). Come accennato in precedenza, KService ti consente anche di impostare alias per i tuoi identificatori. Usando KService::setAlias('maindbaseadapter','com://admin/default.database.adapter.mysqli')
; ci consente di caricare un oggetto db con KService::getService('maindbaseadapter')
.
Questo ci dà il disaccoppiamento di cui abbiamo parlato e fornisce un netto vantaggio nella manutenzione e nell'estensione delle nostre applicazioni. Siamo liberi di creare applicazioni diverse da "sito" e "amministratore" se necessario e tramite gli identificatori qui descritti possiamo utilizzare prontamente servizi che si trovano in altre applicazioni per aiutare le nostre soluzioni a soddisfare i loro requisiti. Ancora una volta, questo è un altro esempio di come Nooku fornisce agli sviluppatori e ai team PHP e RAD il supporto per la composizione non solo di oggetti di singole classi ma di interi servizi e applicazioni... gratuitamente.
Riassumendo
Con la composizione sull'eredità al centro; le composizioni e le strutture intelligenti e preesistenti che esistono per supportare ulteriori amalgame; e l'architettura gratuita orientata ai servizi con gli identificatori qui descritti, Nooku fornisce un potente framework RAD con un vantaggio significativo rispetto a tutti i suoi strumenti di sviluppo PHP peer.