IAM

OPENSOURCEFAN STUDYING
STUDYINGCOMPUTERSCIENCEANDMATH COMPUTERSCIENCE

Check out the latest superpixel benchmark — Superpixel Benchmark (2016) — and let me know your opinion! @david_stutz
15thOCTOBER2016

SNIPPET

C++

Implementation of Martin Fowler’s example in “Inversion of Control Containers and the Dependency Injection pattern” using GoogleFruit.

movie.hpp
#include <string>

/** \brief Class representing a movie by name and director. 
 * \author David Stutz
 */
class Movie
{
public:
    
    /** \brief Constructor.
     * \param[in] title title of the movie
     * \param[in] director director of the movie
     */
    Movie(std::string title, std::string director) : title(title), director(director)
    {
        
    }
    
    /** \brief Get the movie's title. 
     * \return title of the movie
     */
    std::string getTitle()
    {
        return this->title;
    }
    
    /** \brief Get the directory of the movie.
     * \return the movie's director
     */
    std::string getDirector()
    {
        return this->director;
    }
    
private:
    
    /** \brief Title of the movie. */
    std::string title;
    
    /** \brief Directory of the movie. */
    std::string director;
};
movie_finder.hpp
#include "movie.hpp"

/** \brief Abstract movie finder.
 * \author David Stutz
 */
class MovieFinder
{
public:
    
    /** \brief Find all movies.
     * \param[out] movies list of all found movies
     */
    void virtual findAllMovies(std::list<Movie> &movies) = 0;
};
fixed_list_movie_finder.hpp
#include <list>
#include <fruit/fruit.h>
#include "movie.hpp"
#include "movie_finder.hpp"

using fruit::Injector;

/** \brief Movie finder with a fixed list of movies.
 * \author David Stutz
 */
class FixedListMovieFinder : public MovieFinder
{
public:
    
    /** \brief Default constructor. */
    INJECT(FixedListMovieFinder()) = default;
    
    /** \brief Find all movies.
     * \param[out] movies all found movies
     */
    void findAllMovies(std::list<Movie> &movies)
    {
        movies.clear();
        movies.push_back(Movie("The Shawshank Redemption", "Frank Darabont"));
        movies.push_back(Movie("The Godfather", "Francis Ford Coppola"));
        movies.push_back(Movie("The Dark Knight", "Christopher Nolan"));
    }
};
movie_lister.hpp
#include <list>
#include <fruit/fruit.h>
#include "movie.hpp"
#include "movie_finder.hpp"

/** \brief Abstract movie lister.
 * \author David Stutz
 */
class MovieLister
{
public:
    
    /** \brief Constructor.
     * \param[in] movieFinder underlying movie finder to use
     */
    MovieLister(std::shared_ptr<MovieFinder> movieFinder) : movieFinder(movieFinder)
    {
        this->movieFinder = movieFinder;
    }
    
    /** \brief Get movies directed by the given director.
     * \param[in] directory name of the director
     * \param[out] movies list of movies with given director
     */
    void virtual getMoviesDirectedBy(std::string director, std::list<Movie> &movies) = 0;
    
protected:
    
    /** \brief Underlying movie finder. */
    std::shared_ptr<MovieFinder> movieFinder;
};
simple_movie_lister.hpp
#include <list>
#include <fruit/fruit.h>
#include "movie.hpp"
#include "movie_lister.hpp"
#include "movie_finder.hpp"

using fruit::Injector;

/** \brief List movies with specific criteria.
 * \author David Stutz
 */
class SimpleMovieLister : public MovieLister
{
public:
    
    /** \brief Constructor with the dependency on MovieFinder being injected.
     * \param[in] movieFinder shared pointer to movie finder
     */
    INJECT(SimpleMovieLister(std::shared_ptr<MovieFinder> movieFinder)) : MovieLister(movieFinder)
    {
        
    }
    
    /** \brief Get movies directed by the given director.
     * \param[in] directory name of the director
     * \param[out] movies list of movies with given director
     */
    void getMoviesDirectedBy(std::string director, std::list<Movie> &movies)
    {
        movieFinder->findAllMovies(movies);
        for (std::list<Movie>::iterator it = movies.begin(); it != movies.end(); /* ... */)
        {
            if (it->getDirector() != director)
            {
                it = movies.erase(it);
            }
            else
            {
                it++;
            }
        }
    }
};
main.cpp
#include <iostream>
#include <list>
#include <fruit/fruit.h>
#include "movie.hpp"
#include "movie_lister.hpp"
#include "simple_movie_lister.hpp"
#include "fixed_list_movie_lister.hpp"

using fruit::Injector;
using fruit::Component;

/** \brief Main entry point of movie lister.
 * \param[in] argc
 * \param[in] argv
 */
Component<MovieLister> getComponent()
{
    return fruit::createComponent()
        .bind<MovieFinder, FixedListMovieFinder>()
        .bind<MovieLister, SimpleMovieLister>();
}

int main(int argc, char** argv) {
    Injector<MovieLister> injector(getComponent());
    
    std::shared_ptr<MovieLister> movieLister = injector.get< std::shared_ptr<MovieLister> >();
    
    std::list<Movie> movies;
    movieLister->getMoviesDirectedBy("Christopher Nolan", movies);
    
    for (std::list<Movie>::iterator it = movies.begin(); it != movies.end(); it++)
    {
        std::cout << "\"" << it->getTitle() << "\" by " << it->getDirector() << std::endl;
    }
    
    return 0;
}

What is your opinion on the code snippet? Is it working? Let me know your thoughts in the comments below or using the following platforms: