Oggi scrivo qualche appunto relativo alle proprietà delle relazioni UML
Ogni relazione fra elementi UML, può avere le seguenti proprietà:
Cardinalità (o molteplicità)
Rappresenta il numero di oggetti minimo e massimo, che è possibile associare ad una classe.
La relazione può essere di tre tipi: uno a uno, uno a molti, o molti a molti. In un diagramma UML è indicata da un numero (1, 1..6, *) vicino alla fine del un segmento di congiunzione ad un elemento.
I possibili valori di molteplicità sono:
molti (*)
uno (1)
zero o più (0..*)
uno o più (1..*)
zero o uno (0..1)
all'interno di un range (2..4)
Guadando le cardinalità dell'esempio del post sulle relazioni UML (e ricordando che la regola è valida, per il momento temporale in cui viene descritta), abbiamo le seguenti cardinalità:
Un datore di lavoro può avere da un minimo di zero ad uno o più dipendenti (quando un datore di lavoro viene creato, non deve avere necessariamente un dipendente). La molteplicità persona, datore di lavoro invece non è segnata quindi la relazione viene detta indefinita. Una persona ha una sola posizione (e deve necessariamente averne una per il momento ed il contesto in cui si trova) e una entità posizione è ricoperta da una sola persona. Una posizione è creata ed è assegnata da un datore di lavoro e senza di lui non esisterebbe.
Navigabilità
Può essere unidirezionale (un oggetto fa riferimento ad un altro, ma non il contrario), oppure bidirezionale (un oggetto fa riferimento ad un altro e viceversa).
Quando una classe può "navigare" o aggiornare l'associazione vuol dire che ha responsabilità sulla stessa.
Una relazione unidirezionale, può avere anche una freccia invece del rombo, sul segmento di collegamento fra gli elementi.
Ecco un esempio di relazione di contenimento, unidirezionale:
In questo diagramma, un Libro è un contenitore di (puntatori a) pagine, ma anche le pagine hanno le loro relazioni di navigazione. Un lettore, (oppure un browser), che visualizzano una pagina alla volta, beneficia dei collegamenti alle pagine vicine e al sommario. Ogniuno di questi collegamenti è unidirezionale, e nella figura sopra ne possiamo vedere di tre tipi diversi.
Per la lista di pagine m_pagine non vi è nessuna relazione inversa raffigurata, quindi questa poterebbe rappresentare una relazione di contenimento unidirezionale, ma anche bidirezionale.
Se c'è bisogno che Pagina possa muoversi nell'oggetto Libro che la contiene, la direzionalità sul diagramma, dovrebbe essere mostrata, etichettando l'alta estremità del rapporto e/o aggiungendo un attributo m_libro alla classe Pagina.
Per adesso è tutto, se ci sono domande o altro scrivetemi pure un feedback.
Studiando UML, non potevo fare a meno di pubblicare qualcosa riguardo le basi.
Per questo motivo, parlerò delle relazioni, che sono il passo fondamentale da compiere ed apprendere per riuscire a convertire in codice, un pensiero astratto.
Quando abbiamo relazioni fra oggetti 1:1 (uno a uno) o 1: * (uno a molti), possiamo usare vari tipi di connessioni per descriverle.
Il seguente diagramma esprime una relazione uno a molti fra le entità coinvolte:
Nel contesto descritto dal diagramma si può desumere che ci possono essere più persone che lavorano per uno stesso datore di lavoro. Lo si vede dalla molteplicità specificata alla fine della relazione: 1 verso il datore di lavoro, * molti verso la persona. * significa 0 o molti (come nel caso di un esperssione regolare).
Dal punto di vista del datore di lavoro la figura seguente ci mostra 3 tipi di relazione:
Relazione di composizione (il rombo pieno) fra DatoreDiLavoro e Posizione. Questo indica che il datore di lavoro che è colui che ha in controllo delle posizioni e senza di lui, tali posizioni non esistono.
Relazione di aggregazione (il rombo vuoto) fra DatoreDiLavoro e il suo personale. Il DatoreDiLavoro controlla un gruppo di Persone durante l'orario di lavoro, ma dopo esse vivono anche senza di lui, hanno una vita propria ed indipendente.
La persona e la posizione ricoperta da essa hanno un associazione bi-direzionale. Questa associazione, nonspecifica niente al riguardo di come è stata implementata e da chi è controllata. E'possibile anche, che al momento attuale non esista una persona che lavora per un certo datore di lavoro. Questa relazione può essere verificata, chiamando un metodo (in sintassi C++) Posizione::dammiDatoreDiLavoro(); , che ritornaerà NULL. Anche se il diagramma indica una relazione 1:1 tra la persona e posizione, è possibile che una persona possa contenere più posizioni, oppure un datore di lavoro possa assumere molte persone con la stessa posizione. Per descrivere un sistema in grado di gestire tali casi, la cardinalità, parleremo di relazione molti-a-molti.
Sentire parlare di starterkit mi ricorda gli inizi della mia carriera lavorativa. quando giocavo con gli asp.net starterkit per creare i miei primi siti web interattivi.
Da qualche giorno c'è stato un restiling della sezione Google developers. Sotto la voce web, troviamo in beta un nuovo starter kit. Ma di cosa si tratta?
In poche parole, questo starterkit, è un punto di partenza per far vedere come sia possibile visualizzare web application compatibili su tutti i device, dagli smartphone alle tv, garantendo alte performance in termini di leggerezza, responsività e velocità di caricamento. Inoltre è possibile sincronizzare in realtime layout e dati su diversi device e tenere traccia delle metrice di performance, mobile e desktop.
Iniziamo
Lo starterkit è basato sui seguenti componenti:
NodeJs: Possiamo definirlo un framework che permette l'utilizzo server-side di Javascript. Npm: E' per Node cio che NuGet è per .Net, e cioè un package manager, che permette di produrre e consumare pacchetti di software (addin, frameworks, ecc..) Sass: Syntactically Awesome Style Sheets, un preprocessore CSS serve a definire fogli di stile con una forma più semplice, completa e potente rispetto ai CSS e a generare file CSS ottimizzati, aggregando le strutture definite anche in modo complesso.
Controlliamo che node sia installato correttamente, da terminal digitate:
node -v
Se non siete all’ultima versione potete aggiornare il tutto tramite Npm con i seguenti comandi:
sudo npm cache clean -f
sudo npm install -g n
sudo n stable
Setup del Google starterkit
Per prima cosa scaricare lo starterkit da qui: download
Decomprimete i file in una nuova cartella ed aggiungervi il componente Glup tramite Npm:
cd my-project
npm install #(mi raccomando è un processo lungo, abbiate pazienza...)
npm install gulp -g
Ora per fare una prova lanciamo il server locale tramite il comando
gulp serve #(si apre il browser Chrome, premte Ctrl-R per attivare reload automatico)
Installare Code
A questo punto abbiamo bisogno di un editor. Google ci consiglia Sublime, ma io ho optato per Microsoft Code perchè mi piace l'idea di vedere girare sotto Linux cose Microsoft e per imparare ad usarlo.
Scaricate Code al seguente indirizzo web: download
Se volete fare l’update, su windows è abilitato di defaut, su MAC lo includeranno ma non sarà automatico, su Linux non è previsto (anche se nel menu lo ho trovato ma non fa niente), quindi dobbiamo verificare ogni tanto e farlo da soli.
Su Linux mi raccomando di estrarre i file dallo zip, con il comando: unzip VSCode-linux-x64.zip -d /home/rudy/Develop/VSCode
se usate un gestore d’archivi grafico vi può dare errori strani.
Funzionalità
Per compilare il nostro progetto Code supporta Glup (che possiamo definire un compressore di html, javascript, css ed immagini. Unisce più file assieme e rimuove le parti superflue che non incidono sul normale funzionamento).
Connessione di device fisici
Per connettere i nostri device (nel mio caso Nexus 5 e Nexus 9) per prima cosa abilitiamo il debug USB (link ad abilitazione) e colleghiamoli al PC tramite USB.
Apriamo il browser al seguente URL: chrome://inspect
Ed abilitiamo il port forwarding.
Debug dei device in realtime
Ogni device ha il suo modo per eseguire il debug.
Con Android
utilizziamo i Chrome DevTools che possiamo impostare al seguente indirizzo: chrome://inspect per impostare il tuo device leggi qui: debug setup
Con Safari for iOS
Apri Safari su tuo device iOS.
Connettilo via USB.
Apri Safari sul tuo PC.
Nel menu di Safari’s menu vai su Develop e seleziona il nome del tuo dispositivo.
Seleziona quale tab vuoi debuggare.
Con IE Windows Phone
Al momento non esiste un supporto al debug nativo, ma si può emulare il browser mobile sul desktop con IE 11, vedi qui: win emulator
Debug Nexus 5 e Nexus 9 in realtime
Per prima cosa collego i 2 device alle porte USB del PC e vado all’indirizzo: chrome://inspect su Google Chrome
Otteniamo l’indirizzo ip del PC, nel caso Linux tramite riga di comando “ifconfig”, con windows “ipconfig”.
Sui device apriamo il browser Chrome all’indirizzo ip del PC ottenuto precedentemente e ci colleghiamo alla porta del server Gulp: x.y.z.n:3000 (Es.: 192.168.1.2:3000)
Dal PC all’indirizzo chrome://inspect, vediamo comparire i device collegati e a quale URL.
Editing con Code in realtime
A questo punto da linea di comando raggiungiamo la cartella dello starter kit ed apriamo Code con il comando: “code .”
Clicchiamo sul menu “File” ed abilitiamo il flag “Enable autosave”.
A questo punto possiamo modificare il codice sorgente del programma e vedere in realtime il cambiamento. Inoltre scrollando e navigando sui vari link, da uno device collegati al PC (o dal PC stesso), tutti gli altri lo seguiranno (questo è possibile tramite la funzionalità “browsersync”).
Mono 4.0 è la prima versione di Mono che contiene codice Microsoft .NET open source. In questa versione sono abilitate per default le nuove funzionalità del C# 6.0.
Queste sono le nuove funzionalità
Auto property initializers
Static members
String interpolation
Expression-bodied methods
Expression-bodied properties
Index initializers
Null-conditional operators
The nameof operator
Exception filters
Await in catch and finally
E questo un esempio di utilizzo (ho usato MonoDevelop 5.9)
using System;
using Newtonsoft.Json.Linq;
using System.Configuration;
//Con - Static members
using static System.Math;
namespace Azzan.Mono4Sample
{
public class Point
{
/*
//Prima di - Auto property initializers
public int X {get; private set;}
public int Y {get; private set;}
public Point()
{
X = 4;
Y = 9;
}
*/
//Con - Auto property initializers
public int X {get; } = 4;
public int Y {get; } = 9;
public Point(int x, int y) { X = x; Y = y; }
//Prima di Expression-bodied properties
/*
public double Dist
{
//Prima di - Static members
//get { return Math.Sqrt(X * X + Y * Y); }
//Con - Static members
get { return Sqrt(X * X + Y * Y); }
}
*/
//Con - Expression-bodied properties
public double Dist => Sqrt(X * X + Y * Y);
//Prima di - Expression-bodied methods
/*
public override string ToString()
{
//Prima di - String interpolation
//return string.Format("[Point: X={0}, Y={1}, Dist={2}]", X, Y, Dist);
//Con - String interpolation
return $"[Point: X={X}, Y={Y}, Dist={Dist}]";
}
*/
//Con - Expression-bodied methods
public override string ToString() => $"[Point: X={X}, Y={Y}, Dist={Dist}]";
//Prima di - Index initializers
/*
public JObject ToJson()
{
var result = new JObject();
result["x"] = X;
result["y"] = Y;
return result;
}
*/
//Con - Index initializers
public JObject ToJson() => new JObject() { ["x"] = X, ["y"] = Y };
//Prima di - Null-conditional operators
/*
public static Point FromJson(JObject json)
{
if(json != null &&
json["x"] != null &&
json["x"].Type == JTokenType.Integer &&
json["y"] != null &&
json["y"].Type == JTokenType.Integer)
{
return new Point((int)json["x"], (int)json["y"]);
}
return null;
}
*/
//Con - Null-conditional operators
public static Point FromJson(JObject json)
{
if(json?["x"]?.Type == JTokenType.Integer &&
json?["y"]?.Type == JTokenType.Integer)
{
return new Point((int)json["x"], (int)json["y"]);
}
return null;
}
public Point Add(Point point)
{
if(point == null)
{
//Prima di - The nameof operator
//throw new ArgumentNullException("point");
//Con - The nameof operator
throw new ArgumentNullException(nameof(point));
}
return point;
}
public void DoSomething()
{
//Prima di - Exception filters
try
{
} //Con - Exception filters
catch(ConfigurationException ex) //when (ex.IsSevere)
{
//Con - Await in catch and finally
//await LogAsync(ex);
}
finally
{
//Con - Await in catch and finally
//await CloseAsync();
}
}
}
}
Qui trovate i sorgenti dell'esempio creati con MonoDevelop 5.9: Download esempio
Purtroppo ho notato però che l'editor di MonoDevelop 5.9 ha ancora qualche problema nel riconoscere la sintassi C# 6.0 ma non sono cose gravi.
Invece gli "Exception filters" proprio non funzionano, se de-commentate il codice del mio esempio il compilatore vi da errore.
Che versione di Mono è installata?
Questo è un comando che potete lanciare tramite shell Linux, per vedere i dettagli della versione che avete installato:
Oggi mi è arrivato l'orologio di LG con Android Wear. Per l'occasione e perché ne avrò bisogno ecco la lista dei comandi Google Now che ho trovato qua e la su internet:
Inizia nuova telefonata
chiama [nome persona] [cognome] [tipo: cellulare, lavoro, casa, ecc..]
Eccomi alla prima parte della rubrica dedicata al confronto fra C# e Qt.
In C# quando vogliamo mettere in pausa il thread corrente in cui ci troviamo per tot millisecondi usiamo la funzione statica: Thread.Sleep([numero di millisecondi]).
In Qt invece ci sono almeno 3 possibilità diverse:
//METODO 1:
//Usare la classe QTest
QTest::qSleep(100); // blocca l' event processing
QTest::qWait(100); // non blocca l' event processing
//METODO 2:
//Usare QWaitCondition / QMutex
QWaitCondition waitCondition;
QMutex mutex;
waitCondition.wait(&mutex, 100);
//METODO 3:
//Oppure fare derivare la nostra classe da QThread.
class Thread : public QThread
{
public:
static void msleep(int ms)
{
QThread::msleep(ms);
}
};
Thread::msleep(100);
Se per caso vi dovesse capitare con Visual Studio 2012 di ricevere il messaggio: The operation cannot be completed. “Puntatore non valido”, quando state tentando di visualizzare un file di risorse .resx, per ripristinarlo, vi basta aprire il file incriminato con un editor di testo e rimuovere tutti gli elementi “data”, dell’xml che contengono l’attributo type="System.Resources.ResXNullRef, System.Windows.Forms".
Es. va eliminato: