Lab 13-2: Template Method

   
¹ê²ß¥Ø¼Ð ½m²ß¹B¥Î Template Method ³oºØ³]­p¼ËªO (Design Pattern) ¨Ï±o³nÅé³]­p¤H­û¥i¥H¾A·í¦a¤À¤u (¼Ò²Õ¤§¶¡¾A·íªº¤À¤u)

½m²ß¹B¥ÎÄ~©Ó¬[ºc¨Óµo´§¦h«¬ªº¥\¯à (¦P®É¹ê²{ OCP, Open-Closed Principle)
   
²¤¶ ¬Ý°_¨Ó»yªk²³æªºÄ~©Ó¡A ¹ï©ó«Ü¦hªì¾ÇªÌ¨ä¹ê³£¬O¹ÚÅâ¡A ®Ú¥»¤£ª¾¹D«ç¼Ë¥Î¤~¯àµo´§¥¦ªº¥\¯à¡A ÁÙ±`±`·|°µ¥X¤£¾A·íªºÄ~©Ó (Improper inheritance, ¥i¥H¥Î Liskov Substitution Principle, local copy ¨ÓÀËÅç)

¹ê»Ú¤WÄ~©Ó»P¦h«¬¥i¥H¨Ï§Aªº³]­p«D±`²½m¡A ¦³«Ü¦nªºÂX¥R©Ê¡A ¹L¥h¤G¤Q¦h¦~¨Ó¦³³\¦h¸g¨åªº³]­p¡A §Ú­ÌºÙ¥¦­Ì¬° ³]­p¼ËªO (Design Pattern)¡A ¼ô±x³o¨ÇªF¦è¥H«á¡A §A·|¦³·Q¹³¤£¨ìªº³nÅé³]­p¥\¤O¡A ³o¸Ì§Ú­Ì¥ý¬Ý¤@¤U³o¤@­Ó±`¥Îªº Template Method ³]­p¼ËªO

³o­Ó Template Method ¼ËªO¨ä¹ê¤]¥i¥H»¡¬O²{¦b«Ü¦h Framework ³]­p·§©ÀªºÁY¤pª©¡A §Ú­Ì¦b«e­± Mandelbrot ¹ê²ß¸Ì¾Þ§@¹L MFC ªº Framework¡A §A¬Ý¨ì§Ú¥i¥H¦b¤£¨ì¤@¤ÀÄÁªº®É¶¡¸Ì´N»s§@§¹¤@­Ó¼Ð·Çªºµøµ¡µ{¦¡¤¶­±¡A ¾Ö¦³¿ï³æ¡B¤u¨ã¦C¡Bª¬ºA¦C¡B¶}ÃöÀɮסB¦C¦L¡B¹wÄý¦C¦L¡Bø¹Ï»P­«Ã¸µ¥µ¥¥\¯à¡A ³o¨Ç¥\¯à¦pªG­n§A¾ÌÂÇ Windows API ¥h§¹¦¨ªº¸Ü¡A ­Ó­Ó³£»Ý­n³\¦hªºµ{¦¡½X¡A ¦ý¬O Framework ¸Ì³o¨Ç¥\¯à¨Æ¥ý³£À°§A°µ¦n¤F¡A §A¥u»Ý­n§â§A³]­pªº¥\¯à¼g¦b§A·s¼WªºÃþ§O¸Ì´N¥i¥H¨³³t±o¨ì§A·Q­nªºÀ³¥Îµ{¦¡ (¤£»Ý­n§ó§ï¥ô¦ó Framework ¸Ìªºµ{¦¡½X)¡C §Aµo²{§A©M Microsoft ¼ô±xµøµ¡¬É­±ªº¤uµ{®v¥¿¦b¤À¤u¡A §A­t³d§A¦Û¤vªºµ{¦¡³¡¥÷¡A ¥L­Ì­t³dµøµ¡¬É­±Ácº¾ªº²Ó¸`¡C

¦b Mandelbrot ¨º­Ó½d¨Ò¸Ì¡A §Ú¤]§â»Ý­nªºÃ¸¹Ï©M¨Ï¥ÎªÌ¤¶­±ªº¥\¯à³£¥ý°µ¦n¡A §A¥u»Ý­n­×§ï Mandelbrot Ãþ§O¡A ¹ê§@¥¦ªº´X­Ó¦¨­û¨ç¦¡´N°÷¤F¡A §A¤£¥Î¤Ó¹L¾Þ¤ß³o¨Ç¨ç¦¡¹ê»Ú¤W¬O«ç¼Ë¹B¥Îªº¡C §Ú©M§A¤§¶¡¦³¾A·íªº¤À¤u¡A ¤£¹L¦b¨º­Ó¹ê²ß¸Ì¡A ¤À¤uªº¤èªk¬O«Ü¦MÀIªº¡A §Ú§â Mandelbrot Ãþ§Oªºµ{¦¡Àɮת½±µµ¹§A­×§ï¡A ¦pªG§A§ï¿ù¤F¡A ¬Æ¦Ü§â§Ú­ì¥ý¼g¦n¡B´ú¸Õ¦nªºÃ¸¹Ï©Î¬O¨Ï¥ÎªÌ¤¶­±¥\¯à§ï±¼¤F¡A §A·|»¡³£¬O§Ú¼gªºµ{¦¡ªº¿ù...§ÚÁٻݭnÀ°§A°»¿ù... ³o¬O«Üµh­Wªº¡A ¦b¤À¤uªº®É­Ô·|¾É­P¨â­Ó¤Hªº³d¥ô¤£²M·¡¡A «Ü®e©ö¤¬¬ÛÃhºÃ«ü³d...

©Ò¥H²{¦b¦³¤@­Ó·sªº°ÝÃD¡G ¯à¤£¯à¤£ª½±µ­×§ï§Ú¼g¦nªº Mandelbrot Ãþ§O¡A ¬Æ¦Ü§Ú®Ú¥»¤£§â Mandelbrot.cpp µ¹§A¡A ¦Ó¹F¨ì¦P¼Ëªº¥\¯à©O? µª®×´N¬OÄ~©Ó©M¦h«¬

Template Method °ò¥»¤W´N¬O¹F¨ì³o¼Ëªº¥\¯àªº¤@­Ó³]­p¼ËªO¡A ¥¦ªººë¯«¬O "¦b¤÷Ãþ§O¸Ì³]­p¸Ì³B²z¤jºõ©M³B²z­ì«h¡A ¦b¤lÃþ§O¸Ì´£¨Ñ¨ãÅ餺®e"¡A °Ñ¦Ò¤U¹Ï¡A ¦b©â¶H¤÷Ãþ§O AbstractClass ªº templateMethod ¦¨­û¨ç¦¡¤¤´y­z§¹¾ãªººtºâªk¡A ¦b¤lÃþ§O¤¤¤£»Ý­n¦A±Ô­zºtºâªk«h¡C

½Ðª`·N¤@­Ó©â¶HÃþ§O (±×Åé¦r) ¨S¦³¿ìªk¥Î¨Ó«Ø¥ßª«¥ó­ÓÅé¡A ¨º»ò¥¦¨s³º¦³¤°»ò¥Î©O? ³o­Ó¹ê²ßªº¡uTemplate Method ¼ËªO¡vÅý§A¬Ý¨ì¤@­Ó©â¶HÃþ§O¥i¥H¨M©w¤èªkªº¦WºÙ (method1, method2, method3)¡A ¥i¥H¨M©w³o¨Ç¤èªkªº¨Ï¥Î¤èªk (templateMethod)¡A °ò¥»¤W¥i¥H¨M©w¨C¤@­Ó¤èªk¬Û¹ï©ó templateMethod ¸Ì­±´y­zªººtºâªkªº "³d¥ô"¡C

¨BÆJ¤@ ½Ð°Ñ¦Ò¤U­±ªº³o­ÓÃþ§O©w¸q
    class DataGroup
    {
    public:
        DataGroup(int numberOfNames, char *names[], 
                  int sizeOfArray, 
                  int numberOfData, double dataArray[]);
        virtual ~DataGroup();
        void serialize(bool bOutput=true);
    private:
        virtual void openStream(bool bOutput) = 0;
        virtual void closeStream(bool bOutput) = 0;
        virtual void writeByte(unsigned char data) = 0;
        char  **m_names;
        int     m_numberOfNames;
        double *m_dataArray;
        int     m_dataArraySize;
        int     m_numberOfData;
    };
    
    DataGroup::DataGroup(int numberOfNames, char *names[], 
                         int sizeOfArray, 
                         int numberOfData, double dataArray[])
        : m_numberOfNames(numberOfNames), 
          m_dataArraySize(sizeOfArray), 
          m_numberOfData(numberOfData)
    {
        int i, len;
        m_names = new char*[numberOfNames];
        for (i=0; i<numberOfNames; i++)
        {
            len = strlen(names[i]);
            m_names[i] = new char[len+1];
            strcpy(m_names[i], names[i]);
        }
        m_dataArray = new double[m_dataArraySize];
        for (i=0; i<numberOfData; i++)
            m_dataArray[i] = dataArray[i];
    }
    
    DataGroup::~DataGroup()
    {
        int i;
        for (i=0; i<m_numberOfNames; i++)
            delete[] m_names[i];
        delete[] m_names;
        delete[] m_dataArray;
    }
¤W­±³o­Ó DataGroup Ãþ§Oªº¸ê®Æ¦¨­û³]­p¬Ý°_¨Ó¦³¤@ÂIÂI½ÆÂø¡A ¬Û«H³]­p³o­ÓÃþ§Oªº¤H¤~·|³Ì²M·¡­þ¤@­Ó«ü¼Ð©Ò¥Nªíªº¸ê®Æµ²ºc¦³¤°»ò¼Ëªº¥\¯à¡A ¨ä¤¤ serialize() ¬É­±¥Nªí­n§â³o­ÓÃþ§Oªºª«¥ó¦s¨ì¥ÃÄòªº (persistent) ´CÅé¤W¡A ¨Ò¦p¡GºÏºÐÀɮסB¸ê®Æ®w¡B³øªí¯È¡BºÏ±a¡B»·ºÝ¸ê®Æ¦øªA¥D¾÷µ¥µ¥¡A ©M³o¨Ç¹ê»ÚÀx¦s¸ê®Æªº¨t²Î¥´¥æ¹D¦³®É¬O«Ü³Â·Ðªº¡A ³]­p³o­ÓÃþ§Oªº¶}µo¤H­û¥D­n±Mª`©ó³o¨Ç¸ê®Æ¹ï©óÀ³¥Î¨t²Îªº¤ä´©¡A ¤]³\¨Ã¤£²M·¡¸Ó¦p¦ó§â¸ê®Æ¦s©ñ¨ì¹ê»ÚÀx¦s¸ê®Æªº¨t²Î¤W¡A ¥L§Æ±æ§â³o¨Ç¨Æ±¡¯dµ¹¼ô±x³o¨Ç¥\¯àªº¦P¨Æ¥h³]­p¡A ¦ý¬O¥Lªº¦P¨Æ¤S¤£§Æ±æ¤F¸Ñ³o­ÓÃþ§O¤º¸ê®Æªº³]­p²Ó¸`¡A ·íµM³o¼Ë¤~¯à°÷ºû«ù DataGroup ­ì©l³]­pªÌ¥H«á§ó§ï¸ê®Æ³]­pªº¼u©Ê¡A ¸Ó¦p¦ó³]­p¤~¯à¨Ï¨â­Ó¤H§¹¬ü¦a¤À¤u©O?

¦b³]­p¤§«e¡A½Ð¥ý¶}±Ò¤@­Ó±M®×¡A §â¤W­zªºµ{¦¡½X½Æ»s¨ì DataGroup.h ©M DataGroup.cpp ¸Ì¡A ³æ¿W½sĶ DataGroup.cpp ½T©w»yªk¨S¦³¿ù»~¡C

¨BÆJ¤G ½Ð¬Ý DataGroup Ãþ§Oªº serialize() ¨ç¦¡³]­p¡G
    void DataGroup::serialize(bool bOutput)
    {
        int i, j, len;
        unsigned char *ptr;

        openStream(bOutput);
        if (bOutput) // output
        {
            ptr = (unsigned char *) &m_numberOfNames;
            for (i=0; i<sizeof(int); i++)
                writeByte(ptr[i]);
        
            for (i=0; i<m_numberOfNames; i++)
            {
                len = strlen(m_names[i]);
                ptr = (unsigned char *) &len;
                for (j=0; j<sizeof(int); j++)
                    writeByte(ptr[j]);
                for (j=0; j<len; j++)
                    writeByte(m_names[i][j]);
            }
        
            ptr = (unsigned char *) &m_numberOfData;
            for (i=0; i<sizeof(int); i++)
                writeByte(ptr[i]);
        
            ptr = (unsigned char *) &m_dataArraySize;
            for (i=0; i<sizeof(int); i++)
                writeByte(ptr[i]);
        
            for (i=0; i<m_numberOfData; i++)
            {
                ptr = (unsigned char *) &m_dataArray[i];
                for (j=0; j<sizeof(double); j++)
                    writeByte(ptr[j]);
            }
        }
        else // input
        {
            freeMemory();
            ptr = (unsigned char *) &m_numberOfNames;
            for (i=0; i<sizeof(int); i++)
                ptr[i] = readByte();
            m_names = new char*[m_numberOfNames];
            for (i=0; i<m_numberOfNames; i++)
            {
                ptr = (unsigned char *) &len;
                for (j=0; j<sizeof(int); j++)
                    ptr[j] = readByte();
                m_names[i] = new char[len+1];
                for (j=0; j<len; j++)
                    m_names[i][j] = readByte();
                m_names[i][len] = 0;
            }
            ...
        }
    
        closeStream(bOutput);
    }
³o­Ó¨ç¦¡ùØ­±¤j³¡¤À¥\¯à³£©M DataGroup ¦Û¤vªº¸ê®Æµ²ºcªº²Ó¸`¦³Ãö¡A ¦]¦¹²zÀ³¥Ñ¼¶¼g DataGroup ªºµ{¦¡³]­pªÌ¨Ó¼g¡A ¦ý¬O§A¬Ý¨ì¥L¦b¹ê»Ú¿é¥X®É¹B¥Î¤@­ÓÁÙ¨S¦³©w¸qªº¨ç¦¡ writeByte(unsigned char) ¨Ó¹ê§@¡A ¦P®É¦bªì©l¤Æ¿é¥X¸Ë¸m®É¹B¥Î openStream(bool) ¨Ó¹ê§@¡A ¦bÃö³¬¿é¥X¸Ë¸m®É¹B¥Î closeStream(bool) ¨Ó¹ê§@¡C ³o¸Ì´N¬O¹B¥Î¦h«¬ªº¾÷¨î¡G ¹ê»Ú¤W°õ¦æ¨ìªº openStream(), closeStream(), writeByte() ¨ç¦¡¬O¦b­l¥ÍÃþ§O¸Ì¤~·|©w¸qªº¡A §Ú­Ì¦b¤W½Ò®É»¡¹L¦h«¬¦b¹B§@®É»Ý­n³z¹L¦h«¬«ü¼Ð©Î¬O¦h«¬°Ñ¦Ò¨Ó¹B§@¡A this «ü¼Ð´N¬O³o¸Ìªº¦h«¬«ü¼Ð¡C

½Ð§¹¦¨ serialize() ¨ç¦¡¸Ì­±¥Ñ¸ê®ÆÀx¦s´C¤¶¿é¤J¸ê®Æªºµ{¦¡ (¬õ¦â ... ªº¦a¤è)¡A §A»Ý­n¦bÃþ§O©w¸q¸Ì©w¸q¤@­Ó¯ÂºéµêÀÀ¨ç¦¡ unsigned char readByte()=0¡A ÂǥѩI¥s³o­Ó¨ç¦¡¨Ó§¹¦¨¿é¤Jªº¥\¯à¡A openStream() ©M closeStream() ¤]¬O¯ÂºéµêÀÀ¨ç¦¡¡A³o¨â­Ó¨ç¦¡³Q©I¥s¨ì®ÉÀ³¸Ó·|®Ú¾Ú bOutput °Ñ¼Æ¨Ó¶}±Ò©Î¬OÃö³¬¿é¥X/¿é¤Jªº¦ê¬y¡A¤W­±³o¤T­Ó¨ç¦¡ªº¤º®e©M¿é¥X©Î¬O¿é¤J¦ê¬yªººØÃþ¦³Ãö¡A¤£»Ý­n¦b DataGroup Ãþ§O¸Ì­±³]­p¡F¤W­± serialize() ¨ç¦¡¸Ì­±ªº¿é¤J¤ñ¿é¥X³Â·Ð¤@ÂIÂI¡A §A»Ý­n§âª«¥óùØ­±­ì¥ýªº°O¾ÐÅé§R°£ (§A¥i¥H§â¤W­±¸Ñºc¤¸¸Ìªºµ{¦¡¼g¨ì¤@­Ó»²§U¨ç¦¡ freeMemory() ¤¤¡A µM«á¦b¸Ñºc¤¸ÁÙ¦³³o­Ó serialize() ¨ç¦¡ªº¿é¤J³¡¥÷©I¥s)¡A ¥t¥~§A¤@©w­n¨Ì·Ó«Øºc¤¸¸Ì°t¸m¸ê®Æªº¤è¦¡°t¸m°O¾ÐÅé¡C

³o­Ó DataGroup Ãþ§O´N§êºt¡utemplate method ¼ËªO¡v¸Ìªº AbstractClass ªº¨¤¦â, DataGroup::serialize() ¨ç¦¡´N§êºt AbstractClass::templateMethod() ªº¨¤¦â, DataGroup::readByte(), DataGroup::writeByte(), DataGroup::opernStream(), DataGroup::closeStream() ´N§êºt AbstractClass::method1(), AbstractClass::method2(), ©Î¬OAbstractClass::method3() ªº¨¤¦â¡C

¨BÆJ¤T ±µ¤U¨Ó½Ð¬Ý¦b¥Dµ{¦¡¸Ì¦p¦ó´ú¸Õ³o­Ó DataGroup Ãþ§Oªº§Ç¦C¤Æ¿é¥X¥\¯à
    void main()
    {
        char *names[] = {"compressor", "o-ring"};
        double darray[] = {1.1, 2.2, 3.3};

        ScreenDataGroup scrobj(2, names, 5, 3, darray);
        TextFileDataGroup tfobj(2, names, 5, 3, darray, "DataGroup.txt");
        BinaryFileDataGroup bfobj(2, names, 5, 3, darray, "DataGroup.dat");
        
        scrobj.serialize();
        
        tfobj.serialize();
        
        bfobj.serialize();
    }
¥Ñ©ó DataGroup ¸Ì¦³¯ÂºéµêÀÀ¨ç¦¡ (pure virtual function)¡A ©Ò¥H¨S¦³¿ìªkª½±µ²£¥Íª«¥ó¡A ·íµM¦]¬°¨S¦³©w¸q¹ê»Ú¿é¥Xªº¸Ë¸m¡A ©Ò¥H²z©Ò·íµM¦a¨S¦³¿ìªk¹B§@¡A ©Ò¥H¤W­±¦³¥Î¨ì¤T­Ó·sªº­l¥ÍÃþ§O ScreenDataGroup, TextFileDataGroup, BinaryFileDataGroup¡A³o¤T­ÓÃþ§O¤À§O§â¸ê®Æ§Ç¦C¤Æ (serialize) ¨ìÁä½L¿Ã¹õ¡B¤å¦rÀɮסB©M¤G¶i¦ì®æ¦¡ªºÀɮפ¤¡A ±µ¤U¨Ó§A´N­n­t³d³]­p³o¤T­ÓÃþ§O¡C

½Ð¨Ì·Ó¤W­±ªº½d¨Ò»s§@¦n main() ¨ç¦¡¡A ¨Ã¥B¦b¨ç¦¡³Ì«á­±¥[¤J´ú¸Õ¥ÑÀx¦s´CÅéŪ¤Jª«¥óªºµ{¦¡¤ù¬q¡A ¨Ò¦p¡G

    TextFileDataGroup tfobj2("DataGroup.txt");
    tfobj2.serialize(false);  // ¥Ñ DataGroup.txt Àɮפ¤­««Ø tfobj2 ª«¥ó
    ...
¦]¬° DataGroup.txt ¬O«e­±ª«¥ó tfobj ªº¿é¥X¡A©Ò¥H­««Ø¦^¨Óªº tfobj2 À³¸Ó ©M«e­±ªº tfobj ¾Ö¦³¤@¼Ò¤@¼Ëªº¸ê®Æ (µ¥¤@¤U·|§Æ±æ§A¥[¤@­Ó´ú¸Õ¬Ûµ¥ªº¦¨­û, ¹B¥Î assert ½T«O¹B§@ªº¥¿½T©Ê)
¨BÆJ¥| ±µ¤U¨Ó»¡©ú¤@¤U ScreenDataGroup ³o­ÓÃþ§O¸Ì­t³d¦b¿Ã¹õ¤W¿é¥Xªº¥\¯à³]­p
    #include <DataGroup.h>

    class ScreenDataGroup : public DataGroup
    {
    public:
        ScreenDataGroup(int numberOfNames, char *names[], 
                        int sizeOfArray, 
                        int numberOfData, double dataArray[])
            : DataGroup(numberOfNames, names, sizeOfArray, 
                        numberOfData, dataArray) {}
    private:
        void openStream(bool bOutput);
        void closeStream(bool bOutput);
        void writeByte(unsigned char data);
    };
    
    void ScreenDataGroup::openStream(bool)
    {
    }
    
    void ScreenDataGroup::closeStream(bool)
    {
    }
    
    void ScreenDataGroup::writeByte(unsigned char data)
    {
        static int nBytes=0;
    
        int lownibble = data & 0x0F;
        int highnibble = data >> 4;
      
        cout << setw(1) << hex << highnibble;
        cout << setw(1) << hex << lownibble << ' ';
    
        nBytes = ++nBytes % 16;
        if (nBytes == 0)
            cout << endl;
    }

½Ð·s¼W¥[¤@­ÓÃþ§OÀÉ®× ScreenDataGroup.cpp ©M ScreenDataGroup.h, ©ñ¶i¤W­zªºµ{¦¡½X¡A §AÀ³¸Ó¥i¥H½sĶ¦P®É´ú¸Õ¤@¤U¿Ã¹õ¿é¥Xªº¥\¯à¤F¡A ¥Î¤ßÅé·|¤@¤U¹B¥ÎÄ~©Ó©M¦h«¬¨Ó§¹¦¨ªºµ{¦¡³]­p¤À¤u¾÷¨î!!

½d¨Ò°õ¦æµ{¦¡¡A ³o­Óµ{¦¡°õ¦æ«á¦b¿Ã¹õ¤W·|Åã¥Ü¸ê®Æªº 16 ¶i¦ì¤º®e¡A ÁÙ·|²£¥Í¨â­ÓÀɮסGDataGroup.txt ¸Ì¬O¤å¦r®æ¦¡ªº 16 ¶i¦ì¤º®e¡A DataGroup.dat ¸Ì¬O¤G¶i¦ì®æ¦¡ªº¸ê®Æ¤º®e

±µ¤U¨Ó½Ð¹Á¸Õ¼¶¼gÁä½L¿é¤Jªº³¡¥÷¡A ¤]´N¬OÂл\ unsigned char readByte() ¨ç¦¡¡A¨Ã¥B¼¶¼g ScreenDataGroup() ªº«Øºc¤¸©M DataGroup() ªº«Øºc¤¸¡A­×§ï serialize() ¨ç¦¡¡A®Ú¾Ú if (bOutput) // output «á­±¤j¬A¸¹¸Ì¿é¥Xªº¶¶§Ç¡A¼¶¼g else // input «á­±¤j¬A¸¹¸Ì¿é¤Jªºµ{¦¡½X¡A§â³o¤@¬qµ{¦¡¤¤ writeByte §ï¦¨ readByte¡A¾A·íªº¦a¤è°t¸m°O¾ÐÅé

¤@¶}©l·|¥H¬°´ú¸Õ³o³¡¥÷ªºµ{¦¡½Xªº®É­Ô·|«Üµh­W¡A¦]¬°§A»Ý­nÁä¤J³\¦hªº 16 ¶i¦ì¸ê®Æ¡A¤£¹L´ú¸Õªº®É­Ô¦]¬°§Ú­Ì¥ý¿é¥X¨ì¿Ã¹õ¤W¡A©Ò¥H§A¥i¥H«þ¨©¿Ã¹õ¤W¥X²{ªº¸ê®Æ°µ¬°¿é¤J¨Ó´ú¸Õ¡A¥t¥~³o­Ó¨ç¦¡ªº¤º®e¦b¤U¤@¨BÆJ¤¤¤]·|¥Î¨ì¡A¥ÑÀɮ׸̪½±µÅª¤J³o­Óª«¥óªº¸Ü´N¤£¥Î¾á¤ßÁä¤J³\¦hªº 16 ¶i¦ì¸ê®Æ¤F¡C

³o­Ó¹ê²ß¸Ì§A¬Ý¨ì¤@­ÓÃþ§O¦b»s§@ªº®É­Ô¥i¥H¥u©w¸q private ªº¾Þ§@¬É­±!

¨BÆJ¤­ ½Ð§¹¦¨¤å¦rÀɮ׿é¥X¤J¸Ë¸mªº TextFileDataGroup Ãþ§O¡A ½Ðª`·N¦b«Øºc³o­ÓÃþ§Oª«¥óªº®É«á¡A «Øºc¤¸ªº°Ñ¼Æ¤ñ DataGroup ª«¥ó«Øºc®É¦h¤@­Ó¦r¤¸°}¦C¡A ¤º®e¬O§Ç¦C¤ÆªºÀɮצWºÙ¡A §A¥i¥H¹B¥Î³o­Ó¦WºÙ¥hªì©l¤Æ¿é¥X©Î¬O¿é¤JÀɮצê¬yª«¥ó¡A§A¥i¥H¹B¥Î fstream ©w¸q¤@­Ó¦ê¬yª«¥ó¦¨­û¡A¦p¦¹¥i¥H®Ú¾Ú bOutput ¨M©w¨ì©³¬O¿é¤JªºÀɮצê¬yÁÙ¬O¿é¥XªºÀɮצê¬y¡C

¥t¥~¥Ñ¤å¦rÀɮ׿é¤J DataGroup ª«¥ó®É¡A TextFileDataGroup ª«¥ó«Øºc®É¥u»Ý­nµ¹¤@­ÓÀɮצWºÙ¡A³o®É¥i¥H¦³¨âºØ³]­p¤èªk¡A¤@ºØ¬Oª½±µ¦b«Øºc¤¸¸Ì­±©I¥s serialize(false) ·|³z¹L openStream ªì©l¤Æ¿é¤J¦ê¬yª«¥ó¡A ¨Ã¥B§¹¦¨¾ã­Ó§Ç¦C¤Æªº°Ê§@¡F¥t¥~¤@ºØ«h¬O¦b«Øºc¤¸¸Ì¥u¬O§âÀɮצWºÙ°O¤U¨Ó¡A¥Ñ«È¤áºÝµ{¦¡¨M©w©I¥s serialize(false) ªº®É¾÷¡C

¦³¦P¾Ç´ú¸Õµo²{ VC2005 ¥H«á setw(1) ¦ü¥G¬O¿é¥XÀɮצê¬y ofstream ¤£¤ä´©ªº¤èªk¡A §A¤£¯à¥Î¡A»Ý­n§â¥¦§R°£¡A ¤£¹L¿é¥Xªºµ²ªGÁÙ¬O¹ïªº´N¬O¤F...

¬°¤F¤ñ¹ï¥Ñ¦ê¬y«Øºc°_¨Óªºª«¥ó¸Ìªº¸ê®Æ¬O§_©M­ì¨Óªºª«¥ó¤@¼Ò¤@¼Ë¡A §A¥i¥H¦b DataGroup Ãþ§O¸Ì¼W¥[¤@­Ó bool operator==(DataGroup &) ªº¦¨­û¡A¨Ò¦p¡G

    bool DataGroup::operator==(DataGroup &rhs)
    {
        int i;
        
        if ((m_numberOfNames != rhs.m_numberOfNames) ||
            (m_dataArraySize != rhs.m_dataArraySize) ||
            (m_numberOfData != rhs.m_numberOfData))
           return false;
        for (i=0; i<m_numberOfNames; i++)
            if (strcmp(m_names[i], rhs.m_names[i]) != 0)
                return false;
        for (i=0; i<m_numberOfData; i++)
            if (m_dataArray[i] != rhs.m_dataArray[i])
                return false;
        return true;
    }

½Ðª`·N¤W­±¦b¤ñ¸û m_dataArray[i] ©M rhs.m_dataArray[i] ®É¤£»Ý­n¦³¦Ê¤À»~®t½d³òªº·§©À, ¥u»Ý­n¤ñ¸û¨â­Ó double ¼Æ¦r¸Ì¨C¤@­Ó¦ì¤¸³£§¹¥þ¤@¼Ë!! (½Ðª`·N§Ú­Ì§Ç¦C¤Æ¨ì¿Ã¹õ¤W©Î¬O¤å¦rÀɮ׸̮É, §Ú­Ì¨Ã¨S¦³§â¸ê®ÆÂà´«¦¨¤Q¶i¦ì, ¦pªGÂର¤Q¶i¦ì´N·|¦³»~®t¤F)

µM«á¦b main() ¸Ì­±¥Î¦p¤Uªº¤èªk´ú¸Õ


    char *name[] = {"compressor", "o-ring"};
    double darray[] = {1.1, 2.2, 3.3};
    TextFileDataGroup tfobj(2, name, 5, 3, darray, "DataGroup.txt");
    
    tfobj.serialize();

    TextFileDataGroup tfobj2("DataGroup.txt");

    tfobj2.serialize(false);
   
    assert(tfobj2 == tfobj);
¨BÆJ¤» ½Ð§¹¦¨¤G¶i¦ì®æ¦¡Àɮ׿é¥X¤J¸Ë¸mªº BinaryFileDataGroup Ãþ§O¡A ¦b«Øºc³o­ÓÃþ§Oª«¥óªº®É«á«Øºc¤¸°Ñ¼Æ¤]¬O¤ñ DataGroup ª«¥ó«Øºc®É¦h¤@­Ó¦r¤¸°}¦C¡A ¤º®e¬O§Ç¦C¤ÆªºÀɮצWºÙ¡A ¨ä¥¦³]­p³¡¥÷©M TextFileDataGroup Ãþ¦ü¡A ¦ý¬O readByte() ©M writeByte() ¨ç¦¡¸Ì»Ý­n¹B¥Î istream::read() ©M ostream::write() ¨Ó¹ê§@¡C
¨BÆJ¤C ½Ð§U±ÐÀˬd«á, ±N©Ò§¹¦¨ªº ±M®× (¥u»Ý«O¯d .cpp, .h, .sln ¥H¤Î .vcxproj ÀɮקY¥i; §R°£±¼ .suo, .sdf, .filters, .users, debug\ ¸ê®Æ§X, ¥H¤Î ipch\ ¸ê®Æ§X¤Uªº©Ò¦³¤º®e) À£ÁY°_¨Ó, ¿ï¾Ü Lab13-2 ¤W¶Ç, «á­±ªº¹ê²ß½Òµ{¥i¯à»Ý­n¨Ï¥Î³o¸Ì©Ò§¹¦¨ªºµ{¦¡¡C
«áÄò

½Ð¤@©w­n¥J²Ó«ä¦Ò³o¼Ë¤l¬[ºc¤U¤À¤uªº¦n³B¡A ¦b³o­Ó½d¨Ò¸Ì¼¶¼g­l¥ÍÃþ§Oªº¤uµ{®v§¹¥þ¤£»Ý­nª¾¹D DataGroup ¸Ì¨ì©³¦³¤°»ò¸ê®Æ¡A¨ì©³¬O¥Î¤°»ò¦s©ñ®æ¦¡¡A ¼¶¼g DataGroup Ãþ§Oªº¤uµ{®v¤]¥i¥H±Mª`©ó DataGroup ¤º³¡¸ê®Æªº³]­p¡A ¤£­n¥h·Ð´o«ç¼ËÀx¦sªº²Ó¸`°ÝÃD¡A ¤×¨ä¬O·í¸ê®Æ»Ý­nÀx¦s¨ì»·ºÝªº¸ê®Æ¦øªA¥D¾÷¤W¡A ©Î¬O»Ý­nÀx¦s¨ì®e¿ùªºµwºÐ°}¦C¤¤¡A ³o¨Çª¬ªp¤U§ó¬O¦³¥²­n¤À¤u¦X§@¡A ¨C­Ó¤H­t³d¤@³¡¥÷§Y¥i¡C

OCP, Open-Closed Principle: ³o­Ó¨Ò¤l¤¤ DataGroup ©â¶HÃþ§O¥H¤Î¹B¥Î DataGroup Ãþ§OªºÀ³¥Îµ{¦¡´Nº¡¨¬ Open for extension, closed for modification ªº­ì«h, ¥ô¦ó·sÂX¥Rªº¥\¯à¥u»Ý­n¼W¥[¤@­ÓÄ~©Ó DataGroup ªºÃþ§O´N¥i¥H¤F, §¹¥þ¤£»Ý­n­×§ï DataGroup ¥H¤Î°ò©ó DataGroup ¬É­±³]­pªº«È¤áºÝÀ³¥Îµ{¦¡½X¡C

¦^ C++ ª«¥ó¾É¦Vµ{¦¡³]­p½Òµ{ ­º­¶

»s§@¤é´Á: 05/29/2008 by ¤B°ö¼Ý (Pei-yih Ting)
E-mail: pyting@mail.ntou.edu.tw TEL: 02 24622192x6615
®ü¬v¤j¾Ç ¹q¾÷¸ê°T¾Ç°| ¸ê°T¤uµ{¾Ç¨t Lagoon