我目前正在為SQL資料庫表構建一個介面。我目前的類層次結構是這樣的,列出了一些基本的方法和變數:
我的類層次結構是這樣的。
class AbstractTable
{
public:
AbstractTable(QString tableName)。
void addRow(); //它對tableName和colNames進行操作。
private。
const QString tableName。
const QStringList colNames;
//...還有一些,例如:
const QString identificationCollumn;
}
class ProductsTable : public AbstractTable
{
ProductsTable()。
}
class UsersTable: public AbstractTable
{
UsersTable()。
}
重點是,AbstractTable::tableName和AbstractTable::colNames在物件創建時被初始化,并且它在特定的xxxTable建構式中被設定。還有一些其他的常量變數。
現在,我的表在整個程式中擁有大量的實體(而且我無法減少,因為有些功能是基于背景關系的),我希望減少代碼中存在的冗余度。我想到的第一個想法是讓AbstractTable::tableName和AbstractTable::colNames都變成靜態的,但是這將為所有的類只引入一個欄位(我需要為每個子型別別引入一個欄位)。我將不得不從AbstractTable中洗掉tableName和colNames的初始化,并將其移到所有繼承自AbstractTable的類中 - 然后我將能夠標記它為static。這并沒有真正解決問題,因為一個方法addRow應該能夠對tableName和colNames進行操作。它可以通過制定一個虛擬方法virtual QString AbstractTable::getTableName()來解決,該方法將在每個子類中實作(即ProductsTable::getTableName()將回傳一個值為 "products "的靜態域)。但是下一點說明了為什么這不是一個解決方案:
最后,我想說的是,我不知道該怎么做。
最后,我想讓每個表的方法addRow()成為靜態的,所以對ProductsTable::addRow()的呼叫將向名為Products的表添加一行,這似乎有必要在每個子類中實作,這將產生大量的復制粘貼到每個子類。
看起來我必須將所有的欄位移到子類中,讓父類毫無意義。tableName和colNames將不得不在子類中實作,盡管這些變數在每個子類中都是相同的,addRow()需要被移到子類中,因為對i.e.的呼叫。 例如:ProductsTable::addRow()需要向Products添加行,而UsersTable::addRow()需要向users添加行。
tableName和colNames的意義在于讓抽象類發揮作用。所以我可以實作一個指令q.exec("SELECT(" colNames.join(',') ") FROM " tableName);,這個解決方案將使在每個子類中實作addRow的邏輯使我的整個結構毫無意義,因為ProductsTable::select(),可以直接呼叫q. exec("SELECT (a,b,c,d,e) FROM Products"); - 因為colNames和tableName是不變的。
在C 中是否有辦法解決這個問題,同時保留父類的實作,因為它對所有子類來說是通用的?
uj5u.com熱心網友回復:
一個簡單的方法是將特定于實體的行為和所有實體共享的行為分成兩個類,也就是引入一個額外的間接性。
struct TableDescriptor {
std::string name;
std::vector<std::string> cols;
};
class AbstractTable {
protected:
AbstractTable(const TableDescriptor& descriptor)
: descriptor(descriptor)
{
// Feel free to change to your prefered way of storing refs if you feel uncomfortable with storing const refs.
//e.g shared_ptr or theirlike。
//如果你想修改這里的描述符,只需傳遞一個普通的參考而不是const ref。
}
private:
const TableDescriptor& descriptor; //x64上每個實體8位元組。
};
class UserTable : public AbstractTable {
static TableDescriptor user_desc;
public:
UserTable()
: AbstractTable(user_desc)
{
}
};
TableDescriptor UserTable::user_desc{"user_table", {"id", "name"}}。
如果每個表有一些共同的行,它們可以在TableDescriptor ctor中自動添加,以防止不必要的復制粘貼。
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/320085.html
標籤:
