對資料操作封裝的一點心得

2021-05-21 20:48:18 字數 2287 閱讀 2964

假設快取中資料的格式如下所示:

id | name level exp time

下面,我們考慮對資料操作進行封裝,先定義乙個類

class ccachedata;

在對資料進行操作時,可能需要讀寫name,於是我們寫了乙個介面,這個介面會實時更新快取

class ccachedata

setname(string &name);

由於業務需要,我們需要乙個介面更新exp,於是又多了乙個介面 

class ccachedata

setname(string &name);

setexp(int exp);

由於業務需要,我們需要乙個介面更新exp的同時,更新time,於是又多了乙個介面

class ccachedata

setname(string &name);

setexp(int exp);

setexp(int exp, int time);

由於業務需要,我們需要乙個介面更新level,於是又多了乙個介面

class ccachedata

setname(string &name);

setexp(int exp);

setexp(int exp, int time);

setlevel(int level);

由於業務需要,我們需要乙個介面更新level的同時,更新time,於是又多了乙個介面

class ccachedata

setname(string &name);

setexp(int exp);

setexp(int exp, int time);

setlevel(int level);

setlevel(int level, int time);

由於業務需要,我們需要乙個介面 ...

上面的方式,有幾個弊端:

1.介面會隨著業務不斷增加

2.每次更新都會更新資料來源,開銷比較大,如果業務需要多次更新時,不能保證原子操作

於是,我們想了乙個辦法,用乙個結構體把資料封裝起來,然後定義讀寫介面,如下所示:

class ccachedata

struct stdata{

int id;

string name;

int exp;

int level;

int time;

get(stdata &data);

set(stdata &data);

上面的方式業務簡單而且清晰,也解決了第一種封裝方式的問題,但存在安全性的問題。

比如,乙個呼叫者,可能在業務邏輯中多次呼叫,在外部多次修改結構體,很有可能會不小心修改了不應該改的字段,如不小心賦了下初值等,這樣set的時候會直接回寫,資料就會出錯。

於是我們想到一種更好的方式,暴露給呼叫者的只有介面,而資料結構本身做為乙個成員變數儲存在類中,如下所示:

class ccachedata

struct stdata{

int id;

string name;

int exp;

int level;

int time;

public: 

query(int id);

commit();

setname(string &name);

string getname();

setexp(int exp);

int getexp();

setlevel(int level);

int getlevel();

settime(int time);

int gettime();

private:

stdata m_data;

這樣,每次呼叫時先query,把資料讀出,並給m_data賦值,然後,可以多次呼叫get和set介面,如果有set過的話,最後只要呼叫commit介面,就可提交,這種方式有幾個優點:

1.保證了原子性,無論是讀或寫幾個字段,都只要兩次操作即可完成

2.保證了類成員資料安全,封裝等級比較高

3.資料結構調整時(比如新增乙個flag欄位),由於暴露給上層的只是介面,所以呼叫者**無需修改

總結:對快取或資料庫資料操作進行封裝時,一定要注意原子性、通用性和可擴充套件性,最好給上層提供統一的介面類或實現,這樣,才能保證**不會隨業務複雜性增加而快速暴漲,同時也能保證**的清晰與易用性。

上面的封裝採用了facade模式,其實設計模式在編碼中處處可以體現,這也對我們開發人員提出更高的要求,如果能合理、適度的使用設計模式,使自己的**更簡潔、更優美。

SQL一點心得

sql語句將所有 stock 表裡的 縮寫 led甲 替換改寫成 led刷 update dbo stock set 縮寫 replace 縮寫 led甲 led刷 where 縮寫 like led甲 go字首 update mytable set myfield replace myfield,...

Cell myCell一點心得

ctor initializer形如 cell cell mvalue 0 mstring ctor initializer,能在建立資料成員的同時賦初值 1.const方法的工作原理是將方法內用到的資料成員都標記為const引用。因此試圖修改資料成員時,編譯器報錯。2.用explicit關鍵字標記...

openjudge 一點心得

031 校門外的樹 總時間限制 1000ms 記憶體限制 65536kb 描述某校大門外長度為l的馬路上有一排樹,每兩棵相鄰的樹之間的間隔都是1公尺。我們可以把馬路看成乙個數軸,馬路的一端在數軸0的位置,另一端在l的位置 數軸上的每個整數點,即0,1,2,l,都種有一棵樹。由於馬路上有一些區域要用來...