Torna indietro   Hardware Upgrade Forum > Software > Programmazione

OPPO Watch X2 Mini, lo smartwatch compatto a cui non manca nulla
OPPO Watch X2 Mini, lo smartwatch compatto a cui non manca nulla
OPPO Watch X2 Mini è uno smartwatch compatto capace di offrire un'esperienza completa di monitoraggio della salute e fitness con una cassa da 43 mm che può adattarsi a qualsiasi tipo di polso, dal più grande al - soprattutto - più piccolo. Con l'architettura dual-chip e un'autonomia che può coprire due giorni con tranquillità, rappresenta la soluzione ideale per chi cerca prestazioni premium in un formato ridotto.
Xiaomi 15T Pro, è lui il nuovo best buy? La recensione
Xiaomi 15T Pro, è lui il nuovo best buy? La recensione
Dopo il recente lancio della serie Xiaomi 15T di Monaco, vi parliamo oggi della versione più performante della nuova famiglia, ovvero Xiaomi 15 T Pro. Vi raccontiamo la nostra prova nel dettaglio, spiegando perché a questo prezzo e in questa fascia, questo smartphone ha davvero senso tenerlo in seria considerazione.
Acer TravelMate P6 14 AI: il Copilot+ PC sotto il chilo per il professionista in movimento
Acer TravelMate P6 14 AI: il Copilot+ PC sotto il chilo per il professionista in movimento
Acer ha ampliato la sua offerta professionale con il TravelMate P6 14 AI, un notebook ultraleggero e robusto pensato per chi lavora in mobilità. Certificato Copilot+ PC, combina design premium, autonomia elevata e piattaforma Intel Core Ultra Serie 2 con funzionalità AI, garantendo sicurezza, affidabilità e produttività per l'utenza business moderna.
Tutti gli articoli Tutte le news

Vai al Forum
Rispondi
 
Strumenti
Old 14-05-2010, 11:39   #1
e-commerce84
Senior Member
 
Iscritto dal: Feb 2009
Messaggi: 700
[Programmazione OO\Java] Chiarimenti su pattern creazionali Factory

Ciao,
stò studiando i pattern ed avrei qualche dubbio che spero mi possiate chiarire.
Attualmente stò vedendo i pattern creazionali ed in particolar modo i Factory.

Faccio riferimento a questa slide: http://www.informatica.uniroma2.it/u...tern%20GOF.pdf

Praticamente da quello che ho capito una factory è una speciale classe introdotta arbitrariamente (pure fabrication dei pattern GRASP) che ha la responsabilità di creare i miei oggetti e scelgo di introdurre questa nuova classe per fare creazioni complesse in oggetti coesi (per garantire high coesion e low coupling di fatto).

Vabbè ci sono vari tipi di Factory...per quanto riguarda la abstract factory tutto ok...

Mi stò impicciando non poco a capire cosa faccia invece la Lazy Factory...che praticamente dovrebbe usare la combinazione di un factory method e del memorizzare l'istanza creata su una mappa solo la prima volta e di poter riprendere la stessa istanza la volta successiva che si richede la stessa con certi parametri...fà questo esempio

Codice:
import java.util.*;

public class Fruit {
	
	/* Crea una HashMap comune a tutte le istanze della classe Fruit */
	private static Map types = new HashMap();
	
	private string type;
	
	private Fruit(String type){		// COSTRUTTORE
		this.type = type;			// Assegna il parametro locale type
		types.put(type, this);		// Che fà esattamente ?!?!
	}
	
	/* Metodo statico comune a tutta la classe che dato un parametro type ritorna un 
	 * oggetto di tipo Fruit */
	public static Fruit getFruit(String type){
		Fruit f;
		
		if(types.containskey(type)){	// Se nella hashmap c'è il valore type
			f = (fruit) types.get(type);	// Mette quell'oggetto in f
		}
		else{
			f = new Fruit(type);		// Altrimenti lo crea con quel valore
		}
		
		return f;						// Ritorna il riferimento ad f
	}
	
}
Praticamente che fà? crea gli oggetti salvandoli di volta in volta nella hashmap e poi quando cerco un oggetto con certe specifici valori della variabile di istanza controlla se è presente nella hashmap?

A che mi serve esattamente un pattern del genere? quand'è che si usa all'atto pratico?

Alla riga types.put(type, this); fà l'inserimento nella hashmpa, praticamente gli stà dicendo di inserire lo specifico oggetto (this) relativo a quel valore type? Sapete darmi qualche info sulle hashmap? mai viste da praticamente nessun'altra parte :-/

Grazie
e-commerce84 è offline   Rispondi citando il messaggio o parte di esso
Old 14-05-2010, 11:48   #2
nuovoUtente86
Senior Member
 
Iscritto dal: Mar 2007
Messaggi: 7863
L' inizializzazione lazy, tenta di ritardare la costruzione di un oggetto nel momento effettivo in cui occorre. Oltre a cio, nel tuo esempio, viene creata una mappa di singletono, in modo da ridurre l' utilizzo di memoria.
nuovoUtente86 è offline   Rispondi citando il messaggio o parte di esso
Old 14-05-2010, 12:03   #3
banryu79
Senior Member
 
L'Avatar di banryu79
 
Iscritto dal: Oct 2007
Città: Padova
Messaggi: 4131
Risposta parziale (i design pattern non sono il mio forte)

Quote:
Originariamente inviato da e-commerce84 Guarda i messaggi
Praticamente che fà? crea gli oggetti salvandoli di volta in volta nella hashmap e poi quando cerco un oggetto con certe specifici valori della variabile di istanza controlla se è presente nella hashmap?
Sì, esatto.
Quando un certo 'type' viene richiesto tramite 'getFruit', viene restituita l'istanza creata e memorizzata nella mappa. Se quell'istanza nella mappa non c'è, la si crea.

Quindi per ogni 'type' richiesto esiste solo una istanza che viene condivisa.
Tenendo in conto questo fatto, e visto il contesto (parlavi di factory patterns) mi viene in mente che questo sistema possa servire per istanziare una sola volta una specifica factory concreta.

Quote:
Originariamente inviato da e-commerce84 Guarda i messaggi
Alla riga types.put(type, this); fà l'inserimento nella hashmpa, praticamente gli stà dicendo di inserire lo specifico oggetto (this) relativo a quel valore type? Sapete darmi qualche info sulle hashmap? mai viste da praticamente nessun'altra parte :-/
HashMap è una implementazione dell'interfaccia Map, package java.util.
Fa parte del "Collections Framework" distribuito con il JDK standard.
Una Map è l'interfaccia ad un oggetto che mappa chiavi con valori.

Nel codice che hai postato non vengono usati i Generics, quindi non viene dichiarto il tipo esplicito che la mappa usa per la chiave (Key) e per il valore (Value) ma esaminando la chiamata a 'put' si vede che il primo argomento (key) è di tipo String e il secondo argomento (value) di tipo Fruit.

L'interfaccia Map fornisce tre "viste" che permettono di esaminare il contenuto di una Map come:
- un set delle chiavi contenute;
- una collezione dei valori contenuti;
- un set di coppie chiave-valore.

L'ordine della Map è definito dall'ordine con cui gli iteratori delle tre viste della mappa iterano gli elementi.
Alcune implementazioni (come TreeMap) grantiscono un certo ordine, altre (come appunto HashMap) no.

Si raccomanda fortemente l'uso di oggetti immutabili come chiavi di una Map (String per l'appunto è immutabile).

Comunque qui trovi un trail se vuoi approfondire: Java Collection Framework
__________________

As long as you are basically literate in programming, you should be able to express any logical relationship you understand.
If you don’t understand a logical relationship, you can use the attempt to program it as a means to learn about it.
(Chris Crawford)
banryu79 è offline   Rispondi citando il messaggio o parte di esso
Old 14-05-2010, 12:16   #4
e-commerce84
Senior Member
 
Iscritto dal: Feb 2009
Messaggi: 700
Quote:
Originariamente inviato da banryu79 Guarda i messaggi
Risposta parziale (i design pattern non sono il mio forte)


Sì, esatto.
Quando un certo 'type' viene richiesto tramite 'getFruit', viene restituita l'istanza creata e memorizzata nella mappa. Se quell'istanza nella mappa non c'è, la si crea.

Quindi per ogni 'type' richiesto esiste solo una istanza che viene condivisa.
Tenendo in conto questo fatto, e visto il contesto (parlavi di factory patterns) mi viene in mente che questo sistema possa servire per istanziare una sola volta una specifica factory concreta.


HashMap è una implementazione dell'interfaccia Map, package java.util.
Fa parte del "Collections Framework" distribuito con il JDK standard.
Una Map è l'interfaccia ad un oggetto che mappa chiavi con valori.

Nel codice che hai postato non vengono usati i Generics, quindi non viene dichiarto il tipo esplicito che la mappa usa per la chiave (Key) e per il valore (Value) ma esaminando la chiamata a 'put' si vede che il primo argomento (key) è di tipo String e il secondo argomento (value) di tipo Fruit.

L'interfaccia Map fornisce tre "viste" che permettono di esaminare il contenuto di una Map come:
- un set delle chiavi contenute;
- una collezione dei valori contenuti;
- un set di coppie chiave-valore.

L'ordine della Map è definito dall'ordine con cui gli iteratori delle tre viste della mappa iterano gli elementi.
Alcune implementazioni (come TreeMap) grantiscono un certo ordine, altre (come appunto HashMap) no.

Si raccomanda fortemente l'uso di oggetti immutabili come chiavi di una Map (String per l'appunto è immutabile).

Comunque qui trovi un trail se vuoi approfondire: Java Collection Framework
Ti ringrazio sei satato molto chiaro, ora vado a dare un'occhiata a quel link per la gestione di collezioni...

Già che ci sono chiedo un'altra cosa per togliermi un altro dubbio...cosa intendi esattamente con: "mi viene in mente che questo sistema possa servire per istanziare una sola volta una specifica factory concreta." ?

Cioè...dici che potrebbe essere usato come factory di factory concrete? o ho capito male?
TNX
e-commerce84 è offline   Rispondi citando il messaggio o parte di esso
Old 14-05-2010, 12:30   #5
nuovoUtente86
Senior Member
 
Iscritto dal: Mar 2007
Messaggi: 7863
Il metodo factory è quello statico getFruit che è l' unico in grado di istanziare oggetti di tipo Fruit, classe nella quale sono presenti solo costruttori privati.
Poi ovviamente puoi utilizzare lo stesso sistema anche per creare factory di altri altri factory, ma non è il caso in esempio.
nuovoUtente86 è offline   Rispondi citando il messaggio o parte di esso
Old 14-05-2010, 12:38   #6
banryu79
Senior Member
 
L'Avatar di banryu79
 
Iscritto dal: Oct 2007
Città: Padova
Messaggi: 4131
Quote:
Originariamente inviato da nuovoUtente86 Guarda i messaggi
Il metodo factory è quello statico getFruit che è l' unico in grado di istanziare oggetti di tipo Fruit, classe nella quale sono presenti solo costruttori privati.
Poi ovviamente puoi utilizzare lo stesso sistema anche per creare factory di altri altri factory, ma non è il caso in esempio.
Già, hai ragione.

Una cosa che mi viene in mente, forse un'osservazione banale.
Se usi questo sistema per creare istanze che poi vengono condivise, è meglio (anche se non è obbligatorio) che gli oggetti creati siano immutabili.
Nel caso specifico poi (Fruit), devono proprio esserlo, per evitare che chi ottiene la data reference Fruit con la chiave "mela" mi faccia, ad esempio, un setType("pera"), con tutte le conseguenze del caso...
__________________

As long as you are basically literate in programming, you should be able to express any logical relationship you understand.
If you don’t understand a logical relationship, you can use the attempt to program it as a means to learn about it.
(Chris Crawford)
banryu79 è offline   Rispondi citando il messaggio o parte di esso
Old 14-05-2010, 13:34   #7
nuovoUtente86
Senior Member
 
Iscritto dal: Mar 2007
Messaggi: 7863
E' necessario che gli oggetti siano immutabili: in maniera assoluta non è necessario, ma dipende dal caso particolare. E' fondamentale che però siano thread safe, cosa che il codice in esempio non è in quanto il "factory method" non implementa strumenti di sincronizzazione.
Cose fondamentali, oltre al thread-safe sono:
-non implementare clonable (o costruttori di copia profonda)
-non implementare serializable
-rendere il reference persistente
Le prime 2 impediscono di ottenere subdolamente istanze non univoche, il terzo di impedire al garbace collector di deallocare l' oggetto o la classe stessa.
nuovoUtente86 è offline   Rispondi citando il messaggio o parte di esso
Old 14-05-2010, 13:46   #8
banryu79
Senior Member
 
L'Avatar di banryu79
 
Iscritto dal: Oct 2007
Città: Padova
Messaggi: 4131
Quote:
Originariamente inviato da nuovoUtente86 Guarda i messaggi
-non implementare clonable (o costruttori di copia profonda)
-non implementare serializable
-rendere il reference persistente
Le prime 2 impediscono di ottenere subdolamente istanze non univoche, il terzo di impedire al garbace collector di deallocare l' oggetto o la classe stessa.
Puoi chiarire il terzo punto?
Nel senso: nell'esempio proposto non mi pare ci sia bisogno di fare alcunchè, in merito, giusto?
Non appena viene richiesta una qualsiasi istanza di Fruit del tipo 'type' viene creata l'istanza e messa nella mappa (che è static, e private).
Da quel momento in poi l'istanza può solo essere referenziata da N reference al di fuori di Fruit, e anche se fossero zero resterebbe sempre referenziata dalla mappa, no?
__________________

As long as you are basically literate in programming, you should be able to express any logical relationship you understand.
If you don’t understand a logical relationship, you can use the attempt to program it as a means to learn about it.
(Chris Crawford)
banryu79 è offline   Rispondi citando il messaggio o parte di esso
Old 14-05-2010, 14:05   #9
nuovoUtente86
Senior Member
 
Iscritto dal: Mar 2007
Messaggi: 7863
ma nessuno ti garantisce che il GC, sussitendo le condizioni, deallochi la classe con le sue componenti statiche.
In tal caso basta far referenziare la mappa da un runnable con il metodo run in wait().
nuovoUtente86 è offline   Rispondi citando il messaggio o parte di esso
Old 14-05-2010, 14:43   #10
banryu79
Senior Member
 
L'Avatar di banryu79
 
Iscritto dal: Oct 2007
Città: Padova
Messaggi: 4131
Quote:
Originariamente inviato da nuovoUtente86 Guarda i messaggi
ma nessuno ti garantisce che il GC, sussitendo le condizioni, deallochi la classe con le sue componenti statiche.
Ah, bon ammetto un'assoluta ignoranza in materia.
Quali sarebbero, in due parole, queste condizioni?

Quote:
Originariamente inviato da nuovoUtente86 Guarda i messaggi
In tal caso basta far referenziare la mappa da un runnable con il metodo run in wait().
Tecnica interessante
__________________

As long as you are basically literate in programming, you should be able to express any logical relationship you understand.
If you don’t understand a logical relationship, you can use the attempt to program it as a means to learn about it.
(Chris Crawford)
banryu79 è offline   Rispondi citando il messaggio o parte di esso
Old 14-05-2010, 16:01   #11
nuovoUtente86
Senior Member
 
Iscritto dal: Mar 2007
Messaggi: 7863
Le classi e le interfacce vengono scaricate qualora il proprio classloader decida in tal senso oppure sia esso stesso soggetto al GC. Di norma le classi caricate dal bootstrap class loader non non soggette ad unload.
nuovoUtente86 è offline   Rispondi citando il messaggio o parte di esso
Old 14-05-2010, 17:41   #12
e-commerce84
Senior Member
 
Iscritto dal: Feb 2009
Messaggi: 700
Ragazzi,
ora vi faccio una domanda che non c'entra molto...ma...io ora stò studiando queste slide del corso...ok...le capisco ma mai mi verrebbero in mente tutte le cose che state tirando fuori voi due

E' una questione di esperienza sul campo che si acquisice con tempo e pratica o dite che c'è proprio da studiare anche altre cose?
e-commerce84 è offline   Rispondi citando il messaggio o parte di esso
Old 14-05-2010, 18:24   #13
nuovoUtente86
Senior Member
 
Iscritto dal: Mar 2007
Messaggi: 7863
che corso di laurea frequenti?
nuovoUtente86 è offline   Rispondi citando il messaggio o parte di esso
Old 15-05-2010, 00:20   #14
e-commerce84
Senior Member
 
Iscritto dal: Feb 2009
Messaggi: 700
Quote:
Originariamente inviato da nuovoUtente86 Guarda i messaggi
che corso di laurea frequenti?
Informatica
e-commerce84 è offline   Rispondi citando il messaggio o parte di esso
Old 15-05-2010, 01:36   #15
nuovoUtente86
Senior Member
 
Iscritto dal: Mar 2007
Messaggi: 7863
Per quanto riguarda i pattern è importante il modo in cui è stato tenuto il corso di ingnegneria del software. Se è stato svolto in maniera adeguata dovresti avere la mente già predisposta a pensare, metodicamente, il software in maniera non monolita.
Per quanto riguarda le specifiche dei singoli linguaggi, bisogna andare a leggere la documentazione ufficiale disponibile.
nuovoUtente86 è offline   Rispondi citando il messaggio o parte di esso
Old 15-05-2010, 10:31   #16
^TiGeRShArK^
Senior Member
 
L'Avatar di ^TiGeRShArK^
 
Iscritto dal: Jul 2002
Città: Reggio Calabria -> London
Messaggi: 12112
Quote:
Originariamente inviato da nuovoUtente86 Guarda i messaggi
ma nessuno ti garantisce che il GC, sussitendo le condizioni, deallochi la classe con le sue componenti statiche.
In tal caso basta far referenziare la mappa da un runnable con il metodo run in wait().
che io sappia è inutile.
L'HashSet in questione verrà garbage-collected solo in caso la sua reference venga posta esplicitamente a null o la classe che lo contiene venga rimossa dal classloader manualmente o automaticamente nel caso di uscita dall'applicazione.
Non vedo il motivo per referenziare la mappa all'interno di un runnable in wait.

comunque riguardo a quel codice io lo scriverei così dato che imho sarebbe più chiaro:
Codice:
import java.util.*;

public interface IFruit {
    public String myMethod();
}

public class Apple implements IFruit {
    public Apple() { }
    public String myMethod { }
}

public class Orange implements IFruit {
    public Orange() { }
    public String myMethod { }
}


public class FruitFactory {
	
    private static Map<String, IFruit> fruits = new HashMap<String, IFruit>();	

    public static IFruit getFruit(Class clazz) {
        String type = clazz.getName();
        return fruits.containsKey(type) ? fruits.get(type) : clazz.newInstance();
    }
}


public class MainApp() {

    public MainApp() {
        Apple apple = FruitFactory.getFruit(Apple.class);
        Orange orange = FruitFactory.getFruit(Orange.class);
    }
}
Così si impediscono errori al runtime dovuti all'utilizzo delle stringhe e mi pare anche più chiaro quello che deve fare il codice.
__________________

Ultima modifica di ^TiGeRShArK^ : 15-05-2010 alle 10:35.
^TiGeRShArK^ è offline   Rispondi citando il messaggio o parte di esso
Old 15-05-2010, 11:15   #17
nuovoUtente86
Senior Member
 
Iscritto dal: Mar 2007
Messaggi: 7863
Quote:
Originariamente inviato da ^TiGeRShArK^ Guarda i messaggi
che io sappia è inutile.
L'HashSet in questione verrà garbage-collected solo in caso la sua reference venga posta esplicitamente a null o la classe che lo contiene venga rimossa dal classloader manualmente o automaticamente nel caso di uscita dall'applicazione.
Non vedo il motivo per referenziare la mappa all'interno di un runnable in wait.
Perchè solo l' utilizzo del bootstrap loader garantisce che l' istanza di tipo Class non entri nello scope del GC, ma non è detto che venga utilizzato il loader di default. Mentre un thread non sarà mai collected se il suo metodo run è ancora attivo.
nuovoUtente86 è offline   Rispondi citando il messaggio o parte di esso
Old 15-05-2010, 11:26   #18
^TiGeRShArK^
Senior Member
 
L'Avatar di ^TiGeRShArK^
 
Iscritto dal: Jul 2002
Città: Reggio Calabria -> London
Messaggi: 12112
Quote:
Originariamente inviato da nuovoUtente86 Guarda i messaggi
Perchè solo l' utilizzo del bootstrap loader garantisce che l' istanza di tipo Class non entri nello scope del GC, ma non è detto che venga utilizzato il loader di default. Mentre un thread non sarà mai collected se il suo metodo run è ancora attivo.
si, ma un user-defined classloader deve comunque alla fine richiamare i metodi del classloader della VM per poter caricare una classe...
Quindi, a meno della rimozione fatta esplicitamente sul classloader che avevo menzionato in precedenza mi sfugge perchè usando un custom class loader sia necessario utilizzare un runnable per mantenere attiva la reference della map....
__________________
^TiGeRShArK^ è offline   Rispondi citando il messaggio o parte di esso
Old 15-05-2010, 11:40   #19
nuovoUtente86
Senior Member
 
Iscritto dal: Mar 2007
Messaggi: 7863
java.lang.ClassLoader è una classe astratta. La jvm ne possiede una implementazione di default, utilizzata qualora non venga esplicitamente utilizzato un classLoader customizzato.
Nessuno vieta di costruirsene uno a proprio piacimento.
Il GC, si premura solo di non scaricare le classi referenziate dal loader nativo, su tutto il resto può applicare i proprio algoritmi di pulizia.
nuovoUtente86 è offline   Rispondi citando il messaggio o parte di esso
Old 15-05-2010, 12:15   #20
^TiGeRShArK^
Senior Member
 
L'Avatar di ^TiGeRShArK^
 
Iscritto dal: Jul 2002
Città: Reggio Calabria -> London
Messaggi: 12112
Quote:
Originariamente inviato da nuovoUtente86 Guarda i messaggi
java.lang.ClassLoader è una classe astratta. La jvm ne possiede una implementazione di default, utilizzata qualora non venga esplicitamente utilizzato un classLoader customizzato.
Nessuno vieta di costruirsene uno a proprio piacimento.
Il GC, si premura solo di non scaricare le classi referenziate dal loader nativo, su tutto il resto può applicare i proprio algoritmi di pulizia.
Aspè, il garbage collector agisce solo sulle reference, e non gliene frega se le instanze di quella classe sono state create da un classloader di default o da uno personalizzato...
Nel caso di classi statiche esse verrano rimosse solo quando viene rimosso il corrispettivo classloader.
__________________
^TiGeRShArK^ è offline   Rispondi citando il messaggio o parte di esso
 Rispondi


OPPO Watch X2 Mini, lo smartwatch compatto a cui non manca nulla OPPO Watch X2 Mini, lo smartwatch compatto a cui...
Xiaomi 15T Pro, è lui il nuovo best buy? La recensione Xiaomi 15T Pro, è lui il nuovo best buy? ...
Acer TravelMate P6 14 AI: il Copilot+ PC sotto il chilo per il professionista in movimento Acer TravelMate P6 14 AI: il Copilot+ PC sotto i...
ASUS NUC 15 Pro e NUC 15 Pro+, mini PC che fondono completezza e duttilità ASUS NUC 15 Pro e NUC 15 Pro+, mini PC che fondo...
Cybersecurity: email, utenti e agenti IA, la nuova visione di Proofpoint Cybersecurity: email, utenti e agenti IA, la nuo...
Scarpe che vi faranno correre alla veloc...
MOVA Z60 Ultra Roller Complete: 200€ di ...
Xiaomi SU7 si sposta da sola? Non esatta...
Cheater bannati entro 30 minuti senza ne...
Record di auto elettriche a settembre an...
In Norvegia due nuovi record: auto elett...
Linux sempre più orfano di Intel:...
Tesla conferma il bonus su Model 3: con ...
Anche Huawei prepara il suo smartphone u...
Sondaggio Steam: AMD guadagna ancora ter...
Zeekr si espande in Europa: 001, X e 7X ...
Fino a 17 sterline a telefono: il risarc...
Nintendo Switch 2 sfrutta una variante p...
AMD e OpenAI stringono un accordo strate...
Nest Cam 2K 3a gen: la videocamera da in...
Chromium
GPU-Z
OCCT
LibreOffice Portable
Opera One Portable
Opera One 106
CCleaner Portable
CCleaner Standard
Cpu-Z
Driver NVIDIA GeForce 546.65 WHQL
SmartFTP
Trillian
Google Chrome Portable
Google Chrome 120
VirtualBox
Tutti gli articoli Tutte le news Tutti i download

Strumenti

Regole
Non Puoi aprire nuove discussioni
Non Puoi rispondere ai messaggi
Non Puoi allegare file
Non Puoi modificare i tuoi messaggi

Il codice vB è On
Le Faccine sono On
Il codice [IMG] è On
Il codice HTML è Off
Vai al Forum


Tutti gli orari sono GMT +1. Ora sono le: 22:40.


Powered by vBulletin® Version 3.6.4
Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
Served by www3v