Welcome to MasterPiece documentation!

Masterpiece - A Piece of Work

Masterpiece™

Welcome to Masterpiece™ - Quite a Piece of Work!

Masterpiece™ is a Python framework designed for creating modular, scalable, plugin-aware, multi-threaded, and object-oriented IoT applications — and even non-IoT applications!

Note: While Python’s Global Interpreter Lock (GIL) might make multi-threading a challenging topic for some developers, I trust the Python community will continue to evolve and address these concerns over time.

Goals

The primary goal of Masterpiece™ is to have fun while learning the Python ecosystem!

Please note: This is an alpha release. It is not ready for production use. Please experiment, explore, and provide feedback, but avoid using it for critical applications!

Design Concepts and Features

  • MQTT Communication: Enables seamless communication between components using the MQTT protocol, ideal for distributed systems.

  • Pythonic Purity: Adheres to Python conventions, ensuring idiomatic, readable, and maintainable code.

  • First-Time Excellence: Designed to be reliable, correct, and efficient from the start—while keeping things fun!

  • Completeness: A minimal yet robust API that gives developers total control over all aspects of their applications.

  • Productivity: Highly modular and reusable codebase to achieve maximum functionality with minimal effort. Productivity grows with the size of the project.

  • Proper Abstraction: Provides clean abstractions for essential third-party libraries, shielding application code from underlying framework changes.

  • User Interface/Time Series Support: Leverages InfluxDB V3 for time-series databases, enabling seamless integration with third-party visualization tools like Grafana.

Project Status and Current State

Here’s what’s currently available in Masterpiece™:

  • Absolutely Bug-free Status!: Just kidding—there are no known bugs (so far).

  • Wiki: The initial Wiki pages are under construction. Visit the Masterpiece Wiki.

  • Tutorial: A tutorial to help you get started with building your masterpieces.

  • Package Infrastructure: The Python package setup is finalized, using pyproject.toml.

  • Classes: Existing classes have been finalized and tested in a production environment.

  • Example Application: A sample application (examples/myhome.py) prints out its instance structure when run. Despite its simplicity, it demonstrates the structure of a typical scalable and fully configurable software.

  • Plugin Projects: Several plugin examples, such as masterpiece_plugin, which adds a “Hello World” greeting to myhome.py, demonstrate minimal yet functional plugin implementations.

  • MQTT API: Enables communication between all Masterpiece™ objects.

  • InfluxDB V3 Time Series: Supports writing and reading from time-series databases.

  • Serialization: Built-in support for JSON serialization, with options to extend to other formats via plugins.

  • : And probably more features I’ve forgotten while writing this.

Projects

Masterpiece comes in a set of Python projects:

  1. Masterpiece (core framework):

This is the core framework for building plugin-aware, multi-threaded applications. It includes a simple yet fully functional application to help you get started and serves as a plugin-aware reference application that can be scaled up to any size.

  1. Masterpiece Plugin (plugin example):

This is a basic plugin example that demonstrates how to create third-party plugins for applications built using Masterpiece. It’s as simple as saying “Hello, World!”, literally.

  1. Masterpiece XML Format plugin::

Plugin that adds XML serialization format support to Masterpiece.

  1. Masterpiece Yaml Format plugin::

Another format plugin. Adds Yaml support to Masterpiece.

  1. Masterpiece Influx::

Support for InfluxDB V3 time series database.

  1. Masterpiece Paho MQTT::

Support for Paho Mosquitto MQTT.

Installing Masterpiece

Step 1: Install Masterpiece and run the example application

To install the core framework:

pip install masterpiece

Then, navigate to the example folder and run the application:

python examples/myhome.py

The application will print out its instance hierarchy. This is a simple example application to demonstrate the basic structure of any multi-threaded, plugin-based, scalable MasterPiece applications.

Example output:

home
    ├─ grid
    ├─ downstairs
    │   └─ kitchen
    │       ├─ oven
    │       └─ fridge
    └─ garage
        └─ EV charger

Step 2: Install the desired Masterpiece Plugins

To extend the application with the say masterpiece_plugin:

pip install masterpiece_plugin

Run the application again:

python examples/myhome.py

You’ll now see a new object in the instance hierarchy, along with a friendly “Hello, World!” object.

Example output:

home
    ├─ grid
    ├─ downstairs
    │   └─ kitchen
    │       ├─ oven
    │       └─ fridge
    ├─ garage
    │   └─ EV charger
    └─ Hello World - A Plugin

Step 3: Configurating

The application also demonstrates the usage of startup arguments. Run the application again:

examples/myhome.py --init --solar 10 --color red

and new ‘Solar plant 10 kW’ object appears in the tree.

  • The --init argument tells the application to save its current configuration to a configuration files.

  • The --solar argument creates an instance of a solar power plant with a specified peak power of 10 kW.

  • The --color argument can be used for setting the color for the tree diagram.

The above class properties (and many more) can also be defined in the class configuration files. By default, the configuration files are created in the ~/.myhome/config folder, as determined by the application identifier and --config [anyname].

For example, --config temp will use the configuration files stored in the ~/.myhome/temp/ folder.

What’s next

Congratulations! You’ve successfully installed Masterpiece, extended it with a plugin, and explored its configuration system. But what is all this for?

That part is up to your imagination. Here’s what you can explore next:

  • Write Plugins: Develop your own plugins to extend Masterpiece with domain-specific functionality. Use the masterpiece_plugin as a starting point for inspiration.

  • Leverage Configurations: Take advantage of configuration files to fine-tune your application’s behavior without changing the code. Experiment with the –config argument to manage multiple configurations for different scenarios.

  • Design a Custom Application: Build a unique application that fits your needs by combining existing plugins, creating new objects in the instance hierarchy, and integrating external services or data sources.

  • Contribute to the Community: Share your plugins or improvements with the Masterpiece community.

Masterpiece provides the building blocks. Where you go from here is entirely up to you. Happy coding!

Contributing

Please check out the Masterpiece Issue Board for tracking progress and tasks.

Developer Documentation

For full documentation and usage details, see the full documentation at Documentation Index (The docs may look rough; I’m still unraveling Sphinx’s mysteries).

Special Thanks

Big thanks to the generous support of [Mahi.fi](https://mahi.fi) for helping bring this framework to life.

MIT License

Copyright (c) 2024, Juha Meskanen

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE

Contributing

Thank You!

Thank you in advance for your forthcoming contributions, whether they are bug fixes, documentation improvements, entirely new features, or simply feedback. Your efforts will be highly appreciated and will help turn this project from its current mission state into an actual masterpiece.

Design Patterns

Please read the developer documentation and understand the few design patterns before contributing. This will help ensure that your contributions align with the project’s design and goals. .. todo:: (okay, the documentation is currently lacking many essential chapters, add.)

Code Formatting

To help maintain consistent code formatting across different developers, we use ‘black’ python formatter, by Microsoft.

Strange, the formatter doesn’t seem to do that much, it doesn’t organize imports, doesn’t adjust docstring lenghts .. todo:: most likely I don’t know how to use it properly, read the docs.

Using Emacs and Makefile

Despite my attempts to fall in love with Eclipse, VSCode and other IDEs, I still find Emacs and Makefile the best tools for many of my workflows. So there is a Makefile in the root folder. For those old dogs who are like me

make help

Unit tests

Todo

write unit tests

CHANGELOG

[0.1.12] 12.1.2025

  • Useless “Loading plugin …” logging message fixed, it shows now the actual name of the loaded plugin class.

  • Redundant “pyyaml” dependency removed from ‘pyproject.toml’.

[0.1.11] 11.1.2025

  • New method read_last_value() added. Retrieves the most recent data point from a specified time series measurement. The method allows the software to easily query its last known state from the time series database, simplifying state recovery and continuity across application restarts.

[0.1.10] 5.1.2025

Nothing spectacular in this release—just a few minor bug fixes and improvements. The code appears to run fine as part of my home automation project, with no issues detected. However, there’s still a lot to be done with type hinting and documentation.

  • Fixed intermittent issues with VSCode and Sphinx integration. Added a sphinx target to the root ‘Makefile’ as a workaround for when VSCode reports incorrect errors. Also removed some docstrings that appeared perfectly fine to me but not to Sphinx (find myself wasting too much time searching for Sphinx/rst format-related bugs)

  • Corrected syntax errors in .rst files. Linked the orphan tutorial.rst and plugintutorial.rst to the root document.

  • Refactored the MasterPieceThread class for better modularity and code clarity.

  • Fixed a few mypy warnings in unit tests.

[0.1.9] 3.1.2025

  • A couple of Pypi warnings sorted out.

  • MasterPieceThread class supports Built-in tests (system-status).

[0.1.8] 30.12.2024

First ‘Alpha’ release:

  • Version elevated to 0.1.8 and Python Development Status elevated to 3 - Alpha.

  • Obsolete Yaml dependencies removed from ‘pyproject.toml’

[0.1.7] 30.12.2024

MasterPieceThread: class added with. This class is both a Thread and MasterPiece, with optional MQTT client for communication.

[0.1.6] 29.12.2024

Logging Level control :

  • Configuration files were read twice, fixed.

  • Logging level can be controlled through -l (–log-level) startup arguments. accepts the standard log levels: DEBUG, INFO, WARNING, ERROR, CRITICAL

Interface to MQTT:

  • Added an interface to MQTT. The module mqtt.py implements two abstract base classes: Mqtt and MqttMsg. These abstractions allow integration with any Mqtt pub-sub implementation, such as Paho Mosquitto.

    Example of the API:

    To publish:

    m = {
      "tmp": {"value": 22.5},  # Room temperature value
      "sensor": {
        "vibration": True,  # Vibration status
        "motion": False,  # Motion status
      },
        "unixtime": int(time.time()),
      }
    
    self.publish("mytopic", json.dumps(m), 1, True)
    

    To subscribe:

    mqtt.subscribe("mytopic")
    

Interface to Time Series:

  • Added an interface to time series databases. The module timeseries.py implements two abstract base classes: TimeSeries and Measurement. These abstractions allow integration with any time series implementation, such as InfluxDB.

    Example of the API:

    point = (
      self.measurement("motion")
        .tag("sensor", "livingroom")
        .field("motion", motion)
        .field("vibration", vibration)
        .field("roomtemp", roomtemperature)
        .time(epoc2utc(timestamp))  # Converts epoch to UTC timestamp
    )
    self.write(point)
    

    Alternatively, you can use the dict data structure to record measurements:

    measurement: dict[str, Any] = {
      "measurement": "motion",
      "tag": {"sensor": "livingroom"},
      "field": {
        "motion": motion,
        "vibration": vibration,
        "roomtemp": roomtemperature
      },
      "time" : epoc2utc(timestamp),
    }
    self.write(measurement)
    

[0.1.4] 17.12.2024

stable-0.1.4: New stable release with minor improvements and bug fixes:

  • Type-hinting: completed and py.typed file added to indicate that the package supports PEP 561 type hints.

  • PluginManager: The add() method of the Composite class now accepts None as a parameter. In such cases, it raises a ValueException. For example, calling self.add(self.instantiate_plugin_by_name(“SomePlugin”)) will now properly terminate the application if the plugin is not installed.

  • @override: decorator imported from typing_extensions rather than from typing, for Python 3.9 backward compatibility.

  • YamlFormat: The YAML serialization format functionality has been removed from the core framework and implemented as a separate plugin project, masterpiece_yaml.

  • Traversing the hierarchy:

    URL class: A new class for instance name-based identification of objects within hierarchical

    tree structures.

    make_url() Method: Generates hierarchical paths for any object in the instance hierarchy.

    resolve_url() Method: Locates objects by their URL.

  • print():

    Method visualizing the instance hierarchy moved from the example/myapp.py to application.py base class. Originally initiated as a demonstrative piece of code, but turned out to be a valueble feature for any MasterPiece application.

[0.1.3] - 4.11.2024

  • stable-0.1.3: First release tagged with stable prefix. When a Git tag is prefixed with stable, the masterpiece CD/CI pipeline deploys the package to the PyPI repository.

  • Development Status :: 2 - Pre-Alpha: PyPi classifier elevated from Planning to Pre-Alpha

[0.1.0] - 3.11.2024

  • Version elevated to 0.1.0: The plugin API has been successfully tested with two separate plugins and confirmed to work. Hooray!

  • classattrs_to_dict(): Who knew iterating over class attributes in Python could be so tricky? Fixed—yes, really!

[0.0.9] - 2.11.2024

  • Tutorial: - Exceptionally well written world-class tutorial covering the basics and essential features, I hope.

  • Bug Fixes: - PlugMaster class attempted to instantiate classes not subclassed from the Plugin class. - Exception when issubclass() was called with class that was not registered. - several bugs fixed in both load_configuration() and save_configuration(). - save_configuration() failed to save because it opened the file for reading, fixed. - is_abstract() class method removed, use inspect.isabstract() instead.

[0.0.7] - 1st 11.2024

  • Milestone Achieved: Despite the modest version increment, this release brings substantial structural, architectural, and functional improvements. With the release of version 0.0.7, I’ve completed my first two major milestones for the project — definitely a cause for celebration!

  • Directory Structure Finalized: Removed the core directory; all classes are now organized under masterpiece/masterpiece/*.py. (Feeling like I’m evolving from a C++ boomer to a proper Pythonista!)

  • @classproperty: A decorator class implemented as a replacement for Python’s decision to deprecate the combination of @classmethod and @property. This decorator addresses the fundamental principle of object-oriented programming: any software is essentially composed of code and data (attributes and methods), which can be either class-specific or instance-specific. Given this, it is logical to have @property for instance-specific attributes and @classproperty for class-specific attributes.

  • Serialization API Finalized: Decoupled hard-coded JSON serialization, implementing it as a separate JsonFormat class. This is the default serialization format for the Application class decoupling also the format from the stream: any data can be formatted to any stream.

  • YamlFormat Added: Implemented YAML serialization format, which can be selected with the startup option --application_serialization_form YamlFormat.

  • Logging Improved: Supports both class and instance methods, enabling both Foo.log_error(...) and foo.error(...) syntax.

  • Unit Tests Enhanced: Coverage significantly improved, now reaching approximately 90%.

[0.0.6] - 26.10.2024

  • Code and Data Decoupling: Hardcoded print() methods have been removed from core classes and re-implemented using the new do() method.

  • ArgMaestro: A class for fully automated class attribute initialization through startup arguments. Allows any public class attribute to be initialized using the –classname_attributename [value] convention. The class name is admittedly ridiculous, consider changing it.

  • Unit Test Coverage Improved: Unit tests have been enhanced to a level where they provide meaningful test coverage.

  • Logging Typos Fixed: All strings have been proofread and typos corrected.

[0.0.5] - 20.10.2024

  • New startup argument –init: If given, all classes in the application will create configuration files for their class attributes, if those files don’t already exist. These configuration files allow users to define custom values for all public class attributes.

  • Rotating Logs: The FileHandler has been replaced with TimedRotatingFileHandler, initialized with parameters when=’midnight’, interval=1, and backupCount=7 to rotate the log file daily and keep 7 backup files. This change resolves the issue of log files growing indefinitely, which could eventually lead to the system running out of disk space.

  • Documentation Refactored: All .rst files have been moved from Sphinx’s docs/source directory to the project root folder for GitLab compatibility.

  • Time Functions: The methods epoc2utc(), timestamp(), epoc2utc() and a few others removed. These were not actually methods of the Masterpiece class since they did not require any instance attributes. More importantly, this change aims to keep the Masterpiece framework focused on its core functionality.

[0.0.4] - October 18, 2024

  • MasterPiece: Undefined class attribute _class_id, added.

  • MetaMasterPiece Refactored: Replaced with a more lightweight __init_subclass__() solution, with special thanks to Mahi for his contribution.

  • Plugin Class Abstracted: The plugin class is now subclassed from ABC to formally implement an abstract base class.

  • Pylint Warnings Resolved: Fixed issues such as long lines, which have been split for better readability.

  • Docstrings Improved: Added more comprehensive documentation with a professional tone for several methods.

[0.0.3] - October 12, 2024

  • From C++ boomer to Python professional: Directory structure simplified:

    • src folder removed

    • masterpiece/base folder renamed to masterpiece/core

    • plugins folder moved outside the project, will be implemented as a separate project (one project - one repository principle)

    • Minor additions and improvements to Docstrings.

[0.0.2] - October 10, 2024

  • GitLab Ready: Revised documentation tone slightly to reflect a more professional and serious nature. Removed excessive humor that may have detracted from the perceived professionalism of the toolkit.

[0.0.1] - August 4, 2024

Pip release with Python pip package uploaded.

New Features and Improvements:

  • Trademark: Cool (not?) slogan: Masterpiece - Quite a piece of work

  • Plugin API: Enhanced the plugin API with two classes: Plugin and PlugMaster with compatibility with Python versions 3.8 and later. The most recent version tested is 3.12.

  • Meta-Class Automation: Per-class bureaucracy automated using Python’s meta-class concept.

  • Folder Structure: Redesigned for future expansion. There is now separate root folders for core and plugin modules.

  • Base Class: Added new base class for MasterPiece applications in base/application.py.

  • Example Application: Added examples/myhome.py to demonstrate the general structure of MasterPiece applications.

  • Startup Argument Parsing: Added API for parsing startup arguments.

  • Serialization API: Fully featured serialization with backward compatibility support implemented.

  • Documentation: Added comprehensive docstrings to numerous classes, aiming for fully documented professional Python code.

  • Type Annotations: Added type annotations to numerous previously non-typed method arguments, moving towards a fully typed Python code.

  • Sphinx conf.py: Created default Sphinx conf.py file in the masterpiece/sphinx folder.

  • Bug Fixes and Improvements:

    • Added encoding=”utf-8” to open() calls

    • Added exclude __pycache__ to MANIFEST.in, to avoid including the folders with the setup.

[0.0.0] - May 31, 2024

Initial, private release (minimal set of classes unified from the RTE and JUHAM Python applications).

  • Base Class Draft: Initial version of the MasterPiece and Composite classes.

  • Python Packaging: Python package infrastructure setup using pyproject.toml, installable via pip.

  • Documentation:

    • Added LICENSE, README, and other standard files in .rst format.

    • Developer documentation autogenerated with Sphinx toolset. Support for Doxygen dropped.

  • Project Name: Named the project ‘MasterPiece™’, with a note that ‘M’ currently stands for mission rather than masterpiece.

  • Miscellaneous: Some unconventional use of the Python programming language.

TODOs for MasterPiece

This will be an exceptionally well structured priorized list of TODOs:

  • Docstrings contain many TODO:s which Sphinx should pick up and include with this file. Does not, fix please.

  • The docs/conf.py file contains both masterpiece framework-specific and plugin-specific information (e.g., copyright and author). Copying the entire conf.py to every project built on masterpiece is a bad habit. Implement a base configuration class from which plugin developers can derive their own conf.py files, containing only plugin-specific info (DRY principle).

The following items have been extraced from the source code:

Todo

write unit tests

(The original entry is located in ../CONTRIBUTING.rst, line 44.)

Mastering the Piece

This tutorial covers the examples/myapp.py application to help you get started with writing world-class masterpieces.

Prerequisites

Fetch the Masterpiece core framework and the plugin:

git clone https://gitlab.com/juham/masterpiece.git
git clone https://gitlab.com/juham/masterpiece_plugin.git

Navigate to the masterpiece/example folder and open the example application in your favorite editor (Emacs, anyone?):

emacs examples/myhome.py

MyHome Application

The main() function of masterpiece Application is as follows:

from myhome import MyHome

def main() -> None:
    # configure  classes
    MyHome.init_app_id("myhome")
    MyHome.load_plugins()
    Application.load_configuration()

    # instantiate
    home = MyHome("home")

    # run
    home.run()

Importing Masterpiece Classes

The first lines of code import the classes used as building blocks in myapp.py.

from masterpiece import Application, MasterPiece, Composite, TreeVisualizer

Application Identifier

The main function initializes the application with an appropriate “application identifier,” a string that describes the software’s purpose.

def main() -> None:
    MyHome.init_app_id("myhome")

This identifier determines where the application reads its configuration files and enables plugins to be written for applications.

Note: The application identifier is not the application name! It’s something shared by all related applications, for example, representing a software “family” or company if multiple applications share the same architecture.

Loading Plugins

If desired, load plugins with:

MyHome.load_plugins()

The plugin discovery uses Python’s importlib.metadata API. Every Masterpiece project can define project entry points in its pyproject.toml file:

[project.entry-points."masterpiece.plugins"]

Then, a plugin can specify the entry-points it can expand - in its entry points in pyproject.toml:

helloworld_plugin = "masterpiece_plugin:HelloWorld"

This example shows that the masterpiece_plugin was written for any Masterpiece application, relying only on core Masterpiece framework features.

Applications should (in fact, must) introduce application-specific entry points to allow plugins tailored to them.

Configuring Application

Application configuration involves setting class attributes, done either through class-specific configuration files or startup arguments, and loaded with:

Application.load_configuration()

Configuration files are found in:

~/.[app_id]/[configuration]/[classname].[ext]

where [app_id] is the application identifier. [configuration] is config by default but can be changed with the –config startup switch, allowing different configurations (e.g., production vs. test).

Each class has a configuration file ([classname]) with format-specific extension ([ext]), usually JSON. YAML is also supported, and plugins can introduce more formats. Select the desired one with:

python myapp.py --application_serialization_format 'YamlFormat'

This demonstrates the factory method pattern, where implementations are chosen through configuration.

If there are no configuration files, the application can generate default ones with:

python myapp.py --init

This creates a new set of configuration files at ~/.myapp/config/, using default values.

Creating the Application

Once classes have the desired properties, the main function can instantiate them:

home = MyHome("myhome")

This creates a MyHome application instance named “myhome”.

Running the Application

Applications perform operations in the run() method.

home.run()

For example, myapp.py prints out the instances in the application:

home
    ├─ grid
    ├─ downstairs
    │   └─ kitchen
    │       ├─ oven
    │       └─ fridge
    ├─ garage
    │   └─ EV charger
    └─ Hello World - A Plugin

The Application Class

Masterpiece is object-oriented, meaning that components should be proper classes. For instance, MyApp:

class MyHome(Application):
    # class attributes
    solar: float = 0.0
    color: str = "yellow"

    def __init__(self, name: str = "myhome") -> None:
        super().__init__(name)
        # instance attributes
        self.create_home()
        self.install_plugins()

[snip]

MyHome inherits from Application, gaining features like plugin support, class attribute configuration, serialization, and startup argument handling, just to name a few.

Configure public class attributes (solar and color) via the ~/.myhome/config/MyHome.json file:

{
    "solar": 10.0,
    "color": "yellow"
}

or via startup arguments:

myhome --myapp_solar 20 --myapp_color "red"

Configuration priority:

  1. Startup arguments, if defined

  2. Configuration files, if present

  3. Hard-coded values

Modeling Reality

Real-world objects are hierarchical. The Masterpiece framework models this with the Composite class, allowing MasterPiece or Composite objects to be added as children. Application classes can also be a Composite.

Methods like create_power_grid() demonstrate this:

def create_power_grid(self):
    grid = MasterPiece("grid")
    self.add(grid)

The method inserts ‘grid’ object into the application as a children.

This creates an “ownership tree,” where the application can robustly manage resources and serialize the hierarchy.

Visualizing the Hierarchy

The run() method has two parts:

def run(self) -> None:
    super().run()
    self.print()

def print(self):
    visualizer = TreeVisualizer(self.color)
    visualizer.print_tree(self)

Note that we could put the code in print() method into the run() method, after all, it is just two lines of code needed to print the hierarhcy. However, this would be bad programming practice! By putting printing specific code into a separate print() other applications sub-classed from ours, can easily override the print() method, if they choose to do so.

Note also that Masterpiece objects, including applications, can host “payload” objects. Therefore, always pass run() to the superclass.

Implementing Plugins

The framework encourages focusing on plugins rather than traditional applications. Applications should implement only the minimal infrastructure required, leaving features to be handled as plugins.

The next tutorial covers this topic in depth: Implementing Plugins

Implementing Plugins

Introduction

The framework strongly encourages not to write applications but plugins.

Applications should implement the minimal infrastructure required for the application in question.

All the features should be implemented as independent plugins, that can be installed, or not to be installed.

Each plugin should implement one self-contained and complete feature. If you install it, then you get a new feature in your application. If you uninstall it, then the application will not have a single piece of information related to the feature in question.

An example of a good plugin is a new serialization format, e.g., XmlFormat. Once installed, the user will have an option to use it:

anyapp --application_serialization_format XmlFormat

This will be the topic for the next tutorial Implementing plugins.

Object-Oriented Philosophy

Using this design, productivity increases with the size of the application because the number of reusable components increases over time, making it faster to implement new features.

  1. Reusable Components: As more plugins are developed, each representing a discrete feature or capability, the pool of reusable components increases. This allows developers to leverage existing plugins when building new features, reducing the time and effort required for implementation.

  2. Simplified Development: With a plugin architecture, teams can work on different plugins simultaneously without stepping on each other’s toes. This parallel development not only speeds up feature delivery but also encourages innovation, as teams can focus on specific areas of functionality.

  3. Easier Maintenance and Upgrades: Since plugins are independent, updating or replacing one feature does not necessitate a complete overhaul of the application. This modularity makes maintaining and upgrading the application more manageable, which is particularly valuable in larger systems.

  4. Scalability: As the application scales, the modular nature of plugins makes it easier to manage complexity. New features can be added incrementally, allowing for gradual enhancement of the application without overwhelming the development team or introducing bugs.

  5. User Customization: Users benefit from the flexibility to choose which features they want to include in their application, making it easier for them to tailor the software to their specific needs without requiring extensive modifications.

Implementing XML Format Plugin

TBD

Classes

Inheritance diagram of masterpiece.masterpiece, masterpiece.composite.Composite, masterpiece.application.Application, masterpiece.plugin.Plugin, masterpiece.plugmaster.PlugMaster, masterpiece.argmaestro.ArgMaestro, masterpiece.log.Log, masterpiece.treevisualizer.TreeVisualizer

Index