Is there one interface with many virtual methods? Or have many interfaces with only one virtual method?

I have a C ++ module that should receive information from other classes without knowing these classes. The obvious approach is to use interfaces.

Let me give you an example. Suppose I have a library that manages books, and all books have their own characteristics and functionality and allow the library to get a characteristic from a book or perform a function, the book must implement an interface. Like this:

class Library
   {
   public:
      void addBook(IBook &book);
   };

class IBook
   {
   public:
      string getAuthor()    = 0;
      string getTitle()     = 0;
      string getISBNCode()  = 0;
      size_t getNofPages()  = 0;
      size_t getNofImages() = 0;
      double getPrice()     = 0;
      void   printBook()    = 0;
      void   convertToPdf() = 0;
   };

Unfortunately, it makes no sense to implement all these methods for all types of books.

  • Some books have no images (so I don't want to implement getNofImages ())
  • Some books do not have ISBN
  • , .
  • PDF

1 , 0, "" , .

, :

class IBook
   {
   public:
      string getAuthor()    = 0;
      string getTitle()     = 0;
      size_t getNofPages()  = 0;
   };

class IISBNGetter
   {
   public:
      string getISBNCode()  = 0;
   };

class IImagesGetter
   {
   public:
      size_t getNofImages() = 0;
   };

class IBuyable
   {
   public:
      double getPrice()     = 0;
   };

class IPrintable
   {
   public:
      void   printBook()    = 0;
   };

class IConvertible
   {
   public:
      void   convertToPdf() = 0;
   };

, .

:

bookid = myLibrary->addBook (myBook);
myLibrary->setISBNGetter  (bookid, myBook);
myLibrary->setImageGetter (bookid, myBook);
myLibrary->setBuyable     (bookid, myBook);

, , , , .

, / , .

- ?

-, , .

?

+5
7

IBook :

class IBook
   {
   public:
      virtual ~IBook() {}

      virtual string getAuthor() { return ""; } // or some other meaningful default value
      virtual string getTitle() { return ""; }
      virtual string getISBNCode() { return ""; }
      virtual size_t getNofPages() { return 0; }
      virtual size_t getNofImages() { return 0; }
      virtual double getPrice() { return .0; }
      virtual void   printBook() {}
      virtual void   convertToPdf() {}
   };

, . , Visitor.

+8

, , , .

- "MethodNotImplemented" , .

, , "", , , .

+2

, , . , (ISP), , . IBook . , IPrintable IConvertible ( pdf) . , IBuyable IISBNGetter .

+2

, ISBN , ISBN ( IBook).

, , "", - , " , ISBN, , ".

, "none", . , . :

bool hasISBNcode();
string getISBNcode();

std::pair<bool, string> getISBNcode();

.

dynamic_cast , IBook, 2 ^ n . , , , ISBN ( - , ). , .

, . ConcreteBook ISBN, - , , , . , , , . , , , -, , .

+2

, boost:: optional , .

class IBook
   {
   public:
      virtual ~Ibook(){}

      virtual string getAuthor()    = 0;
      virtual string getTitle()     = 0;
      virtual string getISBNCode()  = 0;
      virtual size_t getNofPages()  = 0;
      virtual size_t getNofImages() = 0;
      virtual boost::optional< double > getPrice()     = 0;   // some have no price
      virtual void   printBook()    = 0;
      virtual void   convertToPdf() = 0;
   };
+1

, - std::map<std::string, IBase>. , ( null) doDefault() ( IDerived, ). ( ) : doDefault(const Book*).

+1

( !) :

  • .
  • .

. , , , single-method-per-interface, . , boost::optional, , .

, , , .

( ), getSin Javaism?

x = 2*getSin(v)/computeCos(v)

++, sin.: -)

hth.,

+1

All Articles