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

Langage Delphi Discussion :

Changer la visibilité du constructeur


Sujet :

Langage Delphi

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre confirmé Avatar de samaury
    Homme Profil pro
    Chevalier Jedi
    Inscrit en
    Mars 2008
    Messages
    114
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Côte d'Ivoire

    Informations professionnelles :
    Activité : Chevalier Jedi
    Secteur : Finance

    Informations forums :
    Inscription : Mars 2008
    Messages : 114
    Par défaut Changer la visibilité du constructeur
    Bonjour
    Je cherche à implémenter le pattern "Singleton" dans mon appli.
    J'ai besoin de changer la visibilité de mon constructeur de classe pour le mettre en "private" ou "protected" et déleguer la construction de mon singleton à une methode de classe du genre "getInstance()".
    En clair je souhaite faire ceci.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    TMaclasse=class
     private
      ///Redéfinition du constructeur de classe
      constructor create();reintroduce;
     public
      ///Crée une seule instance de TMaclasse ou renvoie celle déja créée
      class function getInstance():TMaClasse;
      .....
    end;
    Mon problème est-que le constructeur create() reste visible en dehors de l'unité contenant TMaclasse.
    Quelqu'un a une idée de comment je peux faire ça?...ou est-ce possible de changer la visibilité de mon constructeur;
    Je précise que je suis sous Delphi 2005.

    Merci

  2. #2
    Membre confirmé Avatar de samaury
    Homme Profil pro
    Chevalier Jedi
    Inscrit en
    Mars 2008
    Messages
    114
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Côte d'Ivoire

    Informations professionnelles :
    Activité : Chevalier Jedi
    Secteur : Finance

    Informations forums :
    Inscription : Mars 2008
    Messages : 114
    Par défaut
    Dans le même ordre d'idée : est-il possible de changer la visibilité du destructeur pour le rendre inaccessible hors de mon unité?
    Merci.

  3. #3
    Expert confirmé
    Avatar de Cl@udius
    Homme Profil pro
    Développeur Web
    Inscrit en
    Février 2006
    Messages
    4 878
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 62
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : High Tech - Matériel informatique

    Informations forums :
    Inscription : Février 2006
    Messages : 4 878
    Par défaut
    Salut

    Citation Envoyé par samaury Voir le message
    J'ai besoin de changer la visibilité de mon constructeur de classe pour le mettre en "private" ou "protected"
    Pourquoi ce besoin impérieux ?

    La définition d'une classe Singleton n'est pas très compliquée en elle-même. Contrôler l'unicité de l'instance de la classe ne nécessite pas a priori de changer la visibilité du constructeur/destructeur.

    @+ Claudius.

  4. #4
    Membre confirmé Avatar de samaury
    Homme Profil pro
    Chevalier Jedi
    Inscrit en
    Mars 2008
    Messages
    114
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Côte d'Ivoire

    Informations professionnelles :
    Activité : Chevalier Jedi
    Secteur : Finance

    Informations forums :
    Inscription : Mars 2008
    Messages : 114
    Par défaut
    Pourquoi ce besoin impérieux ?
    Je ne serai pas le seul à utiliser cette classe. Il s'agit d'une classe utilitaire que d'autres collègue auront à utiliser. Mon but est de les obliger à utiliser le getInstance() plutot que un create() pour instancier la classe.

    La définition d'une classe Singleton n'est pas très compliquée en elle-même. Contrôler l'unicité de l'instance de la classe ne nécessite pas a priori de changer la visibilité du constructeur/destructeur.
    Je suis bien d'accord. Mais pour la raison exposée plus haut masquer le create() me paraissait plus "propre" mais si ce n'est pas possible, je me contenterais de mon getInstance() sans masquer le create()
    Merci

  5. #5
    Expert confirmé
    Avatar de Cl@udius
    Homme Profil pro
    Développeur Web
    Inscrit en
    Février 2006
    Messages
    4 878
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 62
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : High Tech - Matériel informatique

    Informations forums :
    Inscription : Février 2006
    Messages : 4 878
    Par défaut
    Citation Envoyé par samaury Voir le message
    Mon but est de les obliger à utiliser le getInstance() plutot que un create() pour instancier la classe.
    Mouais. Je suis peut-être trop conventionnel.

    Perso je définirais ma classe ainsi:
    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
    interface
     
    type
      TSingleton = class
      strict private
        class var
          FInstance: TObject;
          FRefCount: Integer;
      private
          FList: TList;
          F1: Integer;
      public
        destructor Destroy; override;
        class function NewInstance: TObject; override;
        procedure FreeInstance; override;
        class function RefCount: Integer;
      end;
     
    implementation
     
    { TSingleton }
     
    destructor TSingleton.Destroy;
    begin
      FList.Free;
      inherited;
    end;
     
    procedure TSingleton.FreeInstance;
    begin
      Assert(FRefCount > 0);
     
      Dec(FRefCount);
      if FRefCount = 0 then
      begin
        FInstance := nil;
        inherited;
      end;
    end;
     
    class function TSingleton.NewInstance: TObject;
    begin
      if not Assigned(FInstance) then
      begin
        FInstance:= inherited NewInstance;
        FRefCount := 0;
        // Init des variables privées
        with TSingleton(FInstance) do
        begin
          FList := TList.Create;
          F1 := 0;
        end;
      end;
      Result := FInstance;
      Inc(FRefCount);
    end;
     
    class function TSingleton.RefCount: Integer;
    begin
      Result := FRefCount;
    end;
     
     
    // Utilisation
     
    var
      o1, o2, o3: TSingleton;
    begin
      o1 := TSingleton.Create;
      o2 := TSingleton.Create;
      o3 := TSingleton.Create;
      ShowMessage(Format('RefCount: %d', [TSingleton.RefCount]));
     
      o1.Free;
      o2.Free;
      o3.Free;
      ShowMessage(Format('RefCount: %d', [TSingleton.RefCount]));
    end;
    Une instance unique de la classe avec un comptage de référence.
    Cela me parait plus "conventionnel" voire plus simple.

    @+ Claudius

  6. #6
    Membre émérite Avatar de Kaféine
    Homme Profil pro
    Inscrit en
    Avril 2007
    Messages
    569
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Avril 2007
    Messages : 569
    Par défaut
    Salut,

    Plutôt que masquer le create, autant raisé une exception dedans.

    Voici mon idée:

    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
     
      TTest = class sealed
      private
        class var
          FCanCreate: Boolean;
          FInstance: TTest;
      public
        constructor Create;
        class function GetInstance: TTest;
      end;
     
    implementation
     
    constructor TTest.Create;
    begin
      if not TTest.FCanCreate then
        raise Exception.Create('Utilisez la méthode GetInstance sinon je vous tire les oreilles :)');
    end;
     
    class function TTest.GetInstance: TTest;
    begin
      if FInstance = nil then
      begin
        TTest.FCanCreate := True;
        FInstance := TTest.Create;
        TTest.FCanCreate := False;
      end;
      Result := FInstance;
    end;
     
    initialization
     
    finalization
      if TTest.FInstance <> nil then
        TTest.FInstance.Free;

  7. #7
    Membre confirmé Avatar de samaury
    Homme Profil pro
    Chevalier Jedi
    Inscrit en
    Mars 2008
    Messages
    114
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Côte d'Ivoire

    Informations professionnelles :
    Activité : Chevalier Jedi
    Secteur : Finance

    Informations forums :
    Inscription : Mars 2008
    Messages : 114
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Mouais. Je suis peut-être trop conventionnel.
    J'ai pas tout compris mais on va dire que on est lundi et que mon neurone n'est pas encore sorti d'hibernation...

    Perso je définirais ma classe ainsi:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    ...
      strict private
        class var
          FInstance: TObject;
          FRefCount: Integer;
    ...
    J'ai peur que les appli win32 ne supportent pas le
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    strict private
        class var
    comme déclaration à l'intérieur d'une classe, à moins que ce soit D2005...ou alors je m'y prends vraiment très mal.
    Du coup mon équivalent de ton "FInstance" est déclaré dans la partie implementation de mon unité pour n'être accessible que localement.
    Merci

  8. #8
    Membre Expert
    Avatar de e-ric
    Homme Profil pro
    Apprenti chat, bienfaiteur de tritons et autres bestioles
    Inscrit en
    Mars 2002
    Messages
    1 568
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 56
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Apprenti chat, bienfaiteur de tritons et autres bestioles

    Informations forums :
    Inscription : Mars 2002
    Messages : 1 568
    Par défaut
    Salut

    L'implémentation du singleton si l'on veut être formel n'est pas simple avec Delphi (je ne parle pas de la version .NET, je ne la connais pas).

    Le constructeur ne peut être privé car Create est toujours disponible depuis TObject et on ne peut pas réduire la portée d'une méthode. En outre, Delphi a ce petit défaut qu'il est toujours possible pour un développeur de libérer l'objet à tout moment.

    Pour le singleton, j'ai trouvé une solution "exotique" qui consiste à employer une classe et non un objet. Les méthode sont alors des méthodes de classe. L'état de "l'objet singleton" est représenté par des variables d'implémentation de son unité. Cela n'amène pas à un travail surhumain. Mais la solution a ses limites, l'état du singleton est en dehors (variables d'implémentation) de l'entité syntaxique utilisée, il n'est pas possible par exemple d'examiner l'état interne de ton objet grâce à un pointeur.

    C'est un peu de la bidouille, mais du fait de l'emploi d'une classe, on obtient bien un singleton. Chaque classe est unique par nature.
    Cependant si ton singleton

    Cdlt

    M E N S . A G I T A T . M O L E M
    Debian 64bit, Lazarus + FPC -> n'oubliez pas de consulter les FAQ Delphi et Pascal ainsi que les cours et tutoriels Delphi et Pascal

    "La théorie, c'est quand on sait tout, mais que rien ne marche. La pratique, c'est quand tout marche, mais qu'on ne sait pas pourquoi. En informatique, la théorie et la pratique sont réunies: rien ne marche et on ne sait pas pourquoi!".
    Mais Emmanuel Kant disait aussi : "La théorie sans la pratique est inutile, la pratique sans la théorie est aveugle."

  9. #9
    Membre confirmé Avatar de samaury
    Homme Profil pro
    Chevalier Jedi
    Inscrit en
    Mars 2008
    Messages
    114
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Côte d'Ivoire

    Informations professionnelles :
    Activité : Chevalier Jedi
    Secteur : Finance

    Informations forums :
    Inscription : Mars 2008
    Messages : 114
    Par défaut
    Merci pour ta remarque.
    J'ai implémenté la solution du Dr Who basée sur l'utilisation d'interface.
    Ca correspond bien à ce qu'il me fallait.
    @+

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Changer la visibilité d'un champ à partir d'un autre
    Par mounana199' dans le forum Général JavaScript
    Réponses: 6
    Dernier message: 25/04/2014, 21h05
  2. Changer la visibilité d'un div avec un bouton
    Par Wnejla dans le forum Développement Web avec .NET
    Réponses: 1
    Dernier message: 29/04/2013, 22h33
  3. Edit : Div, changer la visibilité avec display
    Par Wookis dans le forum Général JavaScript
    Réponses: 18
    Dernier message: 19/08/2011, 10h40
  4. visibilité des variables d'un constructeur
    Par med_anis_dk dans le forum Langage
    Réponses: 4
    Dernier message: 06/05/2007, 21h07
  5. Réponses: 8
    Dernier message: 17/04/2007, 11h35

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