Reverse Engineering Architectural Decisions
Published: 2024-01-28 23:59:03

# **System:** Eclipse

**Design Pattern 1:**

Plugin Pattern 

**problem**

The Eclipse system and plugin is used for modular development. It  is a complex and flexible integrated development environment (IDE) used for a variety of programming languages and development jobs. It is difficult to create a monolithic application using Eclipse while remaining simple to maintain and upgrade. Also, if customers want to customize functionality then that is not provided by the IDE.

In order to tackle the problems addressed above the following approaches can be followed:

- The complexity of constructing a monolithic program can be reduced by splitting development tasks down into smaller, modular parts enabled by plugins. This modular approach to development simplifies development while also boosting maintainability and upgradeability.
- Furthermore, the extensibility feature allows users to personalize their integrated development environment (IDE) by adding or removing plugins, hence providing a better experience that aligns with their needs.

**Various elements (e.g., classes, files, data structures) involved and what is their**

**responsibility:**

The different elements are:

- **Eclipse Core**: It contains the basic design and functionality containing classes to manage the user interface, workspace, and vital services such as management of projects and code writing.
- **Plugin**: It is an independent block of operation made up of Java classes, XML configuration files, resources (such icons or templates), and extension points. Its main goal is to establish, execute, and add features to Eclipse.
- **Extension Points**: The Eclipse core defines Extension Points, which determine where plugins can provide functionality in the system are usually defined in XML files and show what kinds of extensions they expect.
- **Extensions**: These are described in XML and specify how a plugin's functionality should be integrated into the Eclipse core and are contributed by plugins to extension points.

**Constraints**

The constraints are as follows:

- **Development Guidelines**: Eclipse has specified development principles that plugin developers must adhere to. These recommendations cover things like naming conventions, version control, packaging requirements, and license terms.
- **Constraint on Core Modification:** Plugins should not modify or make changes in the Eclipse core directly. This can cause problems with compatibility and instability.
- **Clean and Stable API**: Plugins must provide a well-defined and stable API via which other plugins can interact. This promotes reusability and modularity, allowing plugins to communicate effectively.
- **Dependency Management**: Dependencies between plugins are possible and therefore it is critical to carefully manage these dependencies, suggesting which versions of other plugins are essential, to ensure that the system operates correctly.

**References and relationships between elements are as follows:**

1. **Required References and Relationships:**
- Plugins should reference and contribute to the extension points created by the Eclipse core which is necessary for plugins to integrate their functionality into the Eclipse system.
- Extensions for plugins must specify how their functionality will be incorporated into the Eclipse core.
- Sometimes plugins rely on modifications and changes based on other plugins, leading to interdependencies that augments the system's functionality.
1. **Prohibited Relationships:**
- Plugins should avoid directly changing or modifying the inner workings of the Eclipse core which can result in compatibility problems and system crashes. Instead, plugins must expand their functionalities through designated extension points for a smoother and more reliable integration.
- Furthermore, plugins should not form tight coupling with other plugins. This could create complications for the system's flexibility and ease of maintenance. Therefore plugins should communicate through well-defined, clean Application Programming Interfaces (APIs), which simplifies the process.

**Consequences: Advantages and Disadvantages that adopting this particular design pattern has on the system**

The consequences are as follows:

1. **Advantages:**
- **Modularity:** This paradigm imposes a modular structure, making it easier for developers to work independently on and maintain specific plugins. They may focus on their specific functionalities without having to deal with the full codebase. It speeds up the development and testing processes.
- **Extensibility**: Eclipse users can modify their IDE by adding or uninstalling plugins based on their individual development requirements. This versatility is a key advantage because it allows the environment to be customized to each user's specific needs.
- **Large Developer Ecosystem:** The plugin approach has aided in the development of a large ecosystem of Eclipse plugins, making it into a robust and versatile programming environment. This robust ecosystem provides developers with access to a diverse set of features and tools, enhancing their development experience.
- **Code Reusability**: The plugin structure encourages code reuse and sharing. This lowers redundancy and encourages collaborative resource sharing for development.
1. **Disadvantages:**
- **Complexity**: Problems like version compatibility, performance and conflicts gets created when there are a large number of plugins. Hence, careful version management and compatibility testing is essential.
- **Plugin Quality Control**: Poor designed plugins with bugs can cause program crashes and are unstable. Therefore the quality of plugins matter the most.
- **Plugin development**: Developing plugins for Eclipse might require a deep knowledge of the platform. Understanding Eclipse's plugin framework and following its guidelines can be challenging.
- **Dependency Management**: Creating Eclipse plugins is difficult and it is complex to make sure that the plugins logic and its functionalities does not affect the other plugins functionalities and dependencies.

_____________________________________________________________

**Design Pattern 2:**

**Observer Pattern**

The main challenge within Eclipse is to maintain various aspects of the user interface (UI) in sync with the underlying data while quickly displaying any changes. When a developer, for example, updates a source code file in Eclipse, it's important that UI elements such as editor views, outline views, and issues views quickly reflect the most recent content and errors as they occur. The needed solution allows these UI components to sync with the data and react to changes without requiring constant human checks or refreshes.

**Solution**

We can solve this problem by using the Observer Pattern. It's similar to setting up a communication system in which one entity (subject) keeps a list of others (observers) and notifies them whenever it changes. This pattern ensures that the various UI components act as observers in the Eclipse environment. They monitor things like source code documents and automatically update themselves when these documents change. This creative solution will allow the Eclipse IDE to maintain full sync with the underlying data, resulting in real-time updates in the UI components.

**Elements (e.g., classes, files, data structures) involved and the responsibility of each:**

The different elements are:

- **Subject:** In Eclipse, the subject is a document or a resource, such as a source code document whose responsibility is to maintain a list of observers (UI components) and provide methods for registering, unregistering, and notifying observers of changes.
- **Observer:** Observers are the various UI components in Eclipse, like editor views, outline views, and problems views whose responsibility is to update themselves based on the notifications received from the subject.

**Constraints :**

The subject should not be aware of its observers' existence. It communicates with observers through a common interface, which promotes loose coupling and flexibility.

Observers should be able to subscribe (register) and unsubscribe (unregister) from subjects dynamically to accommodate changes in the UI layout or user preferences.

**References and relationships between the elemenets required or prohibited in order to achieve the goals of the design pattern**

In order to achieve the goals of the Observer Pattern in Eclipse, specific references and relationships between elements are required or prohibited:

1. **Required Relationships:**
- **Subject-Observable Relationship:** It's essential to establish a one-to-many relationship between the subject (like a document or resource) and its observers (UI components). The subject keeps a list of observers, and when it undergoes changes, it lets all the registered observers know.
- **Observer-Subject Interface:** Observers (UI components) are required to follow a common interface, often named IObserver or Observer. This interface defines the methods for receiving updates from the subject. This ensures that all observers behave consistently when reacting to changes in the subject.
- **Registration and Unregistration:**The subject should offer methods for observers to sign up (subscribe) and opt-out (unsubscribe) dynamically. This allows observers to express their interest in changes and to stop observing when they're no longer interested. These registration and unregistration mechanisms are vital for the Observer Pattern to work effectively in Eclipse.
1. **Prohibited Relationships:**
- **Tight Coupling:** The Observer Pattern strictly forbids strong connections between the subject and its observers. The subject shouldn't have detailed knowledge of the specific classes of its observers. This restriction means that Eclipse discourages direct dependencies between UI components and the subject, as such dependencies can make the system less adaptable and more challenging to maintain.
- **Direct Method Calls:** Observers should avoid directly calling methods on the subject to check for changes and therefore they should rely on the subject to notify them when changes occur. This rule will ensure that observers remain passive and don't actively check the subject for updates, which could be inefficient.
- **Complex Dependencies:** The goal is to avoid complex dependencies among observers. Each observer should keep a straightforward, direct relationship with the subject of interest. This rule is consistent with Eclipse's objective of keeping its element relationship simple and readily apparent.

**Advantages and disadvantages that adopting this particular design pattern has on the system:**

1. **Advantages:**
- **Promotion of Loose Coupling**: The Observer Pattern promotes loose coupling which ensures that Eclipse's UI components do not need a detailed understanding of the subject's inner workings. This flexibility streamlines system maintenance and the addition of new elements without disrupting existing components.
- **Real-time Updates**: Within Eclipse, the Observer Pattern guarantees that UI components remain in sync with underlying data in real-time. Whenever a document or resource changes, relevant UI components update automatically. This real-time synchronization ensures a responsive and user-friendly experience, enhancing developer efficiency.
- **Enhanced Extensibility**: The Observer Pattern helps with easy integration of new UI components as observers without changing existing subjects. This extensibility is especially valuable in Eclipse's dynamic environment, facilitating the continuous integration of fresh features and tools without extensive modifications to existing components.
- **Efficient Resource Management**: The Observer Pattern contributes to efficient resource management. UI components can dynamically register and unregister themselves as observers, ensuring resource allocation to components as needed. This dynamic process prevents resource wastage and optimizes resource utilization.
1. **Disadvantages:**
- **Additional Workload:** Applying the Observer Pattern may result in increased processing, particularly when a subject has numerous observers. Notifying and updating multiple observers can consume system resources but Eclipse is well-equipped to handle this extra workload efficiently. This potential impact on performance is generally well managed in today's computing environments.
- **Risk of Memory Leaks**: Failure to correctly unregister observers when they are no longer needed might result in Eclipse memory leaks. The subject keeps track of its observers, and failing to unregister them may prevent the garbage collector from releasing resources associated with these observers. To avoid memory-related difficulties, developers must be attentive in managing the registration and unregistration of observers.
- **Added Complexity**: Implementing the Observer Pattern can add complexity to the Eclipse codebase. Developers must thoroughly understand the interactions between subjects and observers, as well as guarantee that observers function properly. In a large and complex system like Eclipse, managing these interactions can be difficult. As a result, careful design and documentation are critical to avoiding unforeseen effects such as circular dependencies or performance concerns.

______________________________________________________________________________

**Design Pattern 3:**

Singleton Pattern

In Eclipse IDE, there is a need for a consistent way to access unique instance of a certain class, ensuring that there is only one instance of the class throughout the application. For example, applications often need to create and manage database sessions, which are a means to connect to a database. Manually creating and managing these sessions is cumbersome and error-prone especially when the application needs to ensure that there is only one instance of session per configuration. The Session manager automates this process, ensuring that sessions are correctly instantiated and managed throughout the application’s lifecycle.

**Solution**

The Session Manager itself is implemented as Singleton, which means it is a globally accessible object that ensures there is only one instance of itself. The singleton pattern is used here to ensure that the Session manager and the Cached sessions can be accessed from any part of the application without creating multiple instances, which could lead to inconsistent states or overconsumption of resources.

**The participants:**

**Elements (e.g., classes, files, data structures) involved and the responsibility of each:**

The Eclipselink Session manager has several elements that work together to manage database sessions.

- **Session Manager**: This is a static utility class that acts as a central point for managing sessions in EclipseLink. It is responsible for:
    - Load sessions from a configuration file (sessions.xml).
    - Caching these sessions to prevent unnecessary information.
    - Providing a global access point to these sessions.
    - Ensuring that only one instance of each session exists.
- **xml**: This is a configuration file that describes the sessions that the Session Manager should manage. It contains the session names and their corresponding details such as database connections and settings. Its responsibilities include:
    - Defining the session configuration.
    - Specifying the session type (e.g., ServerSession, DatabaseSession, SessionBroker)
- **ServerSession**: This is a class that represents a session intended for server-side use. It is responsible for:
    - Managing connections to the database.
    - Serving as a factory for other sessions, like client sessions and unit of work
- **SessionBroker**: This is a class that acts as a broker to manage multiple DatabaseSession instances. Its responsibilities are:
    - Allowing an application to use multiple DatabaseSession instances as if they were a single session.
    - Facilitating transactions that span multiple databases.
- **DatabaseSession**: This is a class that represents a session specifically for database operations. It is responsible for:
    - Direct database connectivity and operations.
    - Transaction management.
- **ClientSession**: Although not mentioned in the initial explanation, a ClientSession would typically be a session derived from a ServerSession for client-specific operations in a multi-tiered application. It is responsible for:
    - Handling client requests.
    - Isolating client work from other clients.
- **Unit of Work**: This is a data structure that represents a transactional context for a set of database operations. It is responsible for:
    - Transaction management and isolation.
    - Change tracking and persistence.

**Constraints :**

**Singleton Constrain on Session Manager:**

- There can only be one Session Manager in the application to maintain the integrity of the session management.
- The Session Manager must be accessible from any point in the application without multiple instantiations.
- **Configuration Constraint on Session Manager:**
    - The Sessions.xml file must be well-formed and valid according to the EclipseLink schema for session Configurations.
    - It must be located in one of the expected paths (either the root of the classpath or within the META-INF directory)
- **Uniqueness Constraint on Sessions:**
    - Each session managed by Session Manager must have a unique name that serves as an identifier.
    - Only one instance of each named session can exist within the application to prevent resource conflicts and ensure consistency.

**References and relationships between elements either required or prohibited in order to achieve the goals of the design pattern:**

1. **Required References and Relationships:**
- **Reference to Configuration**: For the purpose of creating and managing session instances, the Session Manager has to be able to refer to the sessions.xml file.
- **Name-based Mapping**: The session instances that the Session Manager creates and manages must be directly related to the session names specified in the sessions.xml file. As a result, session instances can be retrieved using only their names.
- **Inheritance and Interface Implementation**: Session classes, including ServerSession, DatabaseSession, and SessionBroker, are required to implement a single interface or derive from a common base class that defines the session contract. This is necessary for polymorphism so that all sessions can be handled equally by the Session Manager.
- **Lifecycle Hooks**: To make sure that resources are handled properly, hooks or callbacks should be used to manage the lifecycle of sessions, including initialization and disposal.
1. **Prohibited References and Relationships:**
- **Direct Instantiation**: Direct instantiation of the Singleton Session Manager from outside the manager itself is prohibited. All requests for session instances must go through the Session Manager's access point.
- **Multiple References to Singleton Instance**: Multiple references to the Session Manager's Singleton instance should be avoided as this could result in multiple paths for initialization.
- **Ad-hoc Session Creation**: It is usually forbidden to create sessions that are not under the control of the Session Manager because doing so would evade the management and caching techniques and might result in inconsistent states or resource leaks.
- **Cross-Session References**: Direct references between sessions should be avoided as this may lead to difficult-to-manage dependencies that compromise scalability and maintainability. Rather, they ought to converse via the Session Manager or via shared resources under its supervision.
- **Static References to Session Instances**: Since they violate the controlled access concept of the Singleton pattern and may result in memory leaks, static or global references to session objects are forbidden.

**Consequences: what are the advantages and disadvantages of this design pattern has on the system**

1. **Advantages:**
- **Controlled Instance Creation**: Multiple instantiation of the Session Manager can be avoided by making sure that only one instance is produced. This helps prevent problems like inconsistent setups or excessive resource utilization.
- **Global Access**: It is simpler to access and manage sessions from anywhere in the application when there is a single, globally accessible point for that purpose.
- **Reduced Memory Footprint**: Compared to having several instances of the class, the memory footprint is smaller since there is only one instance of the Session Manager.
- **Enhanced Data Integrity**: The Singleton pattern facilitates data integrity by centralizing session management, which makes transactions easier to handle by directing all database interactions through a single point.
- **Ease of Configuration**: Configuring and modifying session properties becomes simpler when there is only one session management point because changes can be made there.
1. **Disadvantages:**
- **Single Point of Failure**: Within the program, the Session Manager turns into a single point of failure. The entire application may be impacted by problems with the session manager.
- **Testing Difficulties**: Because they frequently do not adhere to the dependency injection principle, singletons might be difficult to mock or stub during unit testing, which makes the tests less independent and more difficult to create.
- **Scalability Concerns**: Singleton objects have the potential to be a bottleneck in the system, particularly in applications with many threads that require simultaneous access to the session manager.
- **Inflexibility**: Since the Singleton paradigm imposes the use of a single instance, it might result in inflexibility as it becomes more difficult to extend or modify the Session Manager when application demands change.
- **Tight Coupling**: Singleton-using system components are closely linked to the particular singleton class implementation, which might complicate system modifications and compromise maintainability.

**Contributions:**

 **Rushil Desetty**

 **Mohnish Hitendrabhai Raval**

 **Abhay Joshi**