PlugIn Architecture Pattern Problem The functionality of a
Plug-In Architecture Pattern
Problem • The functionality of a system needs to be extended after the software is shipped • The set of possible post-shipment extensions is large • Specific details on future extensions are not available, but their general nature is predictable • It should be possible to extend the system without access to the system's source code, by people who were not the system's original developers • It should be easy to add and remove extensions in whatever combination is desired by the customer
Example : Syntax Highlighting • You are writing a text editor intended for use by software developers • You want to support syntax highlighting, but the set of possible programming languages is unbounded • Even if you could list all of the possible languages, you don't have enough resources to implement syntax highlighting for them all • Third-party developers and end-users will need the ability to add syntax highlighting for their favorite languages without your help
Solution • Define an abstract interface that captures the general nature of the necessary extensions – interface ISyntax. Highlighter { … } • Extensions are components that implement the abstract interface – class Perl. Syntax. Highlighter implements ISyntax. Highlighter { … } • • How does the application know when to use our plug-in class? How can the application instantiate our plug-in class? – It doesn’t know the class name to call “new” on (Perl. Syntax. Highlighter) • At installation time, a new plug-in has to “register” with the application – Example
Solution • Extensions are called "plug-ins" because they can be "plugged in" to the system without recompilation • The system instantiates plug-in components indirectly through a registry • The system invokes plug-in functionality through an abstract interface
Solution
Dynamic Behavior : Plug-in Registration
Dynamic Behavior : Plug-in Selection and Execution
Dynamic Behavior : Plug-in Un-registration
Implementation • Plug-ins are frequently implemented as dynamically-linked libraries • The host application loads the plug-in DLLs that have been registered • Registration techniques – Just copy the plug-in DLL into a special directory. The host application loads all DLLs in the plug-in directory, and queries each DLL for information about its plug-in – Installer puts an entry in a configuration file that indicates where the plug-in DLL is located
Implementation • In Java a plug-in could be a. class file containing the plug-in class • Registration could be as simple as putting the name of the plug-in class in a configuration file • The host application uses reflection to instantiate plug-in classes by name, which causes the classes to be loaded into the VM
Known Uses • Web browser plug-ins for different file formats – PDF, Power. Point, Word, etc. • Web servers – Apache Modules • SSL, user authentication, caching, logging, etc. – IIS ISAPI Extensions • MS-Windows compound documents – "Insert Object" menu in many Windows applications
Known Uses • Syntax Highlighting • Eclipse – Framework for building integrated development environments (IDEs) – Provides basic shell for IDE UI – All actual work is done by plug-ins for specific development tasks • Editors, compilers, debuggers, wizards • Database drivers – Generic database APIs: ODBC, JDBC – Plug-in drivers for specific DBs: Sql. Server, My. SQL, Postgres, etc.
Consequences • Results in a system that can be extended: – After it's shipped – By people other than the original developers – Without recompiling the system • Users are free to choose which plug-ins they want to install • Commercial opportunities for third-party plug-in developers • Buggy plug-ins can destabilize the system since they're usually loaded directly into the host application process (crashes, memory leaks, etc. )
Plugin Example package plugin; public interface QPlugin { public void say. Hi(); } This interface needs to be in two places: The JAR with the plugin The application that is using the plugin
Plugin Example package plugin; public class My. QPlugin implements QPlugin { public void say. Hi() { System. out. println("Hi There World!!"); } } This is the implementation of the plugin This needs to be in the plugin JAR
import java. net. URL; import java. net. URLClass. Loader; import plugin. *; public class Plugin. Example { /** * @param args */ public static void main(String[] args) { print. Classpath(); Class c = null; try { c = Class. for. Name("plugin. My. QPlugin"); } catch (Class. Not. Found. Exception e) { // TODO Auto-generated catch block e. print. Stack. Trace(); } QPlugin q = null; try { q = (QPlugin)c. new. Instance(); } catch (Instantiation. Exception e) { // TODO Auto-generated catch block e. print. Stack. Trace(); } catch (Illegal. Access. Exception e) { // TODO Auto-generated catch block e. print. Stack. Trace(); } q. say. Hi(); }
public static void print. Classpath() { //Get the System Classloader Class. Loader sys. Class. Loader = Class. Loader. get. System. Class. Loader(); //Get the URLs URL[] urls = ((URLClass. Loader)sys. Class. Loader). get. URLs(); for(int i=0; i< urls. length; i++) { System. err. println(urls[i]. get. File()); } } }
- Slides: 18