Reputation: 339
I'm new to objected-oriented design and I was hoping I could get some advice regarding a better way to design this project.
I have started with a FooSequence class which should initialize and store a sequence of Foo objects in a vector. I would like to be able to modify and delete the Foo objects from this sequence. That is, apply a number of algorithms to process the entire sequence of Foos, and delete poor-quality Foos from this sequence.
I'm not sure how I should interface FooSequence with a class that processes the Foo objects. If anyone could elaborate on relevant design patterns and pitfalls, I would greatly appreciate it.
I suppose I could:
a) Expand the scope of FooSequence and rename to something like FooProcessor where the member functions of FooProcessor will process member vSequence_
b) Provide accessor and mutator functions to allow read-write access to Foo objects. Use another class (FooProcessor) to modify and delete Foo objects from FooSequence. I'm not sure how this should be interfaced.
//A simplified header of the FooSequence class
class FooSequence {
public:
FooSequence(const std::string &sequence_directory);
~FooSequence();
//To process the sequence, another class must know the capacity of the vector
//I'm not sure if interfacing to std::vector member functions makes much sense
std::size_t getSize() const { return vSequence_.size(); }
//Should I use an accessor that returns a non-const reference??
//In this case, Why not just make the vector public?
std::vector<std::shared_ptr<Foo>> getFoo;
//Return a non-const reference to individual Foo in the sequence??
//This doesn't help iterate over the sequence unless size of vector is known
std::shared_ptr<Foo>& operator[] (std::size_t index) {
return vSequence_[index];
}
private:
const std::string directory_;
std::vector<std::shared_ptr<Foo>> vSequence_;
FooSequence(const FooSequence &);
void operator=(const FooSequence &);
};
I've tried consulting Design Patterns by the GoF but I think it is too advanced for me just yet. Any advice would be tremendously appreciated.
Edit: While I think this question should have a general answer regarding object-oriented design, I thought I should clarify that I am looking to interface an ImageSequence class with OpenCV. I am wondering about which strategies or designs I can use to best interface ImageSequence with other classes
Upvotes: 2
Views: 239
Reputation: 39796
i doubt, that you need that class at all.
in real life, you'd have a vector<Mat>
(not a vector<shared_ptr<Mat>>
, since Mat already acts as a smartpointer) and call it a day.
Upvotes: 1
Reputation:
Depending on what kind of processing you need to do on your Foo objects, I believe a simple approach of just having an std::vector<std::shared_ptr<Foo>>
in conjunction with standard algorithm calls from the STL could be enough.
There is a lot you can do with the STL:
And all these algorithms are available to you for use on std::vector
because the standard containers and algorithms are designed to work together.
Have a look at the list of algorithms from cppreference:
General Design Guidelines (in response to your edit)
Keep it simple. The simpler your design is, the easier it will be to maintain your program. If your sequence of images can be represented as a simple vector, do it. You can then have other functions/classes operate on that vector by iterating over the images and processing them.
A simple ranged for works here:
for (auto& myImage: myImageVector) {
// Process my image here
}
Upvotes: 2
Reputation: 255
for_each is a construct which allows you to apply a custom function to each element in the container.
For example in your case:
myCustomFunction ( Foo& fooObj)
{
//do something with the foo object
}
now you can call
for_each(vSequence_.begin(),vSequence_.end(),myCustomFunction)
This statement will execute myCustomFunction
for each element in the sequence.
This is not a design advice per say , but in the context of your point a , A FooProcessor
can use for_each
whenever batch processing is required on all the objects.
Upvotes: 1