I have a DBwrapper that I use for all my SQL queries. So far its worked out quite nicely. Now I just ran into a bit of a problem when implementing a transaction class.
class Transaction{
public:
int TID, UID, MID, DueDate;
Transaction(int ID, int UID, int MID) : ID(ID), UID(UID), MID(MID) { checkIfOverDue(); }
createTransaction() {DBwrapper::addTransaction(UID, MID, DueDate);}
modifyTransaction() {DBwrapper::modifyTransaction(ID, DueDate);}
...
}
class DBwrapper{
public:
/* various functions for user and composite classes */
void getTransactions(int UID, std::list<Transaction*>& v)
{
try { // Open DB file in read-only mode
SQLite::Database db("library.db3"); // SQLite::OPEN_READONLY
SQLite::Statement query(db, "SELECT * FROM transactions WHERE UID = :UID ORDER BY TID;");
query.bind(":UID", UID);
while (query.executeStep())
{
v.push_back( new Transaction(query.getColumn("ID"), /* etc etc */ ));
}
}
catch (std::exception& e) {std::cout << "ERROR!" << std::endl;}
}
}
So as you can see, my Transaction class has methods that reference the DBwrapper class to keep the SQL encapsulated to that class but my DBwrapper now has a method that references the Transaction class thereby creating a circular reference.
Any thoughts on how I could or should go about resolving this? For the moment, I put getTransactions in a Library class, but that breaks the SQL separation Im aiming for and I have to make DBfile public for it to work.
Im thinking that if I want to keep the general style of my implementation, that I have to create an abstract transaction class and accept a pointer to that in getTransactions. Other than that, the factory-pattern would probably solve this too, though to be honest, Im still wrapping my head around that design pattern.
Aucun commentaire:
Enregistrer un commentaire