面向方法、宏定義、dll庫、面向對象給程序靈活性帶來的好處

從一個網上找的例子說起:

定義了一個ILog接口,用於記錄日誌文件,它有一個對外接口WriteLog用於記錄日誌

這些日誌可以記錄到磁盤上(FileLog)或者數據庫上(DBLog),或者其它的什麼地方;後來,你又發現需要一個StdOutLog,於是你又繼承了一個StdOutLog類。

各種派生類:DBLog, FileLog, StdOutLog不同的Log創建不同的對象。但對於程序來說他們都是ILog,程序中使用該日誌功能的方法都是ILog->WriteLog(),對於日誌類的不同具體實現不影響你客戶端的已有代碼。


版本一

1、如果我們用面向過程的方法,直接針對不同的實現都分別寫一個write函數,eg:void write_dblog()

2、接着,用戶要求改用文件來實現,你又得寫一個write_filelog()函數,關鍵是接下來你得把客戶端程序中所有調用write_dblog的代碼都改成write_filelog()

3、對於write_stdoutlog同樣是上面的問題


版本二

這下,我們感覺相當的不爽,改成用宏定義來實現

#define write_log write_stdoutlog

好了,以後再怎麼改,我們的程序只需要修改宏就好了。


版本三

過了一段時間,用戶老是要頻繁的修改記錄方式,每次修改宏定義後,我們又要重新編譯,

爲了避免重新編譯,我們現在改用dll。我們把不同寫日誌的函數都叫做 write_log,然後不同的dll(db.dll,file.dll,stdout.dll)根據不同需要去實現write_log函數

最後,我們把write_log 這個函數導出。這樣以來,每次用戶要更改記錄方式的時候,我們可以直接根據需要去替換這個dll庫,而不用重新修改甚至重新編譯用戶的代碼。

(感嘆dll的神奇和偉大)


版本四:

又過了一段時間,用戶又提出了許多需求, 我們把他們叫做:function1(),function2(),function3()......function100()

這下麻煩了,由於使用dll,我們需要導出dll中的函數,並用指向函數的指針來記錄他們,100個需求對應100個函數,都要我們在用戶程序中用指針的方式記錄下來,對於這個工作量 我只能表示"呵呵"。

好了,接着改。用面向對象的方法來解決:

創建一個接口

class ILog

{

   virtual void write_log() = 0;

   virtual void function1() = 0;

   virtual void function2() = 0;

   ...

   virtual void function100() = 0;


   

};

然後在DB.dll和 File.dll中,實現這個接口

class DBLog : public ILog

{

   virtual void write_log() {.....};

   virtual void function1() {...};

   virtual void function2() {...};

   ...

   virtual void function100() {.....};

};

class FileLog : public ILog

{

   virtual void write_log() {.....};

   virtual void function1() {...};

   virtual void function2() {...};

   ...

   virtual void function100() {.....};

};


最後,你再讓這些dll文件只導出一個獲取具體實現類的接口: ILog * create_log_object();

,這樣用戶程序裏只需要保存一個,ILog * pLog 類型的指針。

其他的地方只需要寫pLog->write_log() 、pLog->function1() 。。。。。,看到沒有這樣用戶代碼段裏就不需要再去記錄100多個函數指針了。我們程序的靈活性進一步提高!!!!!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章