Case study per app multipiattaforma: Attività

TaskyPortable è una semplice applicazione elenco attività. Questo documento illustra come è stato progettato e compilato, seguendo le indicazioni del documento Building Cross-Platform Applications (Compilazione di applicazioni multipiattaforma). La discussione riguarda le aree seguenti:

Processo di progettazione

Prima di iniziare a scrivere codice, è consigliabile creare una roadmap per ottenere ciò che si vuole ottenere. Ciò vale soprattutto per lo sviluppo multipiattaforma, in cui si creano funzionalità che verranno esposte in diversi modi. A partire da un'idea chiara di ciò che si sta creando consente di risparmiare tempo e impegno più avanti nel ciclo di sviluppo.

Requisiti

Il primo passaggio nella progettazione di un'applicazione consiste nell'identificare le funzionalità desiderate. Questi possono essere obiettivi di alto livello o casi d'uso dettagliati. Tasky ha requisiti funzionali semplici:

  • Visualizzare un elenco di attività
  • Aggiungere, modificare ed eliminare attività
  • Impostare lo stato di un'attività su 'done'

È consigliabile prendere in considerazione l'uso di funzionalità specifiche della piattaforma. Tasky può sfruttare i vantaggi del recinto virtuale iOS o dei riquadri animati di Windows Telefono? Anche se non si usano funzionalità specifiche della piattaforma nella prima versione, è consigliabile pianificare in anticipo per assicurarsi che i livelli di dati e aziendali possano supportarli.

Progettazione dell'interfaccia utente

Iniziare con una progettazione di alto livello che può essere implementata tra le piattaforme di destinazione. Prestare attenzione a prendere nota dei vincoli dell'interfaccia utente specifica della piattaforma. Ad esempio, un TabBarController in iOS può visualizzare più di cinque pulsanti, mentre Windows Telefono equivalente può visualizzare fino a quattro. Disegnare il flusso dello schermo usando lo strumento preferito (carta funziona).

Draw the screen-flow using the tool of your choice paper works

Modello di dati

Conoscere i dati da archiviare consentirà di determinare quale meccanismo di persistenza usare. Vedere Accesso ai dati multipiattaforma per informazioni sui meccanismi di archiviazione disponibili e su come decidere tra di essi. Per questo progetto verrà usato SQLite.NET.

Tasky deve archiviare tre proprietà per ogni 'TaskItem':

  • Name – String
  • Note - Stringa
  • Operazione completata - Valore booleano

Funzionalità principali

Si consideri l'API che l'interfaccia utente dovrà usare per soddisfare i requisiti. Un elenco attività richiede le funzioni seguenti:

  • Elencare tutte le attività : per visualizzare l'elenco della schermata principale di tutte le attività disponibili
  • Ottenere un'attività : quando viene toccata una riga di attività
  • Salva un'attività : quando un'attività viene modificata
  • Elimina un'attività : quando un'attività viene eliminata
  • Creare un'attività vuota: quando viene creata una nuova attività

Per ottenere il riutilizzo del codice, questa API deve essere implementata una sola volta nella libreria di classi portabile.

Implementazione

Dopo aver concordato la progettazione dell'applicazione, valutare come può essere implementata come applicazione multipiattaforma. Questo diventerà l'architettura dell'applicazione. Seguendo le indicazioni contenute nel documento Compilazione di applicazioni multipiattaforma, il codice dell'applicazione deve essere suddiviso nelle parti seguenti:

  • Codice comune: un progetto comune che contiene codice riabilitabile per archiviare i dati dell'attività, esporre una classe Model e un'API per gestire il salvataggio e il caricamento dei dati.
  • Codice specifico della piattaforma: progetti specifici della piattaforma che implementano un'interfaccia utente nativa per ogni sistema operativo, usando il codice comune come "back-end".

Platform-specific projects implement a native UI for each operating system, utilizing the common code as the back end

Queste due parti sono descritte nelle sezioni seguenti.

Codice comune (PCL)

Tasky Portable usa la strategia della libreria di classi portabile per la condivisione di codice comune. Per una descrizione delle opzioni di condivisione del codice, vedere il documento Opzioni del codice di condivisione.

Tutto il codice comune, incluso il livello di accesso ai dati, il codice e i contratti del database, viene inserito nel progetto di libreria.

Il progetto PCL completo è illustrato di seguito. Tutto il codice nella libreria portabile è compatibile con ogni piattaforma di destinazione. Quando viene distribuita, ogni app nativa farà riferimento a tale libreria.

When deployed, each native app will reference that library

Il diagramma classi seguente mostra le classi raggruppate per livello. La SQLiteConnection classe è il codice boilerplate del pacchetto Sqlite-NET. Le altre classi sono codice personalizzato per Tasky. Le TaskItemManager classi e TaskItem rappresentano l'API esposta alle applicazioni specifiche della piattaforma.

The TaskItemManager and TaskItem classes represent the API that is exposed to the platform-specific applications

L'uso di spazi dei nomi per separare i livelli consente di gestire i riferimenti tra ogni livello. I progetti specifici della piattaforma devono includere solo un'istruzione using per il livello business. Il livello di accesso ai dati e il livello dati devono essere incapsulati dall'API esposta da TaskItemManager nel livello business.

Riferimenti

Le librerie di classi portabili devono essere utilizzabili in più piattaforme, ognuna con diversi livelli di supporto per le funzionalità della piattaforma e del framework. Per questo motivo, esistono limitazioni per cui è possibile usare pacchetti e librerie framework. Ad esempio, Xamarin.iOS non supporta la parola chiave c# dynamic , quindi una libreria di classi portabile non può usare alcun pacchetto che dipende da codice dinamico, anche se tale codice funzionerebbe in Android. Visual Studio per Mac impedirà di aggiungere pacchetti e riferimenti incompatibili, ma è consigliabile tenere presenti limitazioni per evitare sorprese in un secondo momento.

Nota: si noterà che i progetti fanno riferimento alle librerie del framework non usate. Questi riferimenti sono inclusi come parte dei modelli di progetto Xamarin. Quando le app vengono compilate, il processo di collegamento rimuoverà il codice senza riferimenti, quindi, anche se System.Xml è stato fatto riferimento, non verrà incluso nell'applicazione finale perché non si usano funzioni Xml.

Livello dati (DL)

Il livello dati contiene il codice che esegue l'archiviazione fisica dei dati, indipendentemente dal fatto che si tratti di un database, di file flat o di un altro meccanismo. Il livello dati Tasky è costituito da due parti: la libreria SQLite-NET e il codice personalizzato aggiunto per collegarlo.

Tasky si basa sul pacchetto NuGet Sqlite-net (pubblicato da Frank Krueger) per incorporare il codice SQLite-NET che fornisce un'interfaccia di database ORM (Object-Relational Mapping). La TaskItemDatabase classe eredita da SQLiteConnection e aggiunge i metodi Create, Read, Update, Delete (CRUD) necessari per leggere e scrivere dati in SQLite. Si tratta di una semplice implementazione boilerplate di metodi CRUD generici che potrebbero essere riutilizzati in altri progetti.

TaskItemDatabase è un singleton, assicurando che tutti gli accessi si verifichino sulla stessa istanza. Viene usato un blocco per impedire l'accesso simultaneo da più thread.

SQLite in Windows Telefono

Anche se iOS e Android vengono entrambi forniti con SQLite come parte del sistema operativo, Windows Telefono non include un motore di database compatibile. Per condividere il codice in tutte e tre le piattaforme è necessaria una versione nativa di Windows Phone di SQLite. Per altre informazioni sulla configurazione del progetto di Windows Telefono per Sqlite, vedere Uso di un database locale.

Uso di un'interfaccia per generalizzare l'accesso ai dati

Il livello dati assume una dipendenza da BL.Contracts.IBusinessIdentity in modo da poter implementare metodi di accesso ai dati astratti che richiedono una chiave primaria. Qualsiasi classe business layer che implementa l'interfaccia può quindi essere resa persistente nel livello dati.

L'interfaccia specifica semplicemente una proprietà integer da usare come chiave primaria:

public interface IBusinessEntity {
    int ID { get; set; }
}

La classe base implementa l'interfaccia e aggiunge gli attributi SQLite-NET per contrassegnarlo come chiave primaria con incremento automatico. Qualsiasi classe nel livello Business che implementa questa classe di base può quindi essere mantenuta nel livello dati:

public abstract class BusinessEntityBase : IBusinessEntity {
    public BusinessEntityBase () {}
    [PrimaryKey, AutoIncrement]
    public int ID { get; set; }
}

Un esempio dei metodi generici nel livello dati che usano l'interfaccia è questo GetItem<T> metodo:

public T GetItem<T> (int id) where T : BL.Contracts.IBusinessEntity, new ()
{
    lock (locker) {
        return Table<T>().FirstOrDefault(x => x.ID == id);
    }
}

Blocco per impedire l'accesso simultaneo

Un blocco viene implementato all'interno della TaskItemDatabase classe per impedire l'accesso simultaneo al database. Ciò consente di garantire la serializzazione dell'accesso simultaneo da thread diversi. In caso contrario, un componente dell'interfaccia utente potrebbe tentare di leggere il database contemporaneamente a un thread in background che lo sta aggiornando. Di seguito è riportato un esempio di come viene implementato il blocco:

static object locker = new object ();
public IEnumerable<T> GetItems<T> () where T : BL.Contracts.IBusinessEntity, new ()
{
    lock (locker) {
        return (from i in Table<T> () select i).ToList ();
    }
}
public T GetItem<T> (int id) where T : BL.Contracts.IBusinessEntity, new ()
{
    lock (locker) {
        return Table<T>().FirstOrDefault(x => x.ID == id);
    }
}

La maggior parte del codice livello dati può essere riutilizzata in altri progetti. L'unico codice specifico dell'applicazione nel livello è la CreateTable<TaskItem> chiamata nel TaskItemDatabase costruttore.

Livello di accesso ai dati (DAL)

La TaskItemRepository classe incapsula il meccanismo di archiviazione dei dati con un'API fortemente tipizzata che consente di TaskItem creare, eliminare, recuperare e aggiornare gli oggetti.

Uso della compilazione condizionale

La classe usa la compilazione condizionale per impostare il percorso del file. Questo è un esempio di implementazione della divergenza della piattaforma. Proprietà che restituisce il percorso compilato in codice diverso in ogni piattaforma. Le direttive del compilatore specifiche della piattaforma e del codice sono illustrate di seguito:

public static string DatabaseFilePath {
    get {
        var sqliteFilename = "TaskDB.db3";
#if SILVERLIGHT
        // Windows Phone expects a local path, not absolute
        var path = sqliteFilename;
#else
#if __ANDROID__
        // Just use whatever directory SpecialFolder.Personal returns
        string libraryPath = Environment.GetFolderPath(Environment.SpecialFolder.Personal); ;
#else
        // we need to put in /Library/ on iOS5.1+ to meet Apple's iCloud terms
        // (they don't want non-user-generated data in Documents)
        string documentsPath = Environment.GetFolderPath (Environment.SpecialFolder.Personal); // Documents folder
        string libraryPath = Path.Combine (documentsPath, "..", "Library"); // Library folder
#endif
        var path = Path.Combine (libraryPath, sqliteFilename);
                #endif
                return path;
    }
}

A seconda della piattaforma, l'output sarà "<percorso> app/Library/TaskDB.db3" per iOS, "<percorso> app/Documents/TaskDB.db3" per Android o semplicemente "TaskDB.db3" per Windows Telefono.

Livello business (BL)

Il livello business implementa le classi Model e una facciata per gestirle. In Tasky il modello è la TaskItem classe e TaskItemManager implementa il modello facciata per fornire un'API per la gestione di TaskItems.

Facciata

TaskItemManager esegue il wrapping di DAL.TaskItemRepository per fornire i metodi Get, Save e Delete a cui farà riferimento i livelli dell'applicazione e dell'interfaccia utente.

Le regole di business e la logica verranno posizionate qui se necessario, ad esempio tutte le regole di convalida che devono essere soddisfatte prima del salvataggio di un oggetto.

API per codice specifico della piattaforma

Dopo aver scritto il codice comune, l'interfaccia utente deve essere compilata per raccogliere e visualizzare i dati esposti. La TaskItemManager classe implementa il modello facciata per fornire un'API semplice per l'accesso al codice dell'applicazione.

Il codice scritto in ogni progetto specifico della piattaforma sarà in genere strettamente associato all'SDK nativo di tale dispositivo e accederà solo al codice comune usando l'API definita da TaskItemManager. Sono inclusi i metodi e le classi di business esposti, ad esempio TaskItem.

Le immagini non vengono condivise tra piattaforme, ma aggiunte in modo indipendente a ogni progetto. Questo è importante perché ogni piattaforma gestisce le immagini in modo diverso, usando nomi di file, directory e risoluzioni diversi.

Le sezioni rimanenti illustrano i dettagli di implementazione specifici della piattaforma dell'interfaccia utente tasky.

App iOS

Esistono solo alcune classi necessarie per implementare l'applicazione tasky iOS usando il progetto PCL comune per archiviare e recuperare i dati. Il progetto IOS Xamarin.iOS completo è illustrato di seguito:

iOS project is shown here

Le classi sono visualizzate in questo diagramma, raggruppate in livelli.

The classes are shown in this diagram, grouped into layers

Riferimenti

L'app iOS fa riferimento alle librerie SDK specifiche della piattaforma, ad esempio Xamarin.iOS e MonoTouch.Dialog-1.

Deve anche fare riferimento al TaskyPortableLibrary progetto PCL. L'elenco dei riferimenti è illustrato di seguito:

The references list is shown here

Il livello applicazione e il livello dell'interfaccia utente vengono implementati in questo progetto usando questi riferimenti.

Livello applicazione (AL)

Il livello applicazione contiene classi specifiche della piattaforma necessarie per "associare" gli oggetti esposti dalla libreria di classi portabile all'interfaccia utente. L'applicazione specifica di iOS include due classi che consentono di visualizzare le attività:

  • EditingSource : questa classe viene usata per associare elenchi di attività all'interfaccia utente. Poiché MonoTouch.Dialog è stato usato per l'elenco Attività, è necessario implementare questo helper per abilitare la funzionalità swipe-to-delete in UITableView . Swipe-to-delete è comune in iOS, ma non Android o Windows Telefono, quindi il progetto specifico di iOS è l'unico che lo implementa.
  • TaskDialog : questa classe viene usata per associare una singola attività all'interfaccia utente. Usa l'API Reflection per eseguire il MonoTouch.Dialog wrapping dell'oggetto TaskItem con una classe che contiene gli attributi corretti per consentire la formattazione corretta della schermata di input.

La TaskDialog classe usa MonoTouch.Dialog gli attributi per creare una schermata in base alle proprietà di una classe. La classe ha questo aspetto:

public class TaskDialog {
    public TaskDialog (TaskItem task)
    {
        Name = task.Name;
        Notes = task.Notes;
        Done = task.Done;
    }
    [Entry("task name")]
    public string Name { get; set; }
    [Entry("other task info")]
    public string Notes { get; set; }
    [Entry("Done")]
    public bool Done { get; set; }
    [Section ("")]
    [OnTap ("SaveTask")]    // method in HomeScreen
    [Alignment (UITextAlignment.Center)]
    public string Save;
    [Section ("")]
    [OnTap ("DeleteTask")]  // method in HomeScreen
    [Alignment (UITextAlignment.Center)]
    public string Delete;
}

Si noti che gli OnTap attributi richiedono un nome di metodo: questi metodi devono esistere nella classe in cui viene creato l'oggetto MonoTouch.Dialog.BindingContext ( in questo caso, la HomeScreen classe descritta nella sezione successiva).

Livello interfaccia utente

Il livello interfaccia utente è costituito dalle classi seguenti:

  1. AppDelegate : contiene chiamate all'API Aspetto per applicare stili ai tipi di carattere e ai colori usati nell'applicazione. Tasky è una semplice applicazione in modo che non siano in esecuzione altre attività di inizializzazione in FinishedLaunching .
  2. Schermate : sottoclassi di UIViewController che definiscono ogni schermata e il relativo comportamento. Le schermate associano l'interfaccia utente alle classi del livello applicazione e all'API comune ( TaskItemManager ). In questo esempio le schermate vengono create nel codice, ma potrebbero essere state progettate usando Interface Builder di Xcode o la finestra di progettazione dello storyboard.
  3. Immagini: gli elementi visivi sono una parte importante di ogni applicazione. Tasky include immagini di schermata iniziale e icone, che per iOS devono essere fornite in risoluzione normale e Retina.

Schermata Home

La schermata iniziale è una MonoTouch.Dialog schermata che visualizza un elenco di attività dal database SQLite. Eredita da DialogViewController e implementa il codice per impostare l'oggetto Root in modo che contenga una raccolta di TaskItem oggetti per la visualizzazione.

It inherits from DialogViewController and implements code to set the Root to contain a collection of TaskItem objects for display

I due metodi principali correlati alla visualizzazione e all'interazione con l'elenco di attività sono:

  1. PopulateTable : usa il metodo del TaskManager.GetTasks livello business per recuperare una raccolta di TaskItem oggetti da visualizzare.
  2. Selezionata : quando viene toccata una riga, visualizza l'attività in una nuova schermata.

Schermata Dettagli attività

Dettagli attività è una schermata di input che consente di modificare o eliminare le attività.

L'attività usa MonoTouch.Dialogl'API Reflection per visualizzare la schermata, quindi non esiste alcuna UIViewController implementazione. Al contrario, la HomeScreen classe crea un'istanza e visualizza un DialogViewController oggetto usando la TaskDialog classe dal livello applicazione.

Questo screenshot mostra una schermata vuota che illustra l'impostazione dell'attributo Entry del testo della filigrana nei campi Nome e Note :

This screenshot shows an empty screen that demonstrates the Entry attribute setting the watermark text in the Name and Notes fields

La funzionalità della schermata Dettagli attività ,ad esempio il salvataggio o l'eliminazione di un'attività, deve essere implementata nella classe , perché è la posizione in HomeScreen cui viene creato .MonoTouch.Dialog.BindingContext I metodi seguenti HomeScreen supportano la schermata Dettagli attività:

  1. ShowTaskDetails : crea un oggetto MonoTouch.Dialog.BindingContext per il rendering di una schermata. Crea la schermata di input usando la reflection per recuperare i nomi e i tipi delle proprietà dalla TaskDialog classe . Informazioni aggiuntive, ad esempio il testo della filigrana per le caselle di input, vengono implementate con attributi nelle proprietà.
  2. SaveTask : questo metodo viene fatto riferimento alla TaskDialog classe tramite un OnTap attributo . Viene chiamato quando viene premuto Save e usa un MonoTouch.Dialog.BindingContext oggetto per recuperare i dati immessi dall'utente prima di salvare le modifiche usando TaskItemManager .
  3. DeleteTask : si fa riferimento a questo metodo nella TaskDialog classe tramite un OnTap attributo . TaskItemManager Usa per eliminare i dati usando la chiave primaria (proprietà ID).

App Android

Il progetto Xamarin.Android completo è illustrato di seguito:

Android project is pictured here

Diagramma classi, con classi raggruppate per livello:

The class diagram, with classes grouped by layer

Riferimenti

Il progetto di app Android deve fare riferimento all'assembly Xamarin.Android specifico della piattaforma per accedere alle classi da Android SDK.

Deve anche fare riferimento al progetto PCL (ad esempio. TaskyPortableLibrary) per accedere ai dati comuni e al codice del livello business.

TaskyPortableLibrary to access the common data and business layer code

Livello applicazione (AL)

Analogamente alla versione di iOS esaminata in precedenza, il livello applicazione nella versione Android contiene classi specifiche della piattaforma necessarie per "associare" gli oggetti esposti dal core all'interfaccia utente.

TaskListAdapter : per visualizzare un elenco<T> di oggetti è necessario implementare un adattatore per visualizzare oggetti personalizzati in un oggetto ListView. L'adattatore controlla il layout usato per ogni elemento dell'elenco, in questo caso il codice usa un layout SimpleListItemCheckedpredefinito Android.

Interfaccia utente

Il livello dell'interfaccia utente dell'app Android è una combinazione di codice e markup XML.

  • Risorse/Layout : layout dello schermo e progettazione delle celle di riga implementati come file AXML. L'oggetto AXML può essere scritto manualmente o disposto visivamente usando la finestra di progettazione dell'interfaccia utente di Xamarin per Android.
  • Risorse/Disegnabili : immagini (icone) e pulsante personalizzato.
  • Schermate : sottoclassi di attività che definiscono ogni schermata e il relativo comportamento. Collega l'interfaccia utente con le classi del livello applicazione e l'API comune (TaskItemManager).

Schermata Home

La schermata iniziale è costituita da una sottoclasse HomeScreen Activity e dal HomeScreen.axml file che definisce il layout (posizione del pulsante e dell'elenco di attività). La schermata è simile alla seguente:

The screen looks like this

Il codice della schermata iniziale definisce i gestori per fare clic sul pulsante e fare clic sugli elementi nell'elenco, nonché popolare l'elenco nel OnResume metodo (in modo che rifletta le modifiche apportate nella schermata Dettagli attività). I dati vengono caricati usando il livello TaskItemManager business e dal TaskListAdapter livello applicazione.

Schermata Dettagli attività

La schermata Dettagli attività è costituita anche da una sottoclasse Activity e da un file di layout AXML. Il layout determina la posizione dei controlli di input e la classe C# definisce il comportamento per caricare e salvare TaskItem gli oggetti.

The class defines the behavior to load and save TaskItem objects

Tutti i riferimenti alla libreria PCL sono tramite la TaskItemManager classe .

App di Windows Telefono

Il progetto di Windows Telefono completo:

Windows Phone App The complete Windows Phone project

Il diagramma seguente presenta le classi raggruppate in livelli:

This diagram presents the classes grouped into layers

Riferimenti

Il progetto specifico della piattaforma deve fare riferimento alle librerie specifiche della piattaforma necessarie (ad esempio Microsoft.Phone e System.Windows) per creare un'applicazione di Windows Telefono valida.

Deve inoltre fare riferimento al progetto PCL (ad esempio TaskyPortableLibrary) per utilizzare la classe e il TaskItem database.

TaskyPortableLibrary to utilize the TaskItem class and database

Livello applicazione (AL)

Anche in questo caso, come con le versioni di iOS e Android, il livello applicazione è costituito dagli elementi non visivi che consentono di associare i dati all'interfaccia utente.

ViewModel

ViewModel esegue il wrapping dei dati dal PCL ( TaskItemManager) e lo presenta in modo che possa essere utilizzato dal data binding Silverlight/XAML. Questo è un esempio di comportamento specifico della piattaforma (come illustrato nel documento Applicazioni multipiattaforma).

Interfaccia utente

XAML ha una funzionalità univoca di data binding che può essere dichiarata nel markup e ridurre la quantità di codice necessaria per visualizzare gli oggetti:

  1. Pages : i file XAML e il relativo codebehind definiscono l'interfaccia utente e fanno riferimento a ViewModels e al progetto PCL per visualizzare e raccogliere dati.
  2. Immagini : schermata iniziale, immagini di sfondo e icona sono una parte fondamentale dell'interfaccia utente.

MainPage

La classe MainPage usa per TaskListViewModel visualizzare i dati usando le funzionalità di data binding XAML. La pagina è impostata sul modello di DataContext visualizzazione, popolato in modo asincrono. La {Binding} sintassi in XAML determina la modalità di visualizzazione dei dati.

TaskDetailsPage

Ogni attività viene visualizzata associando a TaskViewModel XAML definito in TaskDetailsPage.xaml. I dati dell'attività TaskItemManager vengono recuperati tramite nel livello Business.

Risultati

Le applicazioni risultanti hanno un aspetto simile al seguente in ogni piattaforma:

iOS

L'applicazione usa la progettazione dell'interfaccia utente standard di iOS, ad esempio il pulsante 'add' posizionato nella barra di spostamento e l'icona del segno più (+) predefinita. Usa anche il comportamento predefinito UINavigationController del pulsante "Indietro" e supporta "swipe-to-delete" nella tabella.

It also uses the default UINavigationController back button behavior and supports swipe-to-delete in the tableIt also uses the default UINavigationController back button behavior and supports swipe-to-delete in the table

Android

L'app Android usa controlli predefiniti, incluso il layout predefinito per le righe che richiedono un segno di graduazione visualizzato. Il comportamento di back hardware/system è supportato oltre a un pulsante Indietro sullo schermo.

The hardware/system back behavior is supported in addition to an on-screen back buttonThe hardware/system back behavior is supported in addition to an on-screen back button

Windows Phone

L'app di Windows Telefono usa il layout standard, popolando la barra dell'app nella parte inferiore dello schermo anziché una barra di spostamento nella parte superiore.

The Windows Phone app uses the standard layout, populating the app bar at the bottom of the screen instead of a nav bar at the topThe Windows Phone app uses the standard layout, populating the app bar at the bottom of the screen instead of a nav bar at the top

Riepilogo

Questo documento ha fornito una spiegazione dettagliata del modo in cui i principi della progettazione di applicazioni a più livelli sono stati applicati a una semplice applicazione per facilitare il riutilizzo del codice in tre piattaforme mobili: iOS, Android e Windows Telefono.

Ha descritto il processo usato per progettare i livelli dell'applicazione e ha illustrato il codice e le funzionalità implementate in ogni livello.

Il codice può essere scaricato da GitHub.