Architecture for extension/plugin communication

不想你离开。 提交于 2019-12-03 16:14:44

A key for your design decision is to analyze and get a clear picture of how different the plugins will be from eachother.

E.g. when dealing with static events, you will probably have to define each event as some form of token, enum, object etc. Having to define a new set of events for each plugin naturally works against your whole design, particularly in terms of loose coupling and reuse.

If your plugins are very different you might benefit from having a bus/messaging architecture since you in such case can introduce domains/categories of communication exchange, which the plugins can subscribe to. I.e. a range of events and messages can be in a certain interest domain. Note here that communication within a certain category can still utilize static events, so those two alternatives are not mutually exclusive.

Direct interfaces implemented by the plugins is in my experience the strictest approach of plugin architecture. Extending the plugin interface usually implies code modification at both plugin and provider. You need to have a solid general interface which you know your application can live on for quite some time.

It may be easier for you to deal with the design by breaking it down into two aspects - communication channel and protocol. Static event handling is a protocol issue, while bus-messaging and direct interfaces is a channel issue.

Generally I would say that the protocol is the hardest to design correctly from the beginning, since you may not have a solid feel for how general or specific you can draw the line.

EDIT: Lars made an important point in his comment - if your platform supports exceptions, you can centralize a lot of the error handling when using direct interfaces, relieving the plugins from having to handle errors that are generic and perhaps outisde their particular domain (e.g. "plugin load error", or "file open failed"). However, such benefits will seem to fade if you have to maintain interfaces each time you add plugins. Worst case is when the interfaces start becoming inconsistent along the way because you didn't realize what they should support from the beginning. Refactoring the entire interface design when a substantial amount of plugins already have been conceived is not an easy task.

I'd go with the Observer pattern. From the GOF:

Define a one-to-many dependency between objects so that when one object changes state all its dependents are notified and updated automatically.

Also known as publish-subscribe I would suggest it most closely matches case two in your examples.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!