Java Architectural Events
- Domain Added/Removed
- New Common Classes Added/Removed
- New Dead Code Added/Removed
- New High Debt Classes Monitoring
- Changes in Exclusivity
- Architecture Complexity Changed
- Library Circular Dependencies
- Dependency Between Domains
- Common to Domain Dependency
- Cloud Readiness
- Compatibility with Target Technology
Architectural Events Overview
Architectural Events provide crucial insights into the changes and activities that impact an Application’s architecture. These Events help identify areas of high technical debt, monitor architectural quality, and catch potential issues before they escalate into significant problems. These Events serve as vital indicators of your Application’s architecture health, contributing to your engineering velocity, application’s scalability and rate of innovation.
Types of Architectural Events
Domain Added/Removed
This Architectural Event is triggered when a new domain is discovered or an existing one is removed. From an architectural standpoint, this is significant because it affects the overall organization and structure of the system. Understanding when and why domains are added or removed helps architects assess the evolving needs and complexity of the system.
When a new domain is added, architects should evaluate its role and ensure it is properly encapsulated to maintain the modularity of the system. It’s also important to verify that the new domain doesn’t duplicate existing functionality, in order to prevent redundancy and maintain the system’s cohesion and efficiency.
When a domain is removed, it signifies a shift in the application’s architecture. This change could be due to various reasons such as evolving business needs, optimization efforts, or refactoring. Regardless of the reason, it’s crucial for architects to review the architecture to confirm that the removal hasn’t adversely affected the coherence of the application. They should validate the boundaries of the remaining domains to ensure they’re intact, check if the responsibilities of the removed domain have been adequately reassigned, and evaluate if the removal has introduced any orphaned elements or dependencies. This analysis helps maintain the integrity and maintainability of the application architecture.
New Common Classes Added/Removed
This Architectural Event monitors when new common classes are introduced or existing ones are removed. Common classes are those used across multiple domains or functions. The misuse or overuse of common classes can lead to tight coupling and decreased modularity, so it’s important to keep track of them. If a common class is used extensively, architects should consider adding its jar to infra jars so it’s not analyzed anymore. Keeping track of how these classes are used across different domains is crucial to avoiding unnecessary dependencies and tight couplings.
New Dead Code Added/Removed
This Architectural Event signals the detection of any dead code within the application. Dead code comprises sections within the application’s source code that are inactive or non-executable during the program’s lifecycle, thereby serving no functional purpose. Such code can be pruned without jeopardizing the program’s operational integrity.
To keep the codebase clean, maintainable, and efficient, architects should implement a strategy to periodically review and clean up the codebase. The continuous detection and removal of dead code is recommended, along with other code review processes to minimize dead code creation.
vFunction utilizes dynamic analysis to detect dead code often missed by traditional static analysis tools:
- Adaptive Dead Code Recognition: vFunction identifies dead code emerging from changes in operational logic and user requirements dynamically
- Sensitive Unreachable Code Detection: It accurately flags unreachable code often mistaken as necessary due to complex dependencies or obfuscated execution paths
- Redundant Code Blocks Detection within Active Functions: vFunction finds obsolete code snippets within active functions
- In-depth Analysis of Runtime Data: The tool discovers dead code not detectable during compile-time or through static analysis, ensuring comprehensive detection
Types of Dead Code Identified:
- Unused Functions/Methods: Defined but not invoked
- Unreachable Code: Logically inaccessible during execution
While traditional methodologies include Static Code Analysis Tools, Code Coverage Tools, and Manual Code Review, vFunction’s dynamic analysis offers real-time and deeply analytical insights, providing thorough and accurate dead code detection and removal.
New High Debt Classes Monitoring
This Architectural Event tracks when High Ddebt Classes are introduced or removed. ‘Debt’ refers to architectural technical debt, which signifies the level of entanglement between domains and architectural complexity created by the specific class.
Our concept of a “High Debt Class” is distinct from the broad industry notion as it is not solely based on the usual suspects of coding flaws or design shortcuts. Instead, we focus on three key parameters to evaluate and identify a class’s architectural debt:
- Dependencies: The class should have a significant number of dependencies, indicating a high level of entanglement with other classes or components within the application
- Dependents: A high debt class in our system has multiple dependents relying on it, making it a crucial node whose failure or malfunction might have cascading effects.
- Size: We consider the absolute size of the class, not relative to the application. A high debt class under our definition is substantial in size, indicative of its encompassing complexity and potential difficulty in maintenance and modification
This approach delves deeper into the architectural intricacies and relationships within the application, offering a more nuanced understanding of the debt a class introduces to the system. To efficiently manage and mitigate technical debt, architects must prioritize the refactoring of classes identified as high debt under our refined criteria. Strategies include:
- Reducing the class’s complexity and dependencies
- Regular architectural reviews to prevent the introduction of new high debt classes
- Prioritizing these classes in the development backlog for refactoring
By focusing on classes that are architecturally significant and entangled, this approach provides a targeted strategy to control and reduce the systemic risk and maintenance overhead introduced by high debt classes, thereby promoting a healthier, more sustainable codebase in the long term.
Changes in Exclusivity
This Architectural Event monitors changes in the exclusivity of specific classes, both dynamic and static, as well as resources like database tables, transactions, spring beans, sockets, and files. Exclusivity, in this context, refers to whether a class or resource is confined to a single domain or dispersed across multiple domains.
A class or resource is deemed ‘exclusive’ if it resides within a single domain. Changes in exclusivity reflect the shifting distribution of these elements across different domains.
When a class or resource starts appearing in multiple domains, it may be indicative of an upcoming issue. In such instances, architects should undertake a careful examination to discern whether this expanded distribution is intentional and advantageous or a harbinger of architectural pitfalls like heightened coupling or encapsulation loss.
For cases where a class or resource loses its exclusivity, refactoring should be a consideration for architects. The objective of this endeavor is to restore the exclusive nature and singular responsibility of the resource or class, thereby minimizing the unnecessary creation of dependencies. By understanding and acting upon exclusivity changes in both dynamic and static classes, as well as resources, architects can safeguard the integrity and efficiency of the application’s architecture.
Dynamic Class Exclusivity Changes
Monitoring exclusivity changes in dynamic classes is crucial as it allows architects to identify and respond to runtime modifications that could introduce instability or security risks to the system. Understanding these changes enables the timely mitigation of potential issues and ensures the consistent and secure performance of the application.
Static Class Exclusivity Changes
Monitoring exclusivity changes in static classes is invaluable for maintaining a coherent and tightly-knit architecture. It helps in tracking unintentional dependencies and coupling introduced during the development phase, promoting cleaner code and facilitating easier maintenance and debugging processes.
Resource Exclusivity Changes
Resources, such as database tables and files, play a pivotal role in the system’s functionality. Monitoring their exclusivity is fundamental for ensuring data integrity and system performance. When a resource that is typically exclusive starts appearing in multiple domains, it could indicate data redundancy, potential data conflicts, or increased load on the resource. Understanding and addressing these exclusivity changes in resources is vital for preventing data-related issues and maintaining the system’s overall health and efficiency.
Architecture Complexity Changed
An application’s architectural complexity reflects the effort required to maintain and refactor its architecture. This complexity is computed as a weighted average of five crucial metrics, each contributing differently to the overall calculation. The architectural complexity changes event is triggered whenever there is a shift in this computed value, either an increase or decrease.
Calculating Complexity:
- Infrastructure Complexity: The complexity arising from the application’s infrastructure components and their interactions
- Topology Complexity / Domain Topology: The complexity inherent in the application’s structural design and the connections between its various elements
- Resource Exclusivity: A measure of how exclusively resources are utilized within the application, with lower exclusivity indicating higher complexity
- Class Exclusivity: The degree to which classes are confined to specific domains, with less exclusivity leading to increased complexity
- Extracted Percentage: The proportion of the application that has been refactored or extracted, influencing the ease of future refactoring efforts.
To navigate through the potential challenges of heightened complexity, architects should actively work to simplify areas identified as highly complex. This simplification process involves:
- Refactoring code to make it cleaner and more manageable.
- Promoting the adoption of simpler design patterns.
- Utilize software metrics to quantify complexity and set acceptable thresholds.
By proactively addressing areas of high complexity, architects can facilitate smoother maintenance and refactoring processes, ultimately fostering the development of more robust and manageable applications.
Library Circular Dependencies
Architectural events continually emphasize the importance of understanding the evolution and health of an application’s architecture. One of the pivotal events, especially in systems based on modular architectures and internal Jars. Such dependencies can manifest as bi-directional arrows in the dependency graphs, indicating that two or more Jars are interdependent either directly or through a series of intermediaries.
Circular dependencies introduce a set of challenges in applications. For instance, they can lead to initialization problems, ambiguous designs and can complicate the module upgrade or replacement processes. These dependencies might affect the startup order or even cause runtime failures, particularly in dynamic module systems. Recognizing and addressing such dependencies is pivotal in ensuring the system’s maintainability and resilience.
When a circular dependency is detected architects should delve deep to understand the reasons behind such a dependency. Often, it’s an unintentional result of incremental changes or rapid development without adequate architectural oversight.
It’s crucial to assess if this dependency introduces redundant functionality or if it’s a manifestation of domain overlap. These insights can guide refactoring efforts to break the circular chain. Beyond just identification, it’s beneficial to have a visual representation of these dependencies. An isolated graph, highlighted with an orange dashed line, focusing solely on the circular chain can be a powerful tool for architects. It allows them to grasp the extent of the issue and strategize a resolution without being overwhelmed by the entirety of the dependency graph.
Addressing these dependencies head-on ensures that the application’s architecture remains modular, maintainable, and free from intricate entanglements that can stifle innovation and scalability.
Dependency Between Domains
The risk of tightly coupled domains can lead to significant challenges, understanding and managing dependencies is key to ensuring stability and resilience. By highlighting new or altered dependencies, architects can take steps to mitigate these risks, leading to a more robust and reliable system. By identifying unnecessary or inefficient dependencies, architects can simplify interactions between domains, leading to improved domain exclusivity.
The event focuses on new dependency, recommending action to analyze and potentially refactor it. For an application architect, understanding these dependencies is crucial for ensuring that the architecture is both efficient and robust. This visibility not only aids in identifying current dependencies but also in tracking changes over time, enabling architects to anticipate potential issues and opportunities for optimization.
With a clear view of the dependencies, architects are better equipped to make decisions regarding refactoring, restructuring, and extracting domains. This is particularly important in scenarios where new dependencies emerge, as these changes have implications for the overall architecture of the application. With this information, architects can plan and execute changes more effectively, allowing them to prepare for future changes and challenges.
Leveraging the insights provided by this event, architects can navigate the complexities of application architecture with greater confidence and precision, leading to more successful and sustainable applications.
Common to Domain Dependency
Focused on the enhancement of compile-time dependencies management, this event identifies and addresses dependencies involving common classes at the entry points of applications. Its primary function is to ensure that compile-time dependencies are tracked and managed, effectively avoiding any oversight. Continual tracking is essential in maintaining the modular structure and cohesiveness of the application architecture, which is crucial for its overall health and efficiency.
In scenarios where an entry point is established with a dependency on a common class at compile time, highlighting the urgent need for attention and resolution to these dependencies is critical. There’s a risk that these dependencies might go undetected and unresolved. Such an oversight can lead to architectural inefficiencies and, subsequently, an increase in technical debt.
One of the key strengths of this event is its capability for automatic detection, playing a key role in early intervention. This proactive approach to managing these dependencies through the event is essential in reducing the likelihood of accumulating technical debt. By ensuring early detection and timely resolution, keeping the application architecture efficient and aligned with best practices.
Cloud Readiness
Cloud Readiness is an architectural event that highlights the degree to which an application is prepared for the transition to cloud environments. It is a critical aspect of modern software architecture, given the increasing reliance on cloud platforms for scalability, flexibility, and efficiency.
Applications should follow the key principles of cloud-native design, such as microservices architecture, containerization, and DevOps practices. This event relies on existing technologies and frameworks in the application and provides actionable insights into the cloud readiness of a certain domain. By alerting about the readiness of application domains for cloud environments, it aids in identifying areas that require changes or improvements to leverage cloud capabilities effectively.
This event is based on rules and guidelines derived from established cloud readiness frameworks and tailored to the specific needs of the application. Cloud readiness is not a one-time event but a continuous process. Regular evaluations and updates are necessary to ensure that applications remain aligned with the latest cloud technologies and methodologies.
Compatibility with Target Technologies
Users have the ability to specify target technologies for both domains and applications, enabling the customization of cloud migration plans and strategies. Viper accurately identifies the source technology, and pinpoints any discrepancies to generate TODOs that address specific target technologies.
Target technologies can be designated at both the application and domain levels, providing granular control over your technology roadmap. If a domain is assigned a specific target technology, it will exclusively follow this selection, bypassing any application-level technology settings.
TODOs are created based on the chosen target technology. This ensures that users are presented with TODOs directly relevant to their current, whether that’s at the domain or application level.
To receive Notifications about Compatility Events with Target Technologies:
- Log into the vFunction Server UI
- Click Observation on the top, center menu bar
- Click the Pencil Icon on the left-hand sidebar to set up or edit a Schedule
- Check the Compatibility checkbox in the center column’s Architectural Events to Follow
- Toggle the Compatibility Events to Follow slider in the right-hand column’s Settings
- Select all Target Technologies you are interested in following, e.g. Azure AKS, Jakarta, Hibernate Search, etc.
- Click the blue Confirm Changes button on the bottom, right of the dialog box
To configure specific Technologies per Domain:
- Log into the vFunction Server UI
- Click the Analysis tab in the top, center menu bar
- Click on a Domain in the center pane’s graph
- Choose the relevant options from the Select Target Technology for the Domain dropdown menu in the Domain Configuration dialog box
- Click the blue Save button in the dialog box
To see a list of TODOs based on the Target Technology:
- Log into the vFunction Server UI
- Click Analysis in the top, center menu bar
- Select the List Icon in the top, right menu bar
- Select the relevant Technology from the Events dropdown menu in the right-hand TODOs pane
See a demonstration video of this feature.