Extensibility pattern
Encyclopedia
In computer programming
, the extensibility pattern is a design pattern
that provides a framework
for straightforward addition of functionality to a system
at a later date.
Extensibility is often desired when an application must be able to support new features, such as networking protocols or file format
s, that do not yet exist. This requires the application
to supply a framework for the general problem without concern for the specifics of details.
. A framework may consist of several parts that must be inherited to be used much like several cases of abstract class. It may also be passed references
to other objects
, as would a class
that is sets up a model-view-controller
. It may read names of classes from a configuration file
or from the user, as in BeanPattern. Instead of code being used by other code, it will use other code on the fly. It is on top of the food chain
instead of the bottom.
See Event listener for the broadcast
er/listener idiom
. This avoids building the names of listener modules into the application. An independent author could write a plugin to this application: she would need only have the user modify //config.pl// to include mention of the plugin. Of course, modification of //config.pl// could be automated. The install program
for the plugin would need to ask the user where the //config.pl// is, and use the ConfigFile idiom to update it.
s is that they make it difficult to script
repetitive tasks. Command line interfaces are difficult for most humans to work with. Neither give rich access to the application programming interface
(API) of a program. A well-designed program is a few lines of Perl
in the main program that use a number of modules — see Creating CPAN
Modules. This makes it easier to reuse the program logic in other programs. Complex programs that build upon existing parts benefit from this, without question. How about the other case — a small script meant to automate some task? This requires that the script have knowledge about the structure of the application — it must know how to assemble the modules, initialize them, and so on. It is forced to work with aspects of the API that it almost certainly is not concerned with. It must itself be the framework.
This is a kind of abstraction inversion
— where something abstract is graphed onto something concrete, or something simple is grafted onto the top of something complex.
It would make more sense in this case for the application to implement a sort of visitor pattern
, and allow itself to be passed whole, already assembled, to another spat of code that knows how to perform specific operations on it. This lends itself to the sequential
nature of the script: the user-defined extension could be a series of simple calls:
The main application could prompt the user for a module to load
, or load all of the modules in a plugins directory
, then make them available as menu
items in an "extensions" menu. When one of the extensions are select from the menu, a reference to the application — or a facade pattern
providing an interface to it — is passed to the run_macro method
of an instance
of that package.
Many applications will have users that want to do simple automation
without being bothered to learn even a little Perl (horrible but true!). Some applications (like Mathematica
, for instance) will provide functionality that does not cleanly map to Perl. In this case, you would want to be able to parse expressions and manipulate them. In these cases, a Little Language
may be just the thing.
A Little Language is a small programming language
, created specifically for the task at hand. It can be similar to other languages. Having something clean and simple specifically targeted at the problem can be better solution than throwing an overpowered language at it. Just by neglecting unneeded features, user confusion is reduced.
place_cursor(0, 0)
set_color(white)
draw_circle(radius=1)
set_color(red)
draw_circle(radius=2)
A few options exist: we can compile this directly to Perl bytecode
, using B::Generate (suitable for integrating legacy
languages without performance loss), or we can munge this into Perl and ||eval|| it. Let us turn it into Perl.
We're using the \G regex metacharacter
that matches where the last global
regex on that string
left off. That let us take off several small bites from the string rather than having to do it all in one big bite. The flags
on the end of the regex are:
Out of context, the string "xyzzy" could be either a parameter
or the name of a method to call. The solution is simply to keep track of context: that is where $state comes in. Every time we find something, we update $state to indicate what class of thing would be valid if it came next. After we find a function
name and an opening parenthesis, either a hash style parameter or a single, lone parameter, or else a close parenthesis would be valid. We are not even looking for the start of another function [though perhaps we should be. If changed, this in our code, it would allow us to nest function calls inside of each other. We would have to track our level of nesting if we wanted to report errors if there were too many or too few right-parenthesis. Exercise left for the reader.].
After a parameter, we are looking for either the close parenthesis or another parameter.
Every time we match something, we append a Perl-ized version of exactly the same thing onto $perl. All of this is wrapped in a package and method declaration
. Finally, $perl is evaluated. The result of evaluating should be to make this new package available to our code, ready to be called.
Hacks as extensions
When a base application, or shared code base, is customized
in different directions for different clients, heavy use should be made of template method
s and abstract factories
, localizing client-specific code into a module or tree of modules under a client-specific namespace
, rather than "where it belongs".
Computer programming
Computer programming is the process of designing, writing, testing, debugging, and maintaining the source code of computer programs. This source code is written in one or more programming languages. The purpose of programming is to create a program that performs specific operations or exhibits a...
, the extensibility pattern is a design pattern
Design pattern (computer science)
In software engineering, a design pattern is a general reusable solution to a commonly occurring problem within a given context in software design. A design pattern is not a finished design that can be transformed directly into code. It is a description or template for how to solve a problem that...
that provides a framework
Software framework
In computer programming, a software framework is an abstraction in which software providing generic functionality can be selectively changed by user code, thus providing application specific software...
for straightforward addition of functionality to a system
System
System is a set of interacting or interdependent components forming an integrated whole....
at a later date.
Extensibility is often desired when an application must be able to support new features, such as networking protocols or file format
File format
A file format is a particular way that information is encoded for storage in a computer file.Since a disk drive, or indeed any computer storage, can store only bits, the computer must have some way of converting information to 0s and 1s and vice-versa. There are different kinds of formats for...
s, that do not yet exist. This requires the application
Application software
Application software, also known as an application or an "app", is computer software designed to help the user to perform specific tasks. Examples include enterprise software, accounting software, office suites, graphics software and media players. Many application programs deal principally with...
to supply a framework for the general problem without concern for the specifics of details.
Frameworks
A framework uses other modules. Normal modules have a fixed set of dependencies, and are only extended through subclassing, as per inheritanceInheritance (computer science)
In object-oriented programming , inheritance is a way to reuse code of existing objects, establish a subtype from an existing object, or both, depending upon programming language support...
. A framework may consist of several parts that must be inherited to be used much like several cases of abstract class. It may also be passed references
Reference (computer science)
In computer science, a reference is a value that enables a program to indirectly access a particular data item, such as a variable or a record, in the computer's memory or in some other storage device. The reference is said to refer to the data item, and accessing those data is called...
to other objects
Object (computer science)
In computer science, an object is any entity that can be manipulated by the commands of a programming language, such as a value, variable, function, or data structure...
, as would a class
Class (computer science)
In object-oriented programming, a class is a construct that is used as a blueprint to create instances of itself – referred to as class instances, class objects, instance objects or simply objects. A class defines constituent members which enable these class instances to have state and behavior...
that is sets up a model-view-controller
Model-view-controller
Model–view–controller is a software architecture, currently considered an architectural pattern used in software engineering. The pattern isolates "domain logic" from the user interface , permitting independent development, testing and maintenance of each .Model View Controller...
. It may read names of classes from a configuration file
Configuration file
In computing, configuration files, or config files configure the initial settings for some computer programs. They are used for user applications, server processes and operating system settings. The files are often written in ASCII and line-oriented, with lines terminated by a newline or carriage...
or from the user, as in BeanPattern. Instead of code being used by other code, it will use other code on the fly. It is on top of the food chain
Food chain
A food web depicts feeding connections in an ecological community. Ecologists can broadly lump all life forms into one of two categories called trophic levels: 1) the autotrophs, and 2) the heterotrophs...
instead of the bottom.
Configuration files as extensions
A ConfigFile may be enough to customize the module for reasonable needs. It may also specify modules by name to be created and employed in a framework.See Event listener for the broadcast
Broadcasting
Broadcasting is the distribution of audio and video content to a dispersed audience via any audio visual medium. Receiving parties may include the general public or a relatively large subset of thereof...
er/listener idiom
Programming idiom
A programming idiom is a means of expressing a recurring construct in one or more programming languages. Generally speaking, a programming idiom is an expression of a simple task or algorithm that is not a built-in feature in the programming language being used, or, conversely, the use of an...
. This avoids building the names of listener modules into the application. An independent author could write a plugin to this application: she would need only have the user modify //config.pl// to include mention of the plugin. Of course, modification of //config.pl// could be automated. The install program
Installation (computer programs)
Installation of a program is the act of putting the program onto a computer system so that it can be executed....
for the plugin would need to ask the user where the //config.pl// is, and use the ConfigFile idiom to update it.
Extending through scripting
A major complaint against GUIGraphical user interface
In computing, a graphical user interface is a type of user interface that allows users to interact with electronic devices with images rather than text commands. GUIs can be used in computers, hand-held devices such as MP3 players, portable media players or gaming devices, household appliances and...
s is that they make it difficult to script
Scripting language
A scripting language, script language, or extension language is a programming language that allows control of one or more applications. "Scripts" are distinct from the core code of the application, as they are usually written in a different language and are often created or at least modified by the...
repetitive tasks. Command line interfaces are difficult for most humans to work with. Neither give rich access to the application programming interface
Application programming interface
An application programming interface is a source code based specification intended to be used as an interface by software components to communicate with each other...
(API) of a program. A well-designed program is a few lines of Perl
Perl
Perl is a high-level, general-purpose, interpreted, dynamic programming language. Perl was originally developed by Larry Wall in 1987 as a general-purpose Unix scripting language to make report processing easier. Since then, it has undergone many changes and revisions and become widely popular...
in the main program that use a number of modules — see Creating CPAN
CPAN
CPAN, the Comprehensive Perl Archive Network, is an archive of nearly 100,000 modules of software written in Perl, as well as documentation for it. It has a presence on the World Wide Web at and is mirrored worldwide at more than 200 locations...
Modules. This makes it easier to reuse the program logic in other programs. Complex programs that build upon existing parts benefit from this, without question. How about the other case — a small script meant to automate some task? This requires that the script have knowledge about the structure of the application — it must know how to assemble the modules, initialize them, and so on. It is forced to work with aspects of the API that it almost certainly is not concerned with. It must itself be the framework.
This is a kind of abstraction inversion
Abstraction inversion
In computer programming, abstraction inversion is an anti-pattern arising when users of a construct need functions implemented within it but not exposed by its interface...
— where something abstract is graphed onto something concrete, or something simple is grafted onto the top of something complex.
It would make more sense in this case for the application to implement a sort of visitor pattern
Visitor pattern
In object-oriented programming and software engineering, the visitor design pattern is a way of separating an algorithm from an object structure on which it operates. A practical result of this separation is the ability to add new operations to existing object structures without modifying those...
, and allow itself to be passed whole, already assembled, to another spat of code that knows how to perform specific operations on it. This lends itself to the sequential
Sequence
In mathematics, a sequence is an ordered list of objects . Like a set, it contains members , and the number of terms is called the length of the sequence. Unlike a set, order matters, and exactly the same elements can appear multiple times at different positions in the sequence...
nature of the script: the user-defined extension could be a series of simple calls:
The main application could prompt the user for a module to load
Load (computing)
In UNIX computing, the system load is a measure of the amount of work that a computer system performs. The load average represents the average system load over a period of time...
, or load all of the modules in a plugins directory
Directory (file systems)
In computing, a folder, directory, catalog, or drawer, is a virtual container originally derived from an earlier Object-oriented programming concept by the same name within a digital file system, in which groups of computer files and other folders can be kept and organized.A typical file system may...
, then make them available as menu
Menu (computing)
In computing and telecommunications, a menu is a list of commands presented to an operator by a computer or communications system. A menu is used in contrast to a command-line interface, where instructions to the computer are given in the form of commands .Choices given from a menu may be selected...
items in an "extensions" menu. When one of the extensions are select from the menu, a reference to the application — or a facade pattern
Façade pattern
The facade pattern is a software engineering design pattern commonly used with Object-oriented programming. The name is by analogy to an architectural facade....
providing an interface to it — is passed to the run_macro method
Method (computer science)
In object-oriented programming, a method is a subroutine associated with a class. Methods define the behavior to be exhibited by instances of the associated class at program run time...
of an instance
Object (computer science)
In computer science, an object is any entity that can be manipulated by the commands of a programming language, such as a value, variable, function, or data structure...
of that package.
Many applications will have users that want to do simple automation
Automation
Automation is the use of control systems and information technologies to reduce the need for human work in the production of goods and services. In the scope of industrialization, automation is a step beyond mechanization...
without being bothered to learn even a little Perl (horrible but true!). Some applications (like Mathematica
Mathematica
Mathematica is a computational software program used in scientific, engineering, and mathematical fields and other areas of technical computing...
, for instance) will provide functionality that does not cleanly map to Perl. In this case, you would want to be able to parse expressions and manipulate them. In these cases, a Little Language
Domain-specific programming language
In software development and domain engineering, a domain-specific language is a programming language or specification language dedicated to a particular problem domain, a particular problem representation technique, and/or a particular solution technique...
may be just the thing.
A Little Language is a small programming language
Programming language
A programming language is an artificial language designed to communicate instructions to a machine, particularly a computer. Programming languages can be used to create programs that control the behavior of a machine and/or to express algorithms precisely....
, created specifically for the task at hand. It can be similar to other languages. Having something clean and simple specifically targeted at the problem can be better solution than throwing an overpowered language at it. Just by neglecting unneeded features, user confusion is reduced.
place_cursor(0, 0)
set_color(white)
draw_circle(radius=1)
set_color(red)
draw_circle(radius=2)
A few options exist: we can compile this directly to Perl bytecode
Bytecode
Bytecode, also known as p-code , is a term which has been used to denote various forms of instruction sets designed for efficient execution by a software interpreter as well as being suitable for further compilation into machine code...
, using B::Generate (suitable for integrating legacy
Legacy system
A legacy system is an old method, technology, computer system, or application program that continues to be used, typically because it still functions for the users' needs, even though newer technology or more efficient methods of performing a task are now available...
languages without performance loss), or we can munge this into Perl and ||eval|| it. Let us turn it into Perl.
We're using the \G regex metacharacter
Metacharacter
A metacharacter is a character that has a special meaning to a computer program, such as a shell interpreter or a regular expression engine.-Examples:...
that matches where the last global
Scope (programming)
In computer programming, scope is an enclosing context where values and expressions are associated. Various programming languages have various types of scopes. The type of scope determines what kind of entities it can contain and how it affects them—or semantics...
regex on that string
String (computer science)
In formal languages, which are used in mathematical logic and theoretical computer science, a string is a finite sequence of symbols that are chosen from a set or alphabet....
left off. That let us take off several small bites from the string rather than having to do it all in one big bite. The flags
Flag (computing)
In computer programming, flag can refer to one or more bits that are used to store a binary value or code that has an assigned meaning, but can refer to uses of other data types...
on the end of the regex are:
- g - global - needed for the \G token to work
- c - not sure, but it makes g work
- s - substring - treat the entire string as one string. Newlines become regular characters and match whitespaceWhitespace (programming language)Whitespace is an esoteric programming language developed by Edwin Brady and Chris Morris at the University of Durham . It was released on 1 April 2003 . Its name is a reference to whitespace characters...
.
Out of context, the string "xyzzy" could be either a parameter
Parameter (computer science)
In computer programming, a parameter is a special kind of variable, used in a subroutine to refer to one of the pieces of data provided as input to the subroutine. These pieces of data are called arguments...
or the name of a method to call. The solution is simply to keep track of context: that is where $state comes in. Every time we find something, we update $state to indicate what class of thing would be valid if it came next. After we find a function
Subroutine
In computer science, a subroutine is a portion of code within a larger program that performs a specific task and is relatively independent of the remaining code....
name and an opening parenthesis, either a hash style parameter or a single, lone parameter, or else a close parenthesis would be valid. We are not even looking for the start of another function [though perhaps we should be. If changed, this in our code, it would allow us to nest function calls inside of each other. We would have to track our level of nesting if we wanted to report errors if there were too many or too few right-parenthesis. Exercise left for the reader.].
After a parameter, we are looking for either the close parenthesis or another parameter.
Every time we match something, we append a Perl-ized version of exactly the same thing onto $perl. All of this is wrapped in a package and method declaration
Declaration (computer science)
In programming languages, a declaration specifies the identifier, type, and other aspects of language elements such as variables and functions. It is used to announce the existence of the element to the compiler; this is important in many strongly-typed languages that require variables and their...
. Finally, $perl is evaluated. The result of evaluating should be to make this new package available to our code, ready to be called.
Hacks as extensions
When a base application, or shared code base, is customized
Custom software
Custom software is software that is specially developed for some specific organization or other user. As such, it can be contrasted with the use of software packages developed for the mass market, such as commercial off-the-shelf software, or existing free software.Custom software can be...
in different directions for different clients, heavy use should be made of template method
Template method pattern
In software engineering, the template method pattern is a design pattern.It is a behavioral pattern, and is unrelated to C++ templates.-Introduction:A template method defines the program skeleton of an algorithm...
s and abstract factories
Abstract factory pattern
The abstract factory pattern is a software design pattern that provides a way to encapsulate a group of individual factories that have a common theme. In normal usage, the client software creates a concrete implementation of the abstract factory and then uses the generic interfaces to create the...
, localizing client-specific code into a module or tree of modules under a client-specific namespace
Namespace (computer science)
A namespace is an abstract container or environment created to hold a logical grouping of unique identifiers or symbols . An identifier defined in a namespace is associated only with that namespace. The same identifier can be independently defined in multiple namespaces...
, rather than "where it belongs".