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 classes

I have a feature in my program that needs to be pretty flexible, so I'm thinking of making a little plugin architecture for it. I would only be "plugging in" features for one or two main classes.

My problem is, I need the plugin classes to be able to call private/protected methods in the main classes. But I don't want to make them subclasses of the main ones, since the main objects will already be instantiated when I need to use the plugins. Plus there will be more than one in use at a time.

If this were JavaScript, I could supply functions in my plugins that are meant to be called in the context of the main classes (so that "this" refers to the main class, not the plugin class). But alas, I'm using PHP, which doesn't have this feature.

Can anyone think of a design that might help with this? Thanks.
JW
Wednesday, March 28, 2007
 
 
If the methods need to be called from outside the class, why are they private?

In general, with any plugin architecture you need to think carefully about the API that the hosting application presents to the plugins. You may be better off defining explicit objects that expose your host's services to the plug-in.
Chris Tavares Send private email
Wednesday, March 28, 2007
 
 
parent::  ?
KC Send private email
Wednesday, March 28, 2007
 
 
This sounds like a 'two interface' problem. You have some classes that need to present one face to one set of classes, and another face to a different, perhaps more privileged set.

There are a few different ways to go.

a) One class, two interfaces.

Make a class that inherits from two different abstract base classes. One is the public interface, another is the more privileged interface.

Have the class inherit privately, so that you can't cross-cast between the interfaces.

b) Composition.

Put a class with a privileged interface inside another one with a more generic interface. This gives much the same effect - you can have two different interfaces depending on whether you have a pointer to the contained class, or the container.

c) Make the base class a friend.

All these plugin classes derive from one base class. Make that base class a friend of the classes which it needs access to, and add some private methods in the base class that call the friends as needed. The plugins can then call their base class functions to make the required friendly accesses.
Duncan Sharpe
Wednesday, March 28, 2007
 
 
All of which is fine in C++ - duh! Sorry for not reading the post thoroughly enough....
Duncan Sharpe
Wednesday, March 28, 2007
 
 
In C++/C#, I don't know about PhP:

class Foo
{
 interface IPlugin
 {
  void do_something_private();
 }
 class ImplementPluginInterface : IPlugin
 {
  Foo m_foo;
  ImplementPluginInterface(Foo foo)
  {
  m_foo = foo;
  }
  //called from plug-in
  void do_something_private()
  {
  //delegate to actual implementation
  m_foo.do_something_private();
  }
 }
 ImplementPluginInterface m_implementPluginInterface;
 Foo()
 {
  m_implementPluginInterface = new ImplementPluginInterface();
 }
private:
 void do_something_private()
 {
  ...
 }
}

With the above scheme:

* Most classes can't invoke the Foo::do_something_private method

* The Foo class can give a pointer/reference to m_implementPluginInterface data to specific modules (i.e. the plug-in). The plug-in sees that as a reference to an instance of the IPlugin interface, and invokes IPlugin methods. When an ImplementPluginInterface method is called via the the IPlugin interface, it delegates to the corresponding private method of the Foo object in which it is contained.
Christopher Wells Send private email
Thursday, March 29, 2007
 
 
> m_implementPluginInterface = new ImplementPluginInterface();

That should have been ...

m_implementPluginInterface = new ImplementPluginInterface(this);
Christopher Wells Send private email
Thursday, March 29, 2007
 
 

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

Other recent topics Other recent topics
 
Powered by FogBugz