IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Design Patterns Discussion :

Besoin de quelques conseils pour une bonne approche POO à un projet


Sujet :

Design Patterns

  1. #1
    Membre habitué
    Inscrit en
    septembre 2008
    Messages
    234
    Détails du profil
    Informations forums :
    Inscription : septembre 2008
    Messages : 234
    Points : 156
    Points
    156
    Par défaut Besoin de quelques conseils pour une bonne approche POO à un projet
    Introduction

    Je projette d'écrire une "modification" ou script pour le jeu 3D Unreal Tournament dont le but seras de garder une ambiance bonne enfant sur les serveurs en l'absence d'un administrateur. Le langage qu'utilise ce jeu est le UnrealScript qui est comme un mélange de de C++ et de Java.

    La plupart des "modifications" dont j'ai pu voir le code mélangent l'orienté objet et le procédural, semble t-il pour des raisons de performances (je n'en suis pas tout à fait convaincu).

    Par exemple, il existe une classe Mutator (dont je vais me servir de base) qui modifie certains aspects d'une partie en cours. Les mutators proposés par des auteurs tiers étendent le plus souvent cette classe avec parfois un océan d'instructions ajoutées aux méthodes et le code est souvent difficile à comprendre. Pour les curieux, le code source de Mutator se trouve en bas de ce post.

    Je n'en suis pas certain à 100% mais il semble qu'il soit possible de travailler en objet car j'ai repéré la keyword New qui permettrais une instantiation. Comme j'ai vu du Java, j'aimerais appliquer quelques principes que j'ai appris au mod que je compte créer.

    Notez qu'il y a une contrainte. Il est déconseillé de modifier les classes standards pour conserver une certaine compatibilité avec les scripts existants.

    Maintenant, venons en aux questions pratiques.

    Mon objectif est d'écrire le script de sorte qu'il demande le moins de maintenance possible tout en offrant un maximum de possibilités. A ce titre, ce serais intéressant d'utiliser des design patterns.

    Classe intermédiaire

    La première question que je me pose c'est de savoir si c'est intéressant de créer une classe intermédiaire avec laquelle ma version de Mutator pourras communiquer.

    Par exemple, pour détecter l'arrivée d'un nouveau joueur dans le serveurs, il n'existe pas de méthode appropriée. Je dois donc utiliser une combinaison des méthodes ModifyLogin() et ModifyPlayer() pour détecter sa présence. Le ModifyLogin() permet d'intercepter l'arrivée d'un joueur et le ModifyPlayer() permet de confirmer que la connection au server s'est établi sans accroche.

    Il serais donc peut être plus intéressant de créer un objet intermédiare avec une méthode, disons nouveauJoueur(). Ou alors, je pourrais ajouter cette méthode à ma version de Mutator. Je ne sais pas si ce genre de chose est une pratique courante.

    Classes pour faciliter la gestion

    Ensuite, pour faciliter la gestion, je voudrais créer des classes utilitaires par rapport au joueur, la partie en cours et le serveur. Par exemple, je pourrais avoir une classe Joueur avec la méthode getIP() qui me renverrais un string contenant l'adresse IP d'un joueur.

    A ce propos, je me demande si je devrais créer l'équivalent d'une classe statique avec des méthodes qui pourraient être utilisées sur n'importe quel joueur ou une classe qui comporterais une référence vers le joueur (aggrégation ?).

    A ce titre, chaque joueur est representé par la classe PlayerPawn (pion du joueur). Comme le joueur peut disparaître à tout moment suite à une déconnection, je dois vérifier si Pawn pointe bien sur quelque chose avant de faire un appel pour chercher l'adresse IP. L'instruction utilisée est PlayerPawn( Player ).GetPlayerNetworkAddress() qui renvois l'adresse IP suivi de deux point et le numéro de port distant utilisé.

    Pour ce qui est de la partie, il n'y en a qu'une en cours à un moment donné. Quant au serveur, il n'est représenté par aucune classe mais il est possible d'obtenir quelques informations à son propos.

    Classes pour représenter des evenements

    Lorsque le script auras pris forme, je souhaiterais créer des classes pour représenter divers évènements comme le début d'une partie ou le départ d'un joueur. Ainsi, un autre programmeur auras la possibilité d'étendre ces classes et d'y intégrer son propre code.

    Pour arriver à cela, je pense créer un classe pour représenter une interface commune qui pourras être étendue (UnrealScript ne supporte ni les interfaces, ni l'héritage multiple).

    Ainsi, je pourrais instancier ces classes selon le cours d'une partie. Bien entendu, un seul évènement ne pourras avoir lieu à un moment donné. Je n'ai pas encore réflêchit sur la manière de signaler la fin d'un évènement mais il existe une méthode Destroy() commune à tous les objets.

    "Plugins"

    Pour augmenter les possibilités du script, j'aimerais ajouter la possibilité d'ajouter des plugins qui viendrons ajouter des fonctionalités au script de base. Pour cela, je compte également utiliser une classe qui va servir d'interface.

    Le souci à ce niveau c'est que les informations qui vont déclencher ces plugins proviendrons de Mutator. Donc, il faudrais que je prévoie ces informations et que j'intégre un maximum de méthodes dans l'interface pour relayer ces informations. Du coup, cela impose une certaine rigidité mais un autre programmeur pourras étendre Mutator et ajouter ses propres méthodes à l'interface.

    Communication inter classes

    Pour la dernière étape du projet, je dois réflêchir à la manière dont les classes instanciées doivent communiquer entre elles. Est-ce la classe Mutator devras superviser les méssages ou est-ce que ces classes peuvent directement s'adresser des méssages entre elles ?

    Pour donner un exemple concret, on pourrais avoir une classe évènement qui signale un abus commis par un joueur. Ensuite il faudras envoyer un méssage pour savoir quelle action dois être prise. Cette action peut être le simple ajout d'une entrée au fichier log du serveur ou, alors, le système peut mettre en garde ou expulser le joueur.

    A ce niveau, je ne suis pas encore décidé sur la manière dont je vais concevoir le processus. En plus des évenements, j'entrevois d'autres classes possibles tel des genres de listeners et des classes qui vont déclencher une série d'actions.

    Conclusion

    Merci d'avoir lu ou parcouru ce post. Tout cela à peut être l'air fouilli à première vue mais j'ai souhaité expliquer le projet de long en large ainsi que mes réflexions.

    N'hésitez pas à me poser des questions s'il y a quelque chose que vous ne comprenez pas. J'attends vos retours avec une certaine impatience et je serais ravi de discuter des problèmes pratiques que ce projet soulève.

    Le contenu de Mutator.uc :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    204
    205
    206
    207
    208
    209
    210
    211
    212
    213
    214
    215
    216
    217
    218
    219
    220
    221
    222
    223
    224
    225
    226
    227
    228
    //=============================================================================
    // Mutator.
    // called by the IsRelevant() function of DeathMatchPlus
    // by adding new mutators, you can change actors in the level without requiring
    // a new game class.  Multiple mutators can be linked together. 
    //=============================================================================
    class Mutator expands Info
    	native;
    
    var Mutator NextMutator;
    var Mutator NextDamageMutator;
    var Mutator NextMessageMutator;
    var Mutator NextHUDMutator;
    
    var bool bHUDMutator;
    
    var class<Weapon> DefaultWeapon;
    
    event PreBeginPlay()
    {
    	//Don't call Actor PreBeginPlay()
    }
    
    simulated event PostRender( canvas Canvas );
    
    function ModifyPlayer(Pawn Other)
    {
    	// called by GameInfo.RestartPlayer()
    	if ( NextMutator != None )
    		NextMutator.ModifyPlayer(Other);
    }
    
    function bool HandleRestartGame()
    {
    	if ( NextMutator != None )
    		return NextMutator.HandleRestartGame();
    	return false;
    }
    
    function bool HandleEndGame()
    {
    	// called by GameInfo.RestartPlayer()
    	if ( NextMutator != None )
    		return NextMutator.HandleEndGame();
    	return false;
    }
    
    function bool HandlePickupQuery(Pawn Other, Inventory item, out byte bAllowPickup)
    {
    	if ( NextMutator != None )
    		return NextMutator.HandlePickupQuery(Other, item, bAllowPickup);
    	return false;
    }
    
    function bool PreventDeath(Pawn Killed, Pawn Killer, name damageType, vector HitLocation)
    {
    	if ( NextMutator != None )
    		return NextMutator.PreventDeath(Killed,Killer, damageType,HitLocation);
    	return false;
    }
    
    function ModifyLogin(out class<playerpawn> SpawnClass, out string Portal, out string Options)
    {
    	if ( NextMutator != None )
    		NextMutator.ModifyLogin(SpawnClass, Portal, Options);
    }
    
    function ScoreKill(Pawn Killer, Pawn Other)
    {
    	// called by GameInfo.ScoreKill()
    	if ( NextMutator != None )
    		NextMutator.ScoreKill(Killer, Other);
    }
    
    // return what should replace the default weapon
    // mutators further down the list override earlier mutators
    function Class<Weapon> MutatedDefaultWeapon()
    {
    	local Class<Weapon> W;
    
    	if ( NextMutator != None )
    	{
    		W = NextMutator.MutatedDefaultWeapon();
    		if ( W == Level.Game.DefaultWeapon )
    			W = MyDefaultWeapon();
    	}
    	else
    		W = MyDefaultWeapon();
    	return W;
    }
    
    function Class<Weapon> MyDefaultWeapon()
    {
    	if ( DefaultWeapon != None )
    		return DefaultWeapon;
    	else
    		return Level.Game.DefaultWeapon;
    }
    
    function AddMutator(Mutator M)
    {
    	if ( NextMutator == None )
    		NextMutator = M;
    	else
    		NextMutator.AddMutator(M);
    }
    
    /* ReplaceWith()
    Call this function to replace an actor Other with an actor of aClass.
    */
    function bool ReplaceWith(actor Other, string aClassName)
    {
    	local Actor A;
    	local class<Actor> aClass;
    
    	if ( Other.IsA('Inventory') && (Other.Location == vect(0,0,0)) )
    		return false;
    	aClass = class<Actor>(DynamicLoadObject(aClassName, class'Class'));
    	if ( aClass != None )
    		A = Spawn(aClass,Other.Owner,Other.tag,Other.Location, Other.Rotation);
    	if ( Other.IsA('Inventory') )
    	{
    		if ( Inventory(Other).MyMarker != None )
    		{
    			Inventory(Other).MyMarker.markedItem = Inventory(A);
    			if ( Inventory(A) != None )
    			{
    				Inventory(A).MyMarker = Inventory(Other).MyMarker;
    				A.SetLocation(A.Location 
    					+ (A.CollisionHeight - Other.CollisionHeight) * vect(0,0,1));
    			}
    			Inventory(Other).MyMarker = None;
    		}
    		else if ( A.IsA('Inventory') )
    		{
    			Inventory(A).bHeldItem = true;
    			Inventory(A).Respawntime = 0.0;
    		}
    	}
    	if ( A != None )
    	{
    		A.event = Other.event;
    		A.tag = Other.tag;
    		return true;
    	}
    	return false;
    }
    
    /* Force game to always keep this actor, even if other mutators want to get rid of it
    */
    function bool AlwaysKeep(Actor Other)
    {
    	if ( NextMutator != None )
    		return ( NextMutator.AlwaysKeep(Other) );
    	return false;
    }
    
    function bool IsRelevant(Actor Other, out byte bSuperRelevant)
    {
    	local bool bResult;
    
    	// allow mutators to remove actors
    	bResult = CheckReplacement(Other, bSuperRelevant);
    	if ( bResult && (NextMutator != None) )
    		bResult = NextMutator.IsRelevant(Other, bSuperRelevant);
    
    	return bResult;
    }
    
    function bool CheckReplacement(Actor Other, out byte bSuperRelevant)
    {
    	return true;
    }
    
    function Mutate(string MutateString, PlayerPawn Sender)
    {
    	if ( NextMutator != None )
    		NextMutator.Mutate(MutateString, Sender);
    }
    
    function MutatorTakeDamage( out int ActualDamage, Pawn Victim, Pawn InstigatedBy, out Vector HitLocation, 
    						out Vector Momentum, name DamageType)
    {
    	if ( NextDamageMutator != None )
    		NextDamageMutator.MutatorTakeDamage( ActualDamage, Victim, InstigatedBy, HitLocation, Momentum, DamageType );
    }
    
    function bool MutatorTeamMessage( Actor Sender, Pawn Receiver, PlayerReplicationInfo PRI, coerce string S, name Type, optional bool bBeep )
    {
    	if ( NextMessageMutator != None )
    		return NextMessageMutator.MutatorTeamMessage( Sender, Receiver, PRI, S, Type, bBeep );
    	else
    		return true;
    }
    
    function bool MutatorBroadcastMessage( Actor Sender, Pawn Receiver, out coerce string Msg, optional bool bBeep, out optional name Type )
    {
    	if ( NextMessageMutator != None )
    		return NextMessageMutator.MutatorBroadcastMessage( Sender, Receiver, Msg, bBeep, Type );
    	else
    		return true;
    }
    
    function bool MutatorBroadcastLocalizedMessage( Actor Sender, Pawn Receiver, out class<LocalMessage> Message, out optional int Switch, out optional PlayerReplicationInfo RelatedPRI_1, out optional PlayerReplicationInfo RelatedPRI_2, out optional Object OptionalObject )
    {
    	if ( NextMessageMutator != None )
    		return NextMessageMutator.MutatorBroadcastLocalizedMessage( Sender, Receiver, Message, Switch, RelatedPRI_1, RelatedPRI_2, OptionalObject );
    	else
    		return true;
    }
    
    // Registers the current mutator on the client to receive PostRender calls.
    simulated function RegisterHUDMutator()
    {
    	local Pawn P;
    
    	ForEach AllActors(class'Pawn', P)
    		if ( P.IsA('PlayerPawn') && (PlayerPawn(P).myHUD != None) )
    		{
    			NextHUDMutator = PlayerPawn(P).myHud.HUDMutator;
    			PlayerPawn(P).myHUD.HUDMutator = Self;
    			bHUDMutator = True;
    		}	
    }
    
    defaultproperties
    {
    }
    P.S: Si vous souhaitez en découvrir plus sur l'UnrealScript, n'hésitez pas à visiter ce wiki : http://wiki.beyondunreal.com/
    Développeur en devenir.

    A la recherche de toute source approfondissant Merise, UML, Java, l'objet, les design patterns hors GOF et le développement en général.

    Recherche également des informations sur les techniques de développement et les bonnes pratiques en terme de programmation en entreprise.

    "On en apprends beaucoup plus par la confrontation que par la conciliation"

  2. #2
    Membre expérimenté
    Avatar de Patriarch24
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    septembre 2003
    Messages
    1 047
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Industrie

    Informations forums :
    Inscription : septembre 2003
    Messages : 1 047
    Points : 1 633
    Points
    1 633
    Par défaut
    Voici des pistes à creuser :
    Classe intermédiaire
    En lisant ton paragraphe, il me semble logique qu'une classe déléguée soit responsable de la gestion du joueur.

    Classes pour faciliter la gestion
    Les classes utilitaires ne sont pas inutiles, mais attention, car dans ton exemple tu parles d'information sur le joueur ; ces informations ne se retrouvent-elles pas via la classe déléguée de la première remarque ?

    Classes pour représenter des evenements
    ET
    Communication inter classes
    Le pattern observateur résout ce genre de problèmes.

    "Plugins"
    Pour ajouter plus simplement des fonctionnalités liées à une interface, le pattern décorateur est un bon choix.

    Bon courage !!!
    En premier lieu, utilisez un moteur de recherche.
    En second lieu, postez sur le forum adéquat !

  3. #3
    Membre habitué
    Inscrit en
    septembre 2008
    Messages
    234
    Détails du profil
    Informations forums :
    Inscription : septembre 2008
    Messages : 234
    Points : 156
    Points
    156
    Par défaut
    En lisant ton paragraphe, il me semble logique qu'une classe déléguée soit responsable de la gestion du joueur.
    Oui, une classe supplémentaire pourrais être nécessaire de part le fait qu'on ne puisse modifier les classes qui représentent le joueur (souci de compatibilité). Pawn représente un personnage ou une créature. Playerpawn est une classe fille de Pawn et représente le joueur en lui-même.

    Les classes utilitaires ne sont pas inutiles, mais attention, car dans ton exemple tu parles d'information sur le joueur ; ces informations ne se retrouvent-elles pas via la classe déléguée de la première remarque ?
    Mon idée d'une "classe intermédiaire" était de simplifier la vue de Mutator pour l'extérieur.

    Je voyais les "classes utilitaires" comme une classe statique, comme Math en Java, pour simplier l'accès aux informations et une certaine mise en forme. Mais à la différence de Math, les informations manipulées sont relatives à la référence d'un objet précis. Une délégation serais sans doute plus appropriée.

    Voici un exemple du genre de méthodes que je voudrais ajouter :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    function string getIP( Pawn p )
    {
    	local string ip;
    
    	if( p != none )
    	{
    		if( PlayerPawn( p ) != none )
    		{
    			ip = PlayerPawn( Player ).GetPlayerNetworkAddress();
    			ip = left( ip, Instr( ip, ":" ) );
    
    			if( Len( ip ) < 7 )
    				ip = "0.0.0.0";
    		}
    		else
    			ip = "0.0.0.0";
    
    		return ( ip );
    	}
    	else
    		ip = "0.0.0.0";
    }
    
    function string getName( Pawn player )
    {
    	local Pawn p;
    
    	if( player != none )
    		return PlayerReplicationInfo.PlayerName
    
    	return;
    }
    
    function int getPlayerID( Pawn aPawn )
    {
    	local Pawn p;
    
    	if( Level != none )
    	{
    		if( Pawn != none )
    		{
    			for( p = Level.PawnList; p != None; p = p.NextPawn )
    			{
    				if( P == aPawn )
    					return p.PlayerReplicationInfo.PlayerID;
    			}
    		}
    	}
    
    	return -1;
    }
    
    function float getScore( Pawn aPlayer )
    {
    	if( aPlayer != none )
    		return Killer.PlayerReplicationInfo.Score;
    
    	return -1;
    }
    (PlayerReplicationInfo est une classe utilisée dans le contexte d'une partie réseau et est attribuée à chaque joueur/client. Des informations sont repliquées entre le serveur et le client selon des règles prédéfinies.)

    Les accesseurs sont peu répandus et la manière habituelle d'obtenir des informations est d'adresser directement une méthode ou un attribut. J'ai eu la confirmation hier que l'instantiation est possible mais je suis étonné que quasi personne n'a vraiment exploité cette possibilité depuis que le jeu est sorti il y a une dizaine d'années. Les constructeurs n'existent pas alors je vais devoir standardiser à ce niveau.

    Sinon, merci pour les pistes et l'encouragement . Je vais réflêchir à la manière dont je pourrais adapter les classes pour utiliser les DP Observateur et Decorateur.
    Développeur en devenir.

    A la recherche de toute source approfondissant Merise, UML, Java, l'objet, les design patterns hors GOF et le développement en général.

    Recherche également des informations sur les techniques de développement et les bonnes pratiques en terme de programmation en entreprise.

    "On en apprends beaucoup plus par la confrontation que par la conciliation"

  4. #4
    Membre habitué
    Inscrit en
    septembre 2008
    Messages
    234
    Détails du profil
    Informations forums :
    Inscription : septembre 2008
    Messages : 234
    Points : 156
    Points
    156
    Par défaut
    Mes excuses au lecteurs éventuels si cela prends l'allure d'un monologue. Je compte me servir de ce thread comme journal et inviter des retours selon mes avancements.

    Pour en revenir à tes suggestions, Patriarch24, j'ai étudié de près les deux design pattern en question. Les remises en question sont doute du même ordre que ceux auquels pourraient être confrontés des personnes qui doivent modifier un système existant.

    Utiliser l'Observateur seras sans doute une chose difficile car la classe observée dois implémenter une classe Sujet prédéfinie. Il vaut mieux ne pas toucher la classe PlayerPawn (remplacer cette classe demanderais une procédure horriblement compliquée) et la classe qui va me servir de base seras déjà une sous-classe de Mutator. Par contre, il ne devrais pas y avoir d'obstacles avec des classes de ma propre composition.

    Le Décorateur, qui semble agir comme un genre de "wrapper" ou emballage, pourrais être très utile dans le cas de ces classes qu'on ne dois pas modifier mais une Délégation simple serais plus adaptée. En ce qui concerne l'idée de plug-in, il y a de toute manière la possibilité d'ajouter des méthodes sans trop chipoter.

    Au cas où d'autres personnes auraient des suggestions au niveau patterns, ce qui me posais un soucis c'est de décider de quelle manière les informations vont entrer dans le système. A l'origine, j'envisageais trois approches possibles (mais pas nécessairement appropriées) :

    - L'une consisterais à considérer la classe de base comme chef qui dicte les méthodes possibles à tous les objets plug-in qui dialoguent avec lui. L'inconvénient de cette approche c'est qu'on limite les possibilités au niveau des classes existantes. Pour ajouter des possibilités il faudrais réécrire Mutator.

    - L'autre approche serais de laisser les classes plug-in aller chercher leurs propres informations auprès des objets du système existant. Dans ce cas, le classe Mutator supervise uniquement les méthodes qui le concerne et il y a moins de contrôle central.

    - La dernière approche serais de considérer les plug-in comme faisant partie intégrante de Mutator. Dans ce cas, il n'y a plus aucun contrôle et, à la limite, Mutator pourrais être réduit à une coquille vide.
    Développeur en devenir.

    A la recherche de toute source approfondissant Merise, UML, Java, l'objet, les design patterns hors GOF et le développement en général.

    Recherche également des informations sur les techniques de développement et les bonnes pratiques en terme de programmation en entreprise.

    "On en apprends beaucoup plus par la confrontation que par la conciliation"

  5. #5
    Membre actif
    Profil pro
    Inscrit en
    décembre 2008
    Messages
    217
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : décembre 2008
    Messages : 217
    Points : 253
    Points
    253
    Par défaut
    Citation Envoyé par Jimalexp Voir le message
    Mes excuses au lecteurs éventuels si cela prends l'allure d'un monologue. Je compte me servir de ce thread comme journal et inviter des retours selon mes avancements.
    Un blog serait peut être plus approprié, non ? Vous semblez avoir déjà du contenu à mettre dessus. Just saying...

    Je rebondis juste là dessus :

    Citation Envoyé par Jimalexp Voir le message
    Mon idée d'une "classe intermédiaire" était de simplifier la vue de Mutator pour l'extérieur.

    Je voyais les "classes utilitaires" comme une classe statique, comme Math en Java, pour simplier l'accès aux informations et une certaine mise en forme. Mais à la différence de Math, les informations manipulées sont relatives à la référence d'un objet précis
    En fait, vous avez pour ainsi dire reformulé l'idée du pattern "façade", pattern assez abstrait et "structurant" mais que j'ai trouvé utile moi aussi à plusieurs reprises ; pour rappel, voir :

    http://en.wikipedia.org/wiki/Facade_pattern

    L'usage que vous prévoyez de faire de celui-ci dans votre conception, avec les autres patterns, me semble ainsi assez justifié.

    Bon courage et bonne suite sur ce projet.

    'HTH

  6. #6
    Membre habitué
    Inscrit en
    septembre 2008
    Messages
    234
    Détails du profil
    Informations forums :
    Inscription : septembre 2008
    Messages : 234
    Points : 156
    Points
    156
    Par défaut
    Citation Envoyé par lysiandad Voir le message
    Un blog serait peut être plus approprié, non ? Vous semblez avoir déjà du contenu à mettre dessus. Just saying...
    Vous avez raison. Je prévois mon propre site d'ici quelques temps et ce serais l'idéal pour mettre en avant mes acquis et aussi inviter les internautes à me faire part des leurs.

    Dorénavant, je me contenterais d'éditer mes posts ou d'ajouter une réponse. Il n'est utile que d'entretenir un fil si celui-ci suscite un intérêt aussi bien chez celui qui pose une question que celui qui y apporte une réponse.

    Il se peut toutefois que je scinde le problème en quelque chose de plus digeste en créant de nouveaux fils de discussion selon une certaine automodération et si personne n'y voie un inconvénient.

    En fait, vous avez pour ainsi dire reformulé l'idée du pattern "façade", pattern assez abstrait et "structurant" mais que j'ai trouvé utile moi aussi à plusieurs reprises ; pour rappel, voir :

    http://en.wikipedia.org/wiki/Facade_pattern
    Oui, je connais la façade. Une personne en avais parlé en donnant un exemple. Il s'agissais d'un système consultable à distance ayant la particularité d'être assez complexe en interne. Dans cet exemple, la façade avais pour but de simplifier les interactions (sans doute dans le but de permettre un dialogue avec une interface graphique). C'est un peu dans cet ordre d'idée là.

    Pour ce qui est du Décorateur, j'ai été faire un petit tour sur le sous-site de Sébastien MERIC et l'Adaptateur est assez voisin. En fait, je me rends compte que les DP sont à utiliser selon son interprétation de la nature du problème.

    Je pense que le mieux c'est que de déjà écrire un peu de code. Au pire, il y aura quelques lignes à changer si je fais fausse route.

    Entretemps, peut être que je devrais ajouter un schéma plus tard car il y a une particularité à tout cela. Contrairement à une application Java, certains objets sont déjà présents lorsque l'application est lancée et certains sont chargés au fur et à mesure qu'une partie démarre ou qu'un client se connecte à une partie.

    Cela signifie que le script est exécuté en plein runtime. Donc, par exemple, la délégation au sens stricte du terme n'est pas possible. Ce n'est pas l'une des mes classes qui va instantier une des classes standards car ces instances existent déjà. Au contraire, si je veut faire quelque chose qui y ressemble, je devrais instantier ma classe et ensuite lui indiquer à quelle classe les méssages doivent être délégués.
    Développeur en devenir.

    A la recherche de toute source approfondissant Merise, UML, Java, l'objet, les design patterns hors GOF et le développement en général.

    Recherche également des informations sur les techniques de développement et les bonnes pratiques en terme de programmation en entreprise.

    "On en apprends beaucoup plus par la confrontation que par la conciliation"

Discussions similaires

  1. Réponses: 4
    Dernier message: 07/12/2007, 19h39
  2. Réponses: 2
    Dernier message: 10/05/2007, 18h10
  3. [AS2] Conseils pour une bonne utilisation de la POO
    Par guy2004 dans le forum ActionScript 1 & ActionScript 2
    Réponses: 9
    Dernier message: 20/03/2006, 09h24
  4. Besoin de quelques conseils pour un script java
    Par poussin544 dans le forum Général JavaScript
    Réponses: 7
    Dernier message: 02/03/2006, 11h41
  5. Besoin d'un conseil pour une sélection Access/fichier
    Par Oluha dans le forum Bases de données
    Réponses: 1
    Dernier message: 20/03/2005, 20h10

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo