apres quelques petits tests je pense que j'ai trouvé
une maniere simple de mettre ce pattern en place :).
deja un peu de definition
http://fr.wikipedia.org/wiki/Singleton_(Motif_de_conception)
" Dans un langage à base de prototypes, où sont utilisés des objets mais pas
des classes, un singleton désigne seulement un objet qui n'a pas de copies,
et qui n'est pas utilisé comme prototype pour d'autres objets. "
en francais aussi
http://www.microsoft.com/france/msdn/architects/info/info.asp?mar=/france/msdn/architects/info/20032811-des-singleton.html
le but d'un Singleton:
- crée une instance unique de la classe
- avoir un acces global a cet instance
- ne pas pouvoir instancier la classe plus d'une fois
Et comme on est en ECMAScript:
- l'instance doit etre un objet sans copies
dans Flex2 creez un projet ActionScript
---------------------------------------------------
package
{
import flash.display.MovieClip;
import flash.util.trace;
import myTest.*;
public class toto extends MovieClip
{
public function toto()
{
trace( MySingleton.test );
trace( MySingleton.foobar );
trace( MySingleton.testMethod() );
}
}
}
---------------------------------------------------
ensuite on va cree un package myTest
qui va contenir le Singleton
---------------------------------------------------
package myTest
{
/* class is internal to package
*/
class Singleton
{
/* Package scope constructor
*/
function Singleton()
{
}
/* you have to declare const, method, property etc.
public so they can be accessed outside of the package
*/
public const test:String = "hello world";
public var foobar:String = "foobar";
public function testMethod():String
{
return "Singleton.testMethod";
}
}
}
---------------------------------------------------
dans ce meme package myTest on va instancier le Singleton
---------------------------------------------------
package myTest
{
/* Singleton
one unique global access point
class can be instancied only once inside its own package
MySingleton is an Object not a class
*/
public const MySingleton:Singleton = new Singleton();
}
---------------------------------------------------
quelques explication supplémentaires:
- le fait d'utiliser une constante empeche que l'on puisse
reinstancier celle-ci avec un autre objet
- comme on cree dans la constante un objet
meme si celle ci est copiée, ce sera une reference
vers l'objet original
- la class Singleton etant internal au package myTest
ne peut etre que instanciée dans celui-ci
- meme si on importe le package myTest
on ne pourra utilisé que les objets, classes, methodes etc.
déclarées public
usage:
on peut faire l'import soit
import myTest.MySingleton;
soit
import myTest.*;
et ensuite on utilise le singleton
trace( MySingelton.test );
ou directement acceder au chemin complet
trace( myTest.MySingelton.test );
voila,
commentaires bienvenus
zwetan
________________________________________
FCNG id: 56000000 - flexcodeurs
Archive: Mon, 14 Nov 2005 18:35:47 +0100
________________________________________
http://www.buRRRn.com/projects/FCNG.html
"zwetan" <flashc...@zwetan.com> a écrit dans le message de
news: kfEgeGU6FHA.348@BURN...
________________________________________
FCNG id: 57000000 - flexcodeurs
Archive: Mon, 14 Nov 2005 19:55:43 +0100
________________________________________
http://www.buRRRn.com/projects/FCNG.html
bah meme dans le cas d une class publique avec des acces statiques
aux methods, les definitions de fonctions ne sont utilisées
qu'une seule fois...
quand a l acces plus lent aux methodes, j aimerais bien savoir
ce qui te fait dire ca ?
> Bon, sans utiliser de vérification statique des types, on peut
> faire autrement, mais sinon, je ne sais pas. Peut-pas utiliser
> un package pour ça ?
bah si justement j'utilise le package
une class internal au package + une const public
dans le meme package
pour ce qui est de faire autrement
oui une simple instanciation d'objet peut le faire
mais le probleme avec cela c'est qu on peut instancier
la class plus d'une fois
l'avantage du package c est qu on peut forcer
la class a etre internal pour qu elle ne soit pas
instanciée plus d une fois (si on a besoin de ce genre de feature).
zwetan
________________________________________
FCNG id: 58000000 - flexcodeurs
Archive: Mon, 14 Nov 2005 20:09:52 +0100
________________________________________
http://www.buRRRn.com/projects/FCNG.html
Je ne comprends pas ce que tu veux dire. Je ne sais pas si tu as compris
que je parlais du constructeur stocké en mémoire pour n'être utilisé
qu'une seule fois.
>
> quand a l acces plus lent aux methodes, j aimerais bien savoir
> ce qui te fait dire ca ?
La recherche dans la chaîne de prototype en AS2, en AS3 peut-être une
étape supplémentaire pour le JIT.
>
>
>>Bon, sans utiliser de vérification statique des types, on peut
>>faire autrement, mais sinon, je ne sais pas. Peut-pas utiliser
>>un package pour ça ?
>
>
> bah si justement j'utilise le package
Je voulais dire : package Singleton {}.
Mais apparemment, on peut pas définir de fonction directement dans un
package. Et restait le problème de l'initialisation.
>
> une class internal au package + une const public
> dans le meme package
>
> pour ce qui est de faire autrement
> oui une simple instanciation d'objet peut le faire
> mais le probleme avec cela c'est qu on peut instancier
> la class plus d'une fois
>
> l'avantage du package c est qu on peut forcer
> la class a etre internal pour qu elle ne soit pas
> instanciée plus d une fois (si on a besoin de ce genre de feature).
Oui, c'est en effet beaucoup mieux, en tout cas dans l'aspect publique,
qu'en AS2.
Pourquoi pas un déclarateur "singleton" (à part son absence du standard
ECMA) ?
________________________________________
FCNG id: 59000000 - flexcodeurs
Archive: Mon, 14 Nov 2005 23:20:45 +0100
________________________________________
http://www.buRRRn.com/projects/FCNG.html
>
> Je ne comprends pas ce que tu veux dire. Je ne sais pas si tu as compris
> que je parlais du constructeur stocké en mémoire pour n'être utilisé
> qu'une seule fois.
>
le constructeur n'est qu'une fonction comme une autre
il n'y a pas de "gaspillage" mémoire,
pas plus que de définir une methode "toString",
et l'appeler 0, 1 ou 10 fois
> >
> > quand a l acces plus lent aux methodes, j aimerais bien savoir
> > ce qui te fait dire ca ?
>
> La recherche dans la chaîne de prototype en AS2, en AS3 peut-être une
> étape supplémentaire pour le JIT.
d'une le JIT en AS2 il n'existe pas,
le code AS2 compile en code AS1 pour la VM 1
la seule chose que fait le compilo c'est de faire un "compile-time type
check"
cad verifier que les type déclarés sont corrects a la compilation
mais en soit un
toto:String = "hello world" en notation AS2 avec le typage
n'est pas plus optimisé que
toto = "hello world" en notation AS1
(lorsque l'on compile avec autre chose que Flex2)
ensuite pour le code AS3, tant que l'on reste avec une syntaxe AS3
on compile vers la VM 1.5, celle qui est justement encore plus optimisée
(oui la syntaxe AS3 ressemble a la syntaxe AS2, mais ce n'est pas pareil)
si par contre tu déclare ton singleton en syntaxe AS1, et/ou a base de
prototype
en le compilant avec Flex2, là oui il y aura moins d'optimisation
mais pas plus que si tu compilais du code AS1/AS2 pour le flash player 7/8
actuel
cad que tout ce qui est AS3 sera compilé pour la VM 1.5
et le reste sera compilé en paralelle pour la VM 1
mais la VM 1 en soit n'est pas lente, elle est juste moins optimisée que la
VM 1.5
il faudrait voir cela comme du "code managé" (VM 1.5)
et du "code non-managé" (VM 1) a la maniere de .NET
et amha il faut vraiment aller dans les extremes pour voir de grosses
differences
mais là de toute manière le probleme ne se pose pas vu que
la construction de singleton que je propose est de toute maniere
en syntaxe AS3 et donc tout compile vers la VM 1.5.
> >
> >>Bon, sans utiliser de vérification statique des types, on peut
> >>faire autrement, mais sinon, je ne sais pas. Peut-pas utiliser
> >>un package pour ça ?
> >
> >
> > bah si justement j'utilise le package
>
> Je voulais dire : package Singleton {}.
> Mais apparemment, on peut pas définir de fonction directement dans un
> package. Et restait le problème de l'initialisation.
>
si si tu peux declare une function dans un package
package test
{
public function titi():String
{
return "titi";
}
}
cependant il y a UNE chose a respecter dans un package
il ne peut y avoir qu'un seul point d'entrée qui est publique
on ne pourrait pas avoir en meme temps (dans le meme fichier)
une function publique et une declaration de class publique
et donc si tu declares une fonction publique
tu dois laisser la class en internal
le chose qui est publique doit avoir le meme nom que le fichier
test/titi.as
----------------------
package test
{
public function titi():String
{
return "titi";
}
internal class someClass
{
}
}
----------------------
on peut voit ce genre de construction dans playerglobal.as
avec fscommand
----------------------
package flash.system
{
import flash.events.*;
public function fscommand(command:String, args:String=""):Void
{
FSCommand._fscommand(command, args);
}
/**
* @private Internal only
*/
final class FSCommand
{
/**
* @private Internal only
*/
public static native function _fscommand(command:String,
args:String):Void;
}
}
----------------------
ici on ne peut acceder que a la function, mais pas a la class
> >
> > une class internal au package + une const public
> > dans le meme package
> >
> > pour ce qui est de faire autrement
> > oui une simple instanciation d'objet peut le faire
> > mais le probleme avec cela c'est qu on peut instancier
> > la class plus d'une fois
> >
> > l'avantage du package c est qu on peut forcer
> > la class a etre internal pour qu elle ne soit pas
> > instanciée plus d une fois (si on a besoin de ce genre de feature).
>
> Oui, c'est en effet beaucoup mieux, en tout cas dans l'aspect publique,
> qu'en AS2.
> Pourquoi pas un déclarateur "singleton" (à part son absence du standard
> ECMA) ?
a cause de ce qui est expliqué dans le 1er post
" Dans un langage à base de prototypes, où sont utilisés des objets mais pas
des classes, un singleton désigne seulement un objet qui n'a pas de copies,
et qui n'est pas utilisé comme prototype pour d'autres objets. "
on n'a pas besoin de reinventer l'objet, avec ECMAScript on y a directement
acces
cf http://livedocs.macromedia.com/labs/1/flex/langref/Class.html
une "Class" est un objet qui contient la definition d'une classe
class Foo
{
}
Foo est l'objet Class pour Foo et du type Class.
la déclaration "new Foo()" crée une instance(objet) de la class Foo qui est
de type Foo
ce qui fait que si on voullait juste un "conteneur" de type objet
on pourrait aussi bien ecrire ca
test/Foo.as
------------------------------
package test
{
public class Foo
{
static bar:String = "foobar";
}
}
------------------------------
que ca
test/Foo.as
------------------------------
package test
{
public var Foo:Object = {};
Foo.bar = "foobar";
}
------------------------------
les deux notations nous donnerait un chemin objet
test.Foo.bar et fonctionneraient de la meme maniere
la difference, c'est que dans la 2nde notation (meme si celle-ci est valide
en AS3)
on perdrait l'avantage de pouvoir donner un type aux membres de l'objet
et que donc on y perdrait un peu d'optimisation.
zwetan
________________________________________
FCNG id: 5a000000 - flexcodeurs
Archive: Tue, 15 Nov 2005 02:46:04 +0100
________________________________________
http://www.buRRRn.com/projects/FCNG.html
"zwetan" <flashc...@zwetan.com> a écrit dans le message de
news: omX5bYY6FHA.3248@BURN...
>
>>
>> Je ne comprends pas ce que tu veux dire. Je ne sais pas si tu
>> as compris
>> que je parlais du constructeur stocké en mémoire pour n'être
>> utilisé
>> qu'une seule fois.
>>
>
> le constructeur n'est qu'une fonction comme une autre
> il n'y a pas de "gaspillage" mémoire,
> pas plus que de définir une methode "toString",
> et l'appeler 0, 1 ou 10 fois
Sauf que la méthode toString est justement prévue pour être
appelée n fois. La fonction de construction du singleton, ne
sera, par définition, invoquée qu'une fois. Mais je chipote.
[...]
> si si tu peux declare une function dans un package
>
> package test
> {
>
> public function titi():String
> {
> return "titi";
> }
>
> }
>
> cependant il y a UNE chose a respecter dans un package
>
> il ne peut y avoir qu'un seul point d'entrée qui est publique
En es-tu sûr ?
Que ce soit vrai pour un élément d'un package défini dans un
fichier (par ex dans monPackage/maClass.as), ça semble logique.
Mais je ne suis pas sûr qu'on ne puisse pas écrire (par ex dans
monPackage.as) :
package monPackage {
public class MaClass {
}
public fonction maFonction {
}
// ...
}
La doc va dans ce sens.
Peut-on imbriquer des déclarations de package ? :
package monPackage {
public package monSousPackage {
}
}
________________________________________
FCNG id: 5b000000 - flexcodeurs
Archive: Tue, 15 Nov 2005 11:09:24 +0100
________________________________________
http://www.buRRRn.com/projects/FCNG.html
euh oui je parle des defintions de class
avec cette erreurei
"A file found in an actionscript-classpath can not have more than one
externally visible definition. myTest:blue;myTest:blah;myTest$internal:Foo"
apres je n ai pas vue dans la doc qu'on pouvait mettre tout
dans un seul fichier nomDuPackage.as ?!?
> Peut-on imbriquer des déclarations de package ? :
>
> package monPackage {
> public package monSousPackage {
> }
> }
>
pas dans un meme fichier
cf l erreure " 1037 Packages must not be nested "
mais dans des fichiers differents on peut faire ce qu'on veut
package monPackage
{
}
package monPackage.monSousPackage
{
}
je sais pas, sur ce point là j'ai cherché les docs
et pas vue de documents clair...
zwetan
________________________________________
FCNG id: 5c000000 - flexcodeurs
Archive: Tue, 15 Nov 2005 13:41:13 +0100
________________________________________
http://www.buRRRn.com/projects/FCNG.html