Cross cutting concern example

Before understanding the Crosscutting Concern, we have to understand the Concern.

A Concern is a term that refers to a part of the system divided on the basis of the functionality.

There are two types of concerns:

  1. The concerns representing single and specific functionality for primary requirements are known as core concerns.
    OR
    Primary functionality of the system is known as core concerns.
    For example: Business logic
  2. The concerns representing functionalities for secondary requirements are referred to as crosscutting concerns or system-wide concerns.
    OR
    The crosscutting concern is a concern which is applicable throughout the application and it affects the entire application.
    For example: logging, security and data transfer are the concerns which are needed in almost every module of an application, hence they are cross-cutting concerns.

Courtesy

enter image description here

This figure represents a typical application that is broken down into modules. Each module’s main concern is to provide services for its particular domain. However, each of these modules also requires similar ancillary functionalities, such as security logging and transaction management. An example of crosscutting concerns is "logging," which is frequently used in distributed applications to aid debugging by tracing method calls. Suppose we do logging at both the beginning and the end of each function body. This will result in crosscutting all classes that have at least one function.

(Courtesy)


i found this very clear from Wikipedia:

if writing an application for handling medical records, the indexing of such records is a core concern, while logging a history of changes to the record database or user database, or an authentication system, would be cross-cutting concerns since they interact with more parts of the program.

Examples of concerns that tend to be cross-cutting include:

Business rules

Caching

Code mobility

Data validation

Domain-specific optimizations

Error detection and correction

Internationalization and localization which includes Language localisation

Information security

Logging

Memory management

Monitoring

Persistence

Product features

Real-time constraints

Synchronization

Transaction processing

Context-sensitive help


I think the single best example of a cross-cutting concern is transactional behavior. Having to put try-catch blocks with commit and rollback calls in all your service methods would be repellent, for instance. Annotating the methods with a marker that AOP can use to encapsulate them with the desired transactional behavior is a big win.

Another good candidate as an example of a cross-cutting concern is authorization. Annotating a service method with a marker that tells who can call it, and letting some AOP advice decide whether to allow the method call or not, can be preferable to handling that in service method code.

Implementing logging with AOP advice could be a way to get more flexibility, so that you can change what gets logged by changing a joinpoint. In practice I don't see projects doing that very often. Typically using a library like log4j that lets you filter by logging-level and category, at runtime if you need to, works out well enough.

A core concern is a reason that the application exists, the business logic that the application automates. If you have a logistics application that handles shipping freight, figuring out how much cargo you can pack on a truck or what's the best route for the truck to take to drop off its deliveries might be core concerns. Cross-cutting concerns are typically implementation details that need to be kept separate from business logic.


In addition to the accepted answer I want to mention another example for a cross-cutting concern: remoting. Say I just want to call other components in my ecosystem locally as if they were running in process. Maybe in some cases they even do. But now I want to run my services distributed in a cloud or cluster. Why should I care about this aspect as an application developer? An aspect could take care of finding out who to call and and how, serialising transmitted data if necessary and making a remote call. If everything was running in process the aspect would just forward the local call. On the callee side the aspect would deserialise the data, make the local call and return the result.

Now let me tell you a little story about "trivial" things like log output: Just a few weeks ago I refactored a complex, but not too big code base (around 250K lines of code) for a client. In a few hundred classes one kind of logging framework was used, in another few hundred another. Then there were several thousand lines of System.out.println(*) where there really should have been log output. So I ended up with fixing thousands of lines of code scattered throughout the code base. Fortunately I could use some clever tricks in IntelliJ IDEA (structural search & replace) in order to speed up the whole action, but boy don't you think it was trivial! Sure, strongly context-dependent debug logging will always occur within a method body, but many important types of logging such as tracing method calls (even hierarchically with a nicely indented output), logging both handled or unhandled exceptions, user auditing (logging calls to restricted methods based on user roles) and so forth can easily be implemented in aspects without them polluting the source code. The everyday application developer does not need to think about it or even see the logger calls scattered across the code base. Someone is responsible for keeping the aspect up to date and can even switch the logging strategy or the whole logging framework centrally in one place.

I can come up with similar explanations for other cross-cutting concerns. Keeping code clean and free from scattering and tangling IMO is a matter of professionalism, not anything optional. Last but not least it keeps the code readable, maintainable, refactorable. Amen.