Avatar billede jmarkling Nybegynder
12. november 2003 - 10:54 Der er 19 kommentarer og
1 løsning

kun et objekt af typen MyFactory

Hvis man vil være sikker på at der kun bliver oprettet et objekt af en bestemt type, hvad skal man så gøre?

Jeg har 2 ideer, men har ikke testet dem.

1. Man laver konstruktøren protected, og tilgår den via en andet sted i klassen og sætter den til at pege på NULL, og så laver en static fkt, der kan lave objektet færdigt hvis det er oprettet og peger på NULL.

2. Implementering af en exception, der tjekker for andre typer af samme objekt?
Avatar billede arne_v Ekspert
12. november 2003 - 11:01 #1
singleton pattern
Avatar billede arne_v Ekspert
12. november 2003 - 11:05 #2
Det er et standard Gof pattern.

Koden må blivet ligende:

class X
{
  private:
      static X *instance;
      ...
      X()
      {
          ...
      }
  public:
      static X GetInstance()
      {
        if(instance == NULL)
        {
            instance = new X();
        }
        return instance;
      }
      ...
}
Avatar billede arne_v Ekspert
12. november 2003 - 11:05 #3
static X *GetInstance()
Avatar billede arne_v Ekspert
12. november 2003 - 11:05 #4
Og det svarer meget godt til din løsning #1 !
Avatar billede jmarkling Nybegynder
12. november 2003 - 11:10 #5
Ja, det er jeg klar over :D men jeg syntes umiddelbart den klassiske implementering som beskrevet i 1, lyder lidt klodset er der ikke en smartere måde ?
Avatar billede arne_v Ekspert
12. november 2003 - 11:11 #6
Nej.

Det er almindeligt anerkendt som *den* objektorienterede løsning
på problemet.
Avatar billede jmarkling Nybegynder
12. november 2003 - 11:35 #7
Tak for det... :D

Jeg arbejder samtidig med en test klasse der skal teste klassens  fkt'er og members...

Hvordan kunne man evt, lave en test der skulle teste om der eksiterer flere af objekter af samme type, så man kunne bevise man har implementeret sit design-pattern Singleton korrekt...
Ved svar øges point til 150... :D
Avatar billede arne_v Ekspert
12. november 2003 - 11:56 #8
Lade constructor tælle en static counter op og så
teste om den counter er blevet større end 2.
Avatar billede arne_v Ekspert
12. november 2003 - 11:57 #9
Men med en public static GetInstance og en private constructor så kan
det vist næsten ikke gå galt.
Avatar billede arne_v Ekspert
12. november 2003 - 11:57 #10
(det kan det i Java men det er en anden historie)
Avatar billede jmarkling Nybegynder
12. november 2003 - 12:09 #11
Ideen er god nok, med den counter... Jeg vil bare gerne kunne adskille min test klasser fra mine klasser, da jeg bruger cppUnit-test framework.

Du har ret at det ikke kan gå galt og det har jeg selvfølgelig osse testet og får en compiler fejl, hvis jeg prøver at oprette objekter af typen MyFactory uden for dens klasse.

Da jeg ikke kender så meget til MFC klasserne kunne det evt tænkes at der var nogle fkt der kunne tilgå alle aktive objekter i et bestemt scope eller lign.

40 points gives hvis det er ok?
Avatar billede jmarkling Nybegynder
12. november 2003 - 12:10 #12
BTW, hvorfor kan det gå galt i java? Den historie vil jeg da gerne høre, :D
Avatar billede arne_v Ekspert
12. november 2003 - 12:12 #13
Den statisk counter behøver jo ikke lige i denne klasse, men
kan sagtens ligge i en separat test klasse.

Eller som en god gammeldags C style global variabel !
Avatar billede arne_v Ekspert
12. november 2003 - 12:13 #14
Jeg mener ikke at du kan iterere over objekter i almindelig C++.

(der må være noget i .NET managed C++ men det er nok en anden historie)
Avatar billede arne_v Ekspert
12. november 2003 - 12:16 #15
Den lille finesse i Java er at en klasse er identificeret ved
navn (inkl. pakke) *og* classloader.

Det betyder at man godt kan loade 2 forkomster af en singleton, hvis
de loades af forskellig classloader.

Ikke noget problem i normale J2SE applikationer.

Men i J2EE sammenhæng skal man lige nærlæse docs om app-serverens
brug af class loader.
Avatar billede driis Nybegynder
12. november 2003 - 12:17 #16
citat: "er der ikke en smartere måde ?"

Man kan diskutere, om det er smartere, men i de fleste tilfælde hvor jeg skal bruge Singleton pattern, plejer jeg at bruge flg. template klasse Singleton. Ved at bruge den er jeg sikker på at det bliver lavet på samme måde hver gang, og jeg slipper for at have implementationen af det Singleton-specifikke til at ligge i de Singleton klasser jeg bruger:

#ifndef SINGLETON_H
#define SINGLETON_H

template<typename T>
class Singleton
{
public:
    static T * object()                // returnerer pointer til objektet.
    {
        if ( m_obj == 0 )
        {
            try
            {
                m_obj = new T;
                if ( m_obj == 0 ) throw bad_alloc();   
            }                                           
                                                       
            catch (...)
            {
                exit(1) ;
            }
        }           
        return m_obj ;
    }       

    static void destroyObject()        // destruerer objektet. Skal bruges varsomt.
    {
        if ( m_obj )
            delete m_obj;
        m_obj = 0;
    }
protected:
    Singleton(){}           
    virtual ~Singleton(){}
private:
    static T * m_obj;
};

// initiering af static medlem
template<typename T>
T* Singleton<T>::m_obj = 0 ;

#endif


En klasse, der skal bruge ovenstående erklæres så sådan:
#include "singleton.h"

class c1 : public Singleton<c1>
{
    friend class Singleton<c1>;
public:
    int get();
    void set(int value);
private:
    int t;
    c1(){}
    ~c1(){}
};
Avatar billede jmarkling Nybegynder
12. november 2003 - 12:26 #17
go' ide, med den template klasse driis, det vil jeg kigge på, hvis tiden ikke løber fra mig...

Arne:
I J2EE tror måske det kan være en fordel at man kan bryde singleton-pattern i visse tilfælde men det skal jeg ikke gøre mig klog på, har ikke arbejdt så meget med det...
Avatar billede arne_v Ekspert
12. november 2003 - 12:31 #18
Det er lavet af andre årsager som bare har den effekt. Man kan iøvrigt sagtens
kode det i en J2SE applikation også, men man kommer jo ikke til at oprette
egne class loader ved et uheld. I J2EE er det ens app-server som opretter
de class loader og man er måske ikke opmærksom på det.
Avatar billede jmarkling Nybegynder
12. november 2003 - 14:41 #19
ok, dvs. at hvis man implementere singleton i sin J2EE server app, så kan med fordel lave en counter i sin konstuktør, og hvis man så bruger Junit test så teste om den er større end 1.
Avatar billede arne_v Ekspert
12. november 2003 - 14:46 #20
Næ fordi hvordan sikrer du dig at der ikke bliver 2 forekomster
af counter'en ?

:-)

Det er mere et spørgsmål om at vide hvordan en given app-server
opfører sig.
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
Kurser inden for grundlæggende programmering

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester