Which pattern to use?

The problem is this:

There is a certain application, some of it, the module works with dynamically linked plugins and he still performs some other task.

Plugins work and return a structure as a result. Plugins can use each other, even cyclically. Ie a plugin can call to assist another( or maybe several, depending on what is available at the moment), and that, in turn, the third plug-in or even the first.

The application structure is as follows:

Can't choose pattern, such that no further writing plugins, and maybe the extension interface does not become a torment. How to implement correctly?

Write a C++/Qt
October 9th 19 at 22:36
3 answers
October 9th 19 at 22:38
You must konkretisierung requirements, namely:
  • The plugins are written for internal use, or can be side plugins?
  • The truth of the assumption that all calls to the plugins to each other occur within the same thread?

I would implement it this way.

Decoupling dependencies between plugins create a plugin Manager that can load a plugin by name. Want to see the caller pulled the plug through a single interface. Each plugin it has its own set of input parameters. If you are unable to select common parameters for all plugins, it seems, from the cast type of the parameter can not escape.

Return result, it may make sense to do not a structure but a callback (if within the same thread). This will give the opportunity to implement a phased treatment (if the argument is any data stream).
By the way, there is a sense to look in the direction of interfaces, for example, by analogy with COM objects (i.e., one plugin can have multiple interfaces).
This is the case, if in Your case it is acceptable to create different interfaces for plugins. - Jerry.Murphy commented on October 9th 19 at 22:41
Apparently I was not quite accurately described the situation. All plugins in turn handle some data. For all of the plugins structure of these data are the same, one some plugins need partial functionality of the other, some of them static(second) methods, for example.
The plugin Manager loads the plugins, which is nothing more than QPluginLoader and QMap< QString, CustomPlugin* >.
All plugins work in the same thread. - jared.Leuschke commented on October 9th 19 at 22:44
Phased processing of the same data is very good to do with decorators. - Jerry.Murphy commented on October 9th 19 at 22:47
"Decorator" will allow you to write several small atomic handlers, and then inserting them into each other to any processing sequence. A good example is processing stream's.
PS I am programming in Java to provide an example in C++ is difficult. But remember that stream's there, too, done by the decorators. - Jerry.Murphy commented on October 9th 19 at 22:50
October 9th 19 at 22:40
Maybe you can help "Command" and "Chain of responsibility".
I thought about the chain of responsibility, I think it is most appropriate, and therefore asked... - Jerry.Murphy commented on October 9th 19 at 22:43
You have a little different situation I think. In the chain of responsibility the plugins don't use each other, but just determine if they can handle the request or not, and in case of failure pass the command down the chain.
I can advise the following:
— define a clear interface for plugins so that they can easily be implemented by expanding a small abstract class (pure interfaces in C++ like no, as far as I remember)
— make a wrapper class over the return structure and place frequently used processing methods, it will facilitate the rest of the plugins and may help to trace the path of transmission of commands between plugins.
Well, write unit tests, they are like nothing else a positive effect on the architecture of the program :) - jared.Leuschke commented on October 9th 19 at 22:46
Cm. the comments above with the same data definitely need a decorator. Moreover, it does not negate your advice and complements. - Jerry.Murphy commented on October 9th 19 at 22:49
October 9th 19 at 22:42
It seems to me that in this case, it is necessary to use a pattern "Strategy".
Strategy Strategy is a behavioral design pattern that is intended to define a family of algorithms, encapsulate each one, and ensure their interchangeability. This allows you to choose the algorithm by defining the appropriate class. The Strategy pattern allows to change the selected algorithm regardless of the object-clients that use it.
I think in this case not an option. Strategy is designed for dynamic substitution algorithm. Here, as I understand it, plugins are more or less static, and I want molochite minimal coupling between them. In this case, fit of the line through interfaces + retrieving instances via the factory. - Jerry.Murphy commented on October 9th 19 at 22:45

Find more questions by tags Patterns of designing