The Design of Software (CLOSED)

A public forum for discussing the design of software, from the user interface to the code architecture. Now closed.

The "Design of Software" discussion group has been merged with the main Joel on Software discussion group.

The archives will remain online indefinitely.

Plugin, dynamic library or static linking?

Hello all,
the core of the program I work on (C++ and Qt) is a tree view displaying the structure of the user data.
When the user doubleclick on an item in the tree a module (based on the type of the item) is invoked. Each module is developed by a different programmer. 
Currently the moules are implemented as plugins.
I question this design. When asking about the rationale for this decision I have been told:
this will simplify patching the program. Say a bug is discovered in module a, then we only need to provide our customers with a new version of the module a dynamic library (.dll/.so).
To me this is a good argument for using dynamic libraries instead of linking in the modules into the exe.
Do anyone have experiences with this approach?
However I do not understand why this should imply that we need to use plugins. To me using plugins is a good idea if you have several different ways of doing the same task but that is not the case in our program, all the modules do completely different things.

Thanks in advance for any answers!





 




 


one wants to be able to release a patch of the program as a new version of the 


I work at we have a program that consist of a core,, and modules.
Depending on the type of item selected in the tree view different modules are called.
 




they have decided to modularize the code by putting sub parts in plugins.
Andreas Werner Paulsen Send private email
Saturday, February 03, 2007
 
 
Sorry about the messup! Ignore everything below the thanking line in my previous posting.
Andreas Werner Paulsen Send private email
Saturday, February 03, 2007
 
 
This is more or less one of the main problems ActiveX solves.  In any case proper versioning and extension discipline is required to avoid breaking compatability.

Why reinvent this wheel?

Ahh, nevermind.  I see you're trying to reinvent the wheel in a multiplatform manner.

Too bad nothing ever came of http://www.microsoft.com/presspass/press/1996/sept96/wkgppr.mspx
Codger
Saturday, February 03, 2007
 
 
"To me using plugins is a good idea if you have several different ways of doing the same task but that is not the case in our program, all the modules do completely different things."

If anything, I would think that's exactly bass-ackwards.  Plugins are probably most helpful when they _do_ do completely different things from other parts of your app.  But that's all beside the point.  Plugins let you ship a dll that adds new functionality (and potentially new forms) to your main app, and your main app doesn't have to know anything more about it than to load the plugin and interact with it in some predefined ways (e.g., to add menu items in main app that allow user to invoke functionality in the plugin).

If it's constructed as I expect it is, you could take your main shell app, throw a new dll plugin in the exe (or plugin) directory, and next time you start it up the app will find and load the plugin, automatically add a new entry into the menu tree that will load a new form with functionality different from anything in the exe (or other plugins).  This all happpens without modifying any code in the main exe.  Moreover, the same plugin can potentially be loaded into other apps that have the same plugin architecture.  Plugins keep things modularized, self-contained.  How is that not a good thing?
Herbert Sitz Send private email
Saturday, February 03, 2007
 
 
You are probably using QT plugins, which are one way you can easily extend QT. They are implemented as shared libraries already, so i'm not sure what you asking here.

Saturday, February 03, 2007
 
 
I've been working in a plug-in context for about 10 years and would not want to go back on anything but a throw-away toy project. In addition to the deoployment aspects already mentioned, it forces you to think about your interfaces, your coupling and your overall design much more. It helps things from becoming a big ball of mud.

Also, a plug-in architecture is independent of the linking method. They tend to be thought of as plug-in/dynamic linking and non-plug-in/static linking. But you can have something that doesn't allow plug-in modularity and be dynamically linked and you can have a plug-in system where all the modules happen to be linked statically. In my opinion, the plug-in concept is the more important of the two because it forces thought about coupling. It's realatively easy to go between statically linked and dynamically linked if you have a well modularitzed architecture.

It does require some more work, the value of which may not be readily apparent. Are you new to the project? If so, perhaps you don't have as long a term view of where it's come from and where it's going. I suggest building relationships with the existing senior developers to understand their philosophy and history a bit better.

Regards,
Harley Pebley Send private email
Saturday, February 03, 2007
 
 
I am fond of software backplanes.  What you are describing sounds to me like a perfect use for a plugin based architecture.  A core application specifies an interface and data exchange contract (i.e. an API) through which separate modules can interact with the application and expose functionality through the application.

Just shipping new modules in DLLs isn't enough.  You need a way for the application to discover these DLLs and to know how to execute the logic within.  This is the essence of what a plugin architecture is.

What you describe doesn't sound quite the same as e.g. breaking up your core application into a "graphics" part and a "UI part" and a "database part" and having these "parts" be individually upgradable DLLs.  In this latter case, you don't have a plugin architecture, per-se. 

Both cases may opt to use DLLs.
Dan Fleet Send private email
Saturday, February 03, 2007
 
 
Thank you all for your replys!
Herbert: when I think of plugins, I think of e.g. Windows Media Player (WMP). It is possible to install a plugin (say DivX) which extends the list of media files it can play.
A (simplified) interface to the plugins in this case might be:
void playFile(std::string &file);
The reason that the interface to the plugins is so simple is that the plugins all does the same thing.
Our modules do very different things. Sticking to the WMP analogy one might say that one module plays a media file another one is a text editor and so on.
The interface to the plugins is something like this:
void doWhateverItIsThatYouDo(std::string &file);
So the reason that things work is that each module work on a separate file (historically each module was a separate program).
In order to do his job however the user is dependent on all modules being present.
This is different from the WMP case since if I remove the DivX plugin WMP is still a useful program.
Also in the WMP case functionality may be added later without upgrading the main program and it may be added by a 3rdparty (e.g. DivX corporation).
In our case it is hardcoded in the core something like:
std::string objectClickedOnType;
...
if(objectClickedOnType == "media")
    loadModule("mediaPlayer");
else if (objectClickedOnType == "textFile")
    loadModule("textEditor");
So in our case it is not possible to extend our program by merely adding a plugin.

Harley: yes it is a good thing to have loose coupling between the modules but could we not achieve this with dynamic libraries (.dll/.so) as well? When using a .dll one is ensured that the contact with the main program only goes trough the exported interface in the .dll.

Cheers,
Andreas Werner Paulsen Send private email
Sunday, February 04, 2007
 
 
+1 to software backplanes.

> In our case it is hardcoded in the core something like

You could easily replace that with a configuration data file, which would map the file type to the name of the plug-in.

The main difference between plug-in and not-plug-in, I think, is that a set of plug-ins must all support the same API: e.g. if they all export a "void doWhateverItIsThatYouDo(std::string &file);" method then they're plug-compatible.

> This is different from the WMP case since if I remove the DivX plugin WMP is still a useful program.

The advantages of your plug-in architecture might include:

* Upgrade a plug-in without affecting the rest of the system

* Minimal coupling (a single method) between the core (backplane) and each plug-in implementation

* Minimal coupling between different plug-ins.
Christopher Wells Send private email
Sunday, February 04, 2007
 
 
"The main difference between plug-in and not-plug-in, I think, is that a set of plug-ins must all support the same API"

That's true, of course.  But the practicaly advantage you get from plugins goes way beyond that.  Dll's expose only a list of procedures or functions.  Variables, classes, objects inside the dll are not directly accessible to outside processes.  Writing a plugin involves moving most or all of the relevant code into the dll, where all variables and objects can be directly referenced.  This is part of the "modularity" advantage that's been mentioned.

"when I think of plugins, I think of e.g. Windows Media Player (WMP). It is possible to install a plugin (say DivX) which extends the list of media files it can play."

Yes, but that is certainly only one scenario where plugins are useful.  That scenario is perhaps most helpful when you want to create architecture where third parties can add functionality to your program. 

But plugins are just as useful for a business app with an "outlook bar" or treeview component along left side that loads different forms with widely varying uses.  This enforces modularity, allows you to distribute same .exe with different price-levels depending on what functionality (i.e., plugins) is included, simplifies updates, and more.

I develop in Delphi and use a commercial plugin architecure. One neat new feature they've added to most recent version is "cross-platform" plugins.  As an advantage derived from the modularity of plugins, a Win32 Delphi application developed with plugins can be ported over to .NET one plugin at a time:
http://www.remobjects.com/devcenter/articles/?id={3539A3AC-3B46-4EAC-841D-898565470BD5}

You certainly rarely _need_ a plugin architecture.  But if you've inherited an application with a nice plugin architecture, I can hardly imagine why you'd want to jettison it and go back to a non-plugin architecture.  I think the main reasons to resist plugin architecture are (1) there's a little bit of a learning curve, and (2) it takes a certain amount of retooling to convert a regular application to use a plugin architecture.  But once you're past both of those, you're home free.  Don't look back.
Herbert Sitz Send private email
Sunday, February 04, 2007
 
 
I have a lot of experience with this as well. In my case, I designed an API for our system that specified a number of plug-in entry points, some required, some optional.

Our plug-ins ran in a server process, so the API consisted of calls such as:

GetPluginVersion()
InitFromPrimaryThread()
TermFromPrimaryThread()
InitFromThread()
TermFromThread()
PerformSomeAction()

There were far more than that, but those were the basics.

A common COM interface is also an option.

Plug-ins are extra work, but they are a great way to extend an application.
MBJ Send private email
Friday, February 23, 2007
 
 

This topic is archived. No further replies will be accepted.

Other recent topics Other recent topics
 
Powered by FogBugz