Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 3244106
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: May 17, 20262026-05-17T18:30:42+00:00 2026-05-17T18:30:42+00:00

In my developments I am slowly moving from an object-oriented approach to interface-based-programming approach.

  • 0

In my developments I am slowly moving from an object-oriented approach to interface-based-programming approach. More precisely:

  • in the past I was already satisfied if I could group logic in a class
  • now I tend to put more logic behind an interface and let a factory create the implementation

A simple example clarifies this.

In the past I wrote these classes:

  • Library
  • Book

Now I write these classes:

  • ILibrary
  • Library
  • LibraryFactory
  • IBook
  • Book
  • BookFactory

This approach allows me to easily implement mocking classes for each of my interfaces, and to switch between old, slower implementations and new, faster implementations, and compare them both within the same application.

For most cases this works very good, but it becomes a problem if I want to use iterators to loop over collections.

Suppose my Library has a collection of books and I want to iterator over them. In the past this wasn’t a problem: Library::begin() and Library::end() returned an iterator (Library::iterator) on which I could easily write a loop, like this:

for (Library::iterator it=myLibrary.begin();it!=mylibrary.end();++it) ...

Problem is that in the interface-based approach, there is no guarantee that different implementations of ILibrary use the same kind of iterator. If e.g. OldLibrary and NewLibrary both inherit from ILibrary, then:

  • OldLibrary could use an std::vector to store its books, and return std::vector::const_iterator in its begin and end methods
  • NewLibrary could use an std::list to store its books, and return std::list::const_iterator in its begin and end methods

Requiring both ILibrary implementations to return the same kind of iterator isn’t a solution either, since in practice the increment operation (++it) needs to be implemented differently in both implementations.

This means that in practice I have to make the iterator an interface as well, meaning that application can’t put the iterator on the stack (typical C++ slicing problem).

I could solve this problem by wrapping the iterator-interface within a non-interface class, but this seems a quite complex solution for what I try to obtian.

Are there better ways to handle this problem?

EDIT:
Some clarifications after remarks made by Martin.

Suppose I have a class that returns all books sorted on popularity: LibraryBookFinder.
It has begin() and end() methods that return a LibraryBookFinder::const_iterator which refers to a book.

To replace my old implementation with a brand new one, I want to put the old LibraryBookFinder behind an interface ILibraryBookFinder, and rename the old implementation to OldSlowLibraryBookFinder.

Then my new (blistering fast) implementation called VeryFastCachingLibraryBookFinder can inherit from ILibraryBookFinder. This is where the iterator problem comes from.

Next step could be to hide the interface behind a factory, where I can ask the factory “give me a ‘finder’ that is very good at returning books according popularity, or according title, or author, …. You end up with code like this:

ILibraryBookFinder *myFinder = LibraryBookFinderFactory (FINDER_POPULARITY);
for (ILibraryBookFinder::const_iterator it=myFinder->begin();it!=myFinder.end();++it) ...

or if I want to use another criteria:

ILibraryBookFinder *myFinder = LibraryBookFinderFactory (FINDER_AUTHOR);
for (ILibraryBookFinder::const_iterator it=myFinder->begin();it!=myFinder.end();++it) ...

The argument of LibraryBookFinderFactory may be determined by an external factor: a configuration setting, a command line option, a selection in a dialog, … And every implementation has its own kind of optimizations (e.g. the author of a book doesn’t change so this can be a quite static cache; the popularity can change daily which may imply a totally different data structure).

  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-05-17T18:30:42+00:00Added an answer on May 17, 2026 at 6:30 pm

    You are mixing metaphors here.

    If a library is a container then it needs its own iterator it can’t re-use an iterator of a member. Thus you would wrap the member iterator in an implementation of ILibraryIterator.

    But strictly speaking a Library is not a container it is a library.
    Thus the methods on a library are actions (think verbs here) that you can perform on a library. A library may contain a container but strictly speaking it is not a container and thus should not be exposing begin() and end().

    So if you want to perform an action on the books you should ask the library to perform the action (by providing the functor). The concept of a class is that it is self contained. User should not be using getter to get stuff about the object and then put stuff back the object should know how to perform the action on itself (this is why I hate getters/setters as they break encapsulation).

    class ILibrary
    {
        public:
             IBook const& getBook(Index i) const;
    
             template<R,A>
             R checkBooks(A const& librarianAction);
    };
    
    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

No related questions found

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.