Is a “program for interfaces” a general design principle in C ++ projects?

I read a lot about the “program for interfaces” and “inversion of control” in recent days. Mostly in the context of the Java language. My question is that this is also a common practice in C ++ development. What are the benefits? What are the disadvantages?

Is it possible to apply to small projects (for example, 15-20 classes)?

+4
source share
10 answers

The principles you are talking about are generally applicable to any OO language. The basic principle here is “free communication”. A class that depends on another class (contains an instance of it and calls methods on it as part of its own work) really depends only on the set of functions provided by the dependency. If a class defines a link to a specific class on which it depends, and then you want to replace the class with another, you will not only need to develop a new class, but also change the dependent class so that it depends on the new type. This is usually bad, because if your class depends on many other classes, you need to change the code in several places, requiring you to test all the uses of these objects to make sure that you have not violated previously working functions.

Interfaces were designed to eliminate this, allowing several classes that are not related to each other's pedigree to be used interchangeably based on a common, forced set of methods that you know the class will implement. If, instead of depending on the class, you depended on the interface, any class that implements the interface would fulfill the dependency. This allows you to write a new class to replace the old one, without a class that uses it, knowing the difference. All you need to change is the code that creates the concrete implementation of the class that fills the dependency.

This presents a predicament; Of course, your Depender class may say that it needs IDoSomething instead of DoerClass, but if Depender knows how to create a DoerClass to use as IDoSomething, you haven’t received anything; if you want to replace DoerClass with BetterDoer, you still have to change the Depender code. The solution is to give responsibility for providing the dependency class to a third party, the Creator. The class selected for this depends on the context. If a class naturally has both a Depender and a DoerClass, this is an obvious choice for combining them. This often happens when you have one class that has two auxiliary dependencies, and one dependency needs another. In other cases, you can create a Factory that exists to provide the caller with an instance of a specific object, preferably with all the dependencies connected.

If you have several interdependent classes or dependencies at many levels, you can consider the IoC framework. IoC containers are factories, because the repositories are for DAO; they know how to get you a fully hydrated instance of the ANY class that requires one or more dependencies, for example, a repository can create any fully hydrated domain object from data in the database. He does this by saying that a particular class should be used to populate dependencies in a specific situation, and when asked to provide a class, he will instantiate that class by providing instances of the necessary dependencies (and dependency dependencies). This may allow patterns in which class A depends on B, which depends on C, but A cannot know about C. The IoC structure knows about all three and will instantiate B, give it a new C, and then give B a new a.

+6
source

Yes, this is quite common, but not in the form that you might expect.

In Java, an interface is formalized and clear, and programming on an interface means implementing that particular interface .

In C ++, the same thing is done sometimes (though using abstract base classes, and not with interfaces), but another general way that it does in C ++ is through templates where the interface is implicit.

For example, standard library algorithms work with an iterator interface, except that such an interface is never defined in code. This is an agreement, and nothing more.

A valid iterator must expose certain functions, so any type that provides this functionality is an iterator. But he does not need to implement some kind of hypothetical IIterator interface, as in Java.

Same thing in user code. You often write your code to accept a template parameter, which may be something that works. You implicitly define an interface through your use of the type: everything you need from it becomes part of this implicit interface that the type must satisfy in order for it to be used.

An interface is never written in code, but you still use it and program against it.

+7
source

Absolutely! Encapsulation is an important part of OOP philosophy. By keeping the implementation separate from the class interface, your code becomes much more universal. For example, if I had a Vector class, and I would like to change the internal representation from a pair of x and y to length and direction (say, this is for efficiency), then just changing a few member functions that handle the FAR implementation is easier than clearing 100 source files for each class, which depends on the implementation of the classes.

And yes, small projects can also be beneficial. This concept is also useful when you have several classes that do the same thing (say, rendering), but in a different way (possibly for different platforms). Providing them with the same interface (or in C ++, deriving them all from the same base class), then any object can switch between them using simple substitution.

+4
source

I think there may be some confusion in the terminology, since the "interface" is not a term defined by the C ++ language. In the context of your question, you obviously mean the specification of an abstract class, which can be implemented by one or more specific classes.

I would not say that this is common, but it is not uncommon - maybe somewhere in the middle? Microsoft COM is built on a concept.

See this question for more information on how to do this: How do you declare an interface in C ++?

+1
source

There are more for interfaces in C ++ than in Java. The simple answer is yes, this is a common practice. Whether you should follow him in your small project depends on the case. Judge for each class, not for the project as a whole. As a rule, if it is not broken, do not correct it.

However, in C ++ you have two types of interfaces: one that supports run-time polymorphism and one that supports compile-time polymorphism. Run-time polymorphism is very similar to what you know from Java. Polymorphism of compilation time comes from the use of patterns.

The advantage of run-time polymorphism is that it usually results in a small binary file, and this makes it easier for the compiler to generate meaningful error messages at compile time. At the bottom, this also leads to a slightly slower binary, as calls require another dereference.

The advantage of compile-time polymorphism is that often your source is shorter and call time is optimized as fast as it gets. On the other hand, because the compiler needs to execute longer compilation times, it is usually slower. Often, compilation time becomes much slower, because templates are usually defined in header files, and therefore are recompiled again and again for each compilation unit that depends on them.

+1
source

I would say that these concepts extend far beyond just OO, but equally apply to most, if not all, paradigms that you can use in C ++, including Generic Programming.

+1
source

Well, the "program for interfaces" is used by anyone in any language that writes libraries.

The library user does not want the library interface to change all the time. Imagine that you had to rewrite your programs because the authors of the C-library decided to redefine "printf". Or what if the Java library decided to override the toString interface?

So yes, the "program for interfaces" is used in C ++.

0
source

Interfaces have become popular in Java and now with C #, before Object Oriented Programming interfaces already exist, the most complete language ever created (in my opinion) C ++ did not grow based on interfaces. The main need for creating interfaces arose to solve the problem of having multiple inheritance (C ++ allows multiple inheritance).

In C ++, there is no extended practice for defining interfaces ( but they can be modeled using abstract classes ). There is also a general practice for defining a file containing declarations (.H) and others containing an implementation (.CPP), probably in combination with a pure abstract class, it serves as a source of inspiration for creating interfaces in modern OO languages.

0
source

Take a look at the design of the standard template library. For example, in msdn channel9 there are some good video tutorials that explain the design (and implementation of MSFT) of STL.

http://channel9.msdn.com/Shows/Going+Deep/C9-Lectures-Introduction-to-STL-with-Stephan-T-Lavavej

0
source

For the "program for the interface", as usual, it depends. If you use polymorphism at runtime, the disadvantage is the speed of execution and the creation of more classes. If you use compile-time polymorphism for your interfaces, the drawbacks are compilation speed and complexity (regarding compilation errors, debugging, etc.).

Both have a great advantage in improving maintainability. This is achieved through encapsulation, which gives better testability and a stronger separation of problems. Adapting to this style of thinking reduces your problems to a smaller scale, enclosed in the interfaces of other components.

This way of thinking is considered good practice in any programming language, even if you are not explicitly coding for interfaces. (see also RESPONSIBLE principles).

Inversion of control is another beast for C ++, since there are no good widely accepted standard frameworks. You must do this, but you need to manage it yourself. Best advice: Avoid statics and use the “program for interfaces” and you should be fine for small projects.

0
source

All Articles