Paul Hammant's Blog: An Ontology: Component vs Class vs Object vs Service vs Application vs Process vs Library, etc
Trying to write something that covers a few computing topics, but remains short and copy/pasteable. If for nobody else, then I’ll use it client work going forwards (subject to community corrections - pls email me)
Process - Appears in ‘ps’ (Linux), ActivityMonitor (Mac) TaskExplorer (Win). A process is a running manifestation software from an operating system’s point of view. Processes consume CPU and RAM. Processes can facilitate leveraging of networks (via host OS). The same is true for file systems. The operating system itself may have its own processes, but most often humans think about the process that is the result of software installation on top of the base OS. Processes are instantiated code which may include libraries and frameworks.
Library - An eminently link-able thing. Does not in itself have life or is capable of life without anything else involved. It will not, therefore, appear in ps (etc). Libraries may be used by multiple services or applications or plugins - as dependencies.
Frameworks - are like libraries in that they can be depended on into an application or services. However, they come with an “I’m in charge” factor. At the very least an opinionated API. Typically, that might mean that the depending application or service has to implement a number of programmatic concepts and the control of execution of your software (that depends on the framework) is orchestrated by the framework. Mere libraries do not have that aspect. Like libraries though frameworks on their own do not have ‘life’ connotation.
Class - A subset of modern languages have object orientation (OO) capability. Notably, Java, C#, Ruby, Python. They are compiled from source. Classes can be used by other classes in a way that is superficially similar to linking. Like libraries and frameworks, there is no clear life to a class on its own. Read more about OO here: DefinitionsForOo. Object-oriented programming (OOP) applies. Also Object-oriented design (OOD).
Object - Classes that are instantiated in a context (say a JVM) are objects. As the “DefinitionsForOo” above says, there can be a hierarchy of specialization (and more). There’s an implicit life for an object (unlike a class on its own). Objects (in most languages) can also be interrogated to determine what class it is an instance of. Metaprogramming is nearly always a possibility.
Service - Has connotations of remoteness, marshalling/serialization and accepting of connections over TCP/IP. Services are otherwise are conventional running processes. Because of the TCP/IP aspect they facilitate heterogeneous computing. The eight fallacies of distributed computing apply to them. They may consume other services. Microservices differ only in that they have fewer lines of code, a smaller focus (and some other rules). Again conventionally, services have TCP/IP addresses which they listen to a port on. Their consumers may have come indirectly (load balancers, firewalls, etc) so may know them to be on a different TCP/IP address/port. Domain names apply too - either first class ‘example.com’ or sub-domains (a.b.d.e.f.g.h.example.com - to a limit of 256 chars or thereabouts). These days, services are more often horizontally scaled than vertically. Server-side web-frameworks would often be used to reduce the code needed to write a service. The actual heavy lifting via HTTP is nearly always delegated to a library (or container: see below).
Services are either a process in the classic design (that conventional tag above), OR in the FaaS era, services may be merely hosted inside some other service on the FaaS platform. They could be managed elsewhere (SaaS, or by yourselves). FaaS can also be online (Amazon Lambda) but that’s not important to understanding services generally. FaaS typically means that the service itself is abstracted away from its TCP/IP address and port, and in fact cannot discover it (see containers below).
“Service” also has three non-software alternates: 1) ITIL “service design”, 2) Designers “service design” and 3) Government “service design” (refer to Prof. John Seddon’s materials).
Application - As service (is a process), but has UI connotations. Applications may also include services if the dev team in question has not done some Conway-esque surgery on them. Applications may be multi-user thin-client (they present a web interface over HTTP). If they have that UI connotation, they may also provide a non-UI service end-point from the same process. With the advent of REST, the distinction between services to support a UI and ones not there to support a UI is very slight and no longer a relevant question. The same goes for GraphQL wire in interfaces. Applications may also be a single-user fat-clients and do not listen on a TCP/IP address/port at all. Meaning they are not services in that incarnation, and are installed on an individual’s desktop machine or phone or tablet.
Components (general): A software thing that can be part of another bigger thing … includes libraries, frameworks, applications, and plugins.
Components (hardware): At another level, hardware-centric IT professionals might refer to switches, hubs, firewalls/load-balancers, SSL-offloaders, as components.
Components (specific): An aggregation of classes (or more ambiguous modules from non-OO languages) that suits a larger purpose that’s closer to a business description. “ShoppingCart” and “Inventory” are good examples. In OO, as well as being an aggregation of classes, components are also classes themselves. Components are instantiated in a context too, and that could be a container. There’s an implied pluggability to components in this model. Terms like decomposition and componentization apply (they mean the same thing) when considering refactoring work to make a better code base.
Containers - At the simplest definition specialization of ‘library’. Software that hosts multiple guest software things. Host and guest; container and contained. There’s always an API between the container and contained. Containers control the life-cycle of the things they contain. Contained things are nearly always lesser capable than the container they are in - a sandbox concept. Contained things can only invoke functionality in the container itself if the container provides an API to do so. In some cases, the contained thing may not explicitly know it is contained. Windows on VmWare is an example, or should be, and as a container concept itself is way beyond a simple ‘specialization of library’. If it was not clear, containers should generally include the ability to have more fine-grained containers used within their contained components, but do not always. Presently Docker, as a container, does not allow additional embedded Docker containers within it. I hope that changes in time and Docker ‘compose’ is a workaround I think. Components being added to running containers should not require a restart of the container seems like a requirement to me, but again is not always facilitated. Self-reference on that and an elaboration of many container/contained things: principles-of-containment
Examples:
- Tomcat is a container that can host multiple WAR-file web applications and/or services (Java ecosystem only - therefore homogeneous). Jetty and Netty are alternates to the same “servlet-spec” API. All of these are now commodity choices.
- WebLogic and WebSphere are two of many J2EE containers (the servlet spec as above and more - originally designed in 1997 and a massive mistake at that moment in time IMO) are containers. The deployments into which are EAR file applications (that may include WAR-files too, though that is not ideal recursive containment). As above, a homogeneous Java ecosystem solutions only - applications and/or services.
- Docker facilitates containers that can host multiple heterogeneous applications/services as processes (typically only one ordinal process per container). Docker started a massive ‘containerization’ growth area for the industry presently.
- VmWare on Mac, Windows or in data centers on far bigger machines/server fits the definition of “general purpose operating system containers”. As container’s go, this (and equivalents) are very generous - a host machine with VMWare could host several other machines concurrently and those could be very different (Windows, Linux, Mac). Within those guest operating system the user would be allowed to install whatever applications services they like (subject to user permissions). This type of containment (like Docker) comes with a virtualization aspect which marginally degrades the performance of the contained/guest OS.
- Dependency Injection (DI): is a container/contained concept where the API is minimal, and exclusively refers to the world of components (aggregations of classes for a larger purpose). As DI is a container/contained thing, the contained components should not be able to get a reference to the container as the API to do so (possibly present in some general container/contained cases) should be missing in all DI cases. There also should not be a back-door way of getting a reference to the container from the contained component. JavaScript and the DOM can’t guarantee this, as that is sadly a bit of a “wild west” environment. The Spring Framework is the most well known DI container. It does use the word ‘framework’ in its name as it has connotations of “in charge” in most uses, but can also be used as a simple library.
Platforms might be super applications at one level. Multiple dissimilar processes that between them offer a range of services and user interfaces. So much so that you don’t think so much about the layer below, but only on the facade and experience of the platform itself. Platforms effectively allow multiple unrelated applications and services to run on them. Platforms may also provide a significant value-add that purports to do something in common for all of those applications services. A “data grid” is an example of that. Platforms nearly always come with a significant administrator-led configuration capability. How much customization is performed before the platform is operational for the ultimate end-users is adjustable. The purchaser/licensee (there are not too many FOSS platforms) and their assigned administrator would be doing that adjustable configuration. “Configuration only” is the simplest design for customization (see plugins below).
Examples:
- Salesforce/Force is a platform - not available for on-premises install, though.
- Amazon’s computing services are a platform - again no on-prem install. Ditto GCP and Azure.
- Jira and Confluence started life as applications but qualify as platforms these days (albeit niche). At the very least both can have significant customization and take embedded functionality (plugins, see below) at the very least from a marketplace managed by the vendor, Atlassian.
Plugins are packaged libraries, services or applications that are tied to a specific application/platform’s purpose-built API. They will most likely run inside the existing process(es) of the application or platform. Most likely they’ll be responsive to event stimuli from the implicitly containing application/platform rather than have a life of their own (including timer-based interrupts/events). Plugins cannot run outside the containing application/platform (except for in build/test loops). Installation of plugins into a running platform or application should not require a restart of that.
Examples:
- Jira and Confluence: the embedded functionality mentioned above is activated via a plugin mechanism.
- Atom, VisualStudioCode, Eclipse and Intellij take plugins, but are definitely applications and not platforms as they are single user. The latter’s plugins are facilitated by PicoContainer (that I co-created). Sadly Intellij needs a reboot:
PicoContainer did not require a reboot as JesktopApps (yours truly again) illustrates. At least if Jesktop still runs at all twelve years later.
Plugins (alternate) - As above with respect to being for applications or platforms, but using remote services to bridge the gap rather than in-process calls. The Xi editor is an example of this. One problem this approach solves easily is the one of plugins crashing and bringing down the containing process. One thing it facilitates is heterogeneous approaches to engineering the plugins, in the same way that services do.
Extensions - Really another name for plugins. I’ll focus on just one that’s actually using the word “extension” to describe the genus of plugin - Firefox’s mechanism for installing third-party bits abd pieces within it. There’s a formal “WebExtensions” API (W3C), sand-boxing, and implicit containment. A second level allows for native executables to participate in the extension mechanism. The novel aspect is that the native executable to pure Firefox extension is over stdin and stdout that is not requiring connecting a socket to a IP address & port. Mentioned before was the claim that containers should not have to be restarted if additional components are mounted within them. Historically, Firefox required a restart whenever you installed an extension within it. That is possibly because Firefox is partially written in JavaScript and there’s still a lot to be advanced there in terms of container/contained capability.