Aspect-oriented Programming

If you’ve been a programmer for a while or have received formal training as a programmer,
it’s very likely you’ve heard of Object-Oriented programming, or OOP. This way of viewing
code focuses on creating objects that represent the data and behavior of real-world
objects. OOP programmers tend to organize modules into groups that inherit from each other
and are (hopefully) loosely coupled or independent of one another.

Cause for Concern

Occasionally, a technique or feature in an application doesn’t seem to fit well in a
single object. Rather than being encapsulated once, it seems to need to “cut across”
many different parts of the architecture at once. Logging, error detection and handling,
workflow auditing, and caching are some examples of cross-cutting concerns that find their
way into most web applications.

Aspect-Oriented Programming, or AOP, is a technique that focuses on the organization and
modularity of these cross-cutting concerns.

AOP

Aspect Oriented Programming finds a home in the li3 in at least two main pieces of
functionality: filters
and strategies.

An entire guide is devoted to li3’s filter system,
but let’s review it at a high
level to see how it fits in the AOP paradigm. A filter is basically a bit of code you
want applied to the existing flow of logic in the framework. For example, you might want
a bit of logic that logs errors and sends them to a web service for reporting. This
cross-cutting concern could really be utilized in many different parts of the code: in
the model, view, or controller layers. Filters allow you to inject your logic into the
flow, logging errors at whatever level they occur. This happens without having to extend
or subclass core objects, nor implement messy beforeX afterX methods in your application
classes.

Apart from filters, strategies are often used as a way to implement many different ways to
accomplish a similar task. For example, the li3 session functionality is handled by the
Session class. You can configure that class to use a number of different storage engines,
each with it’s own storage strategy. For example, you can configure sessions to be stored
in memory either in JSON or Base64 format. Strategies create a cross-cutting solution that
can be applied to a class that’s been adapted to handle them.

Summary

We enjoy the AOP flavor li3 has, mostly for it’s centralized way to deal with
cross-cutting concerns. These features usually start scattered across a codebase, and
li3 solves this problem by facilitating a mechanism to house this logic. Though it does
take some getting used to, embracing AOP in your application can help you organize these
features in a concise and easily managed way.