3. La situazione attuale
Il software è un unico programma
winform che contiene tutta la logica nel
Monolitico code behind di una form
L’accesso all’hardware è effettuato
direttamente nel code-behind, il software
Hardware
può quindi essere lanciato solamente in
presenza dell’hardware
Non è presente nessun test
automatizzato, i test vengono fatti
Bad testing lanciando il software ed utilizzandolo con
l’hardware connesso
4. L’evoluzione richiesta
Il software deve poter essere eseguito
come servizio di windows, quindi senza
Servizi
interazione con l’utente e senza ui
È comunque necessario avere una
interfaccia per poter inviare alcuni
User interface
messaggi e verificare lo stato del servizio
5. Il “desiderata”
Poter effettuare test funzionali di interfaccia senza avere
l’hardware connesso. Possibilità di simulare le varie
condizioni dell’hardware (faulting, disconnection, etc)
Hardware Free
Essere se possibile indipendenti dall’hardware, poter quindi
riusare la UI e la logica in presenza di hardware differenti
con cambiamenti minimali al codice
Plugin
Poter decidere come deployare il software, o come servizio
con UI disconnessa, o come eseguibile monolitico, oppure
in modalità UI-Unattended
Versatilità
Dialogare con un servizio o con la modalità UI-Unattended
da macchine remote previa connessione di rete.
Remote UI
6. Come si è proceduto
As-Is Hardware WCF Servizio Plugin
Si è proceduto prendendo un software minimale il cui scopo è
semplicemente ricevere dei codici letti da una serie di barcode scanner
industriali e scriverli su di una cartella
L’obiettivo era quello di creare una proof of concept che mostrasse i passi
necessari per rifatorizzare un progetto esistente dalla versione monolitica,
alla versione desiderata
Il risultato serve a dimostrare il processo necessario alla rifattorizzazione, sia
costituisce una reference implementation minimale su cui basare i successivi
software.
7. Lavorare con l’hardware
In molti casi è possibile identificare un
comportamento simile tra vari hardware, ad
esempio dei lettori di codici a barre o lettori
RFID sono in grado di essere interrogati per
ricevere una stringa.
Hardware
L’individuazione di una interfaccia IGenericCodeReader
serve quindi ad astrarre il comportamento di un
generico hardware appartenente ad una determinata
categoria.
Questo è il primo passo per poter essere indipendenti
dall’hardware
8. Si comincia con l’hardware
Quando si ha a che fare con hardware, non
esiste refactoring che non parta dal
permettere di utilizzare il software con dei
«simulatori» di hardware
Hardware
La necessità di operare e di effettuare test con
hardware connesso rende molto difficili le operazioni
di test e quindi ogni possibile refactoring.
La soluzione è astrarre l’hardware con una interfaccia
ed iniziare il lavoro con un simulatore
10. Comunicazione
Dato che il codice che contiene la «business
logic» dovrà essere eseguito in un servizio
la UI deve eseguire una comunicazione
Interprocesso
Hardware
In .NET la soluzione migliore è utilizzare una infrastruttura
WCF, il servizio esporrà quindi un host WCF che può essere
contattato da uno o più interfacce remote.
Tramite WCF si può connettere una interfaccia al servizio di
un altro computer, semplificando la manutenzione
11. WCF Discovery
WCF contiene una funzionalità interessante
chiamata Discovery
Servizio
Hardware UI Grazie al discovery, un applicativo può
cercare se nella rete è presente un Host wcf
che soddisfa una determinata interfaccia
Servizio Servizio
Il Discovery può semplificare la gestione delle interfacce
remote perché permette di presentare all’utente una lista di
host attivi, dove ogni host è una istanza del servizio in
esecuzione
13. Flessibilità di deploy
Nel primo scenario il software viene deployato
come «windows service», se necessario si
accede con una UI remota
Servizio UI
Nel secondo scenario si esegue il software con
una interfaccia minimale, usualmente con un
bottone Start/Stop e poco più
Minimal-UI UI
Nel terzo scenario il software viene eseguito in un singolo
tier, interfaccia di monitor e codice di business logic
vengono eseguiti nello stesso processo (come nella as-is)
All-in-on
La necessità di supportare questi tre scenari è richiesta per
aumentare la flessibilità e non «complicarsi la vita con i windows
service quando non serve»
16. Plugin
Spesso vi è la necessità di applicare logiche
simili a più hardware
Hardware Logic Gli hardware possono essere eguali o
eterogenei e condividere solo una certa
interfaccia (es. lettori di codici)
Hardware Hardware
Una business logic deve quindi poter
caricare «dinamicamente» i plugin che va
ad utilizzare
Questa struttura può essere implementata con poco
sforzo grazie a MEF, che si occupa del discovery e della
istanziazione dei plugin
17. MEF
Mef permette di gestire con facilità la
complessità di «individuare» e «caricare» i
Hardware Logic plugin a run-time
Grazie a MEF e poche righe di codice il
nostro progetto è in grado di scandire la
Hardware Hardware
cartella principale alla ricerca di plugin.
I concetti base sono Export ed Import, ovvero fornire e
consumare parti di software
18. Plugin
Per lasciare il tutto molto semplice si utilizzano solamente le
funzionalità base di MEF introducendo una Interfaccia
chiamata IGenericCodeReaderFactory
Tale interfaccia ha lo scopo di creare le reali istanze dei plugin.
Grazie a MEF verranno automaticamente caricate tutte le classi
concrete disponibili che implementano questa interfaccia
new
MEF
Factory A Plugin A
Hardware Plugin A
Software
new
Factory B Plugin B Plugin B
20. Testing
La creazione di plugin di Testing permette
di poter verificare la business logic e le
Hardware Logic logiche di interfaccia senza un hardware
reale.
Un plugin di test permette quindi di
Hardware Hardware
«simulare» i comportamenti dell’hardware
e verificarne le corrispettive risposte del
sistema
Grazie a questo è possibile non solo effettuare test
manuali, ma anche creare UnitTest ripetibili e senza
smell
È possibile sfruttare strumenti come i Coded-Ui-Test