I have a binary file containing rules. I parse these rules into objects and scan files against them. My current object model is like so:
struct TypeARule
{
// rule internals
};
struct TypeBRule
{
// rule internals
};
struct TypeCRule
{
// rule internals
};
struct RuleDatabase
{
vector<TypeARule> TypeA;
vector<TypeBRule> TypeB;
vector<TypeCRule> TypeC;
};
class RuleParser
{
public:
bool ParseFile(const string& path, RuleDatabase& database)
{
// open file, read records from file, generate objects from records, add objects to database
}
private:
// misc helper methods
};
class RuleScanner
{
public:
bool ScanFile(const string& path, const RuleDatabase& database)
{
if(ScanTypeA(path, database))
{
return true;
}
if(ScanTypeB(path, database))
{
return true;
}
if(ScanTypeC(path, database))
{
return true;
}
return false;
}
private:
bool ScanTypeA(const string& path, const RuleDatabase& database)
{
for(const auto& rule : database.TypeA)
{
if (rule matches path))
{
return true;
}
}
return false;
}
bool ScanTypeB(const string& path, const RuleDatabase& database)
{
for(const auto& rule : database.TypeB)
{
if (rule matches path))
{
return true;
}
}
return false;
}
bool ScanTypeC(const string& path, const RuleDatabase& database)
{
for(const auto& rule : database.TypeA)
{
if (rule matches path))
{
return true;
}
}
return false;
}
};
class Client
{
public:
bool Initialize(const string& path)
{
RuleParser parser;
return parser.ParseFile(path, m_database);
}
bool ScanFile(const string& path)
{
RuleScanner scanner;
return scanner.ScanFile(path, m_database);
}
void Cleanup()
{
// cleanup m_database
}
private:
RuleDatabase m_database;
};
I understand dependency injection would help with testing the Client class (by passing references to mock RuleParser and RuleScanner objects to its constructor). But what would I need to do to be able to unit test the RuleParser and RuleScanner classes? Dependency injection won't work in the current model since RuleDatabase is a dumb object used to store other objects. My initial thought is to modify RuleDatabase to hide its data members and provide public methods to operate on them, such as ParseTypeA(), ParseTypeB(), ScanTypeA(), ScanTypeB(). However, that seems to me to be blurring the lines between class responsibilities (e.g. RuleParser should do all the parsing work and RuleScanner should do all the scanning work). Is there a cleaner way to do this?
Aucun commentaire:
Enregistrer un commentaire