1.8.1 Costs of AOP
Some of the costs associated with AOP are the usual suspects associated with any new
technology:
■ Making an investment in learning AOP
■ Hiring skilled programmers
■ Following an adoption path to ensure that you don’t risk the project by overextending yourself
■ Modifying the build and other development processes
■ Dealing with the availability of tools
Well-understood mitigation techniques are available for some of these issues:
■ Making a proper investment in learning the technology (and you already took a
step by reading this book)
■ Doing due diligence in checking skill availability (which is becoming increasingly easy due to Spring’s popularity)
■ Following a gradual adoption path, which we’ll show in part 2 of the book
Tools for AOP aren’t as mature as they are for Java (although they’re more mature
than for most other languages that run inside the Java VM). Fortunately, a lot of effort
is currently under way to improve the tooling around AOP, so this isn’t a serious
impediment to adopting it.
But one cost, still common to most new technologies, deserves more in-depth
treatment: the cost of abstraction. Abstraction lets you hide inessential details and
thus reduce the complexity of the underlying system. Good abstraction leads to the
creation of well-isolated modules. Because each module represents a much smaller
subsystem, abstraction offers a way to contain complexity at a level you can cope with.
Modularity is a divide-and-conquer approach to managing complexity. But the
abstraction introduced by AOP isn’t without costs.
NEED FOR GREATER SKILLS
Creating the right level of abstraction is a highly skilled job (many correct abstractions
are possible in a given system). A thorough understanding of the costs and benefits is
a hallmark of good software engineering. Merely understanding the implementation
mechanisms won’t yield useful abstractions.
In the context of AOP, you must understand how to fit the new unit of modularity—aspects—into the system. For that, you must apply decomposition techniques to
separate core concerns from crosscutting concerns. All this requires experience that is
often best gained by applying AOP in a gradual manner. The second part of the book
provides details of this strategy.
On the flip side, crosscutting logic is separated from business logic. This enables
you to use developers who understand only the business logic and not the intricacies
of the crosscutting functionality.
COMPLEX PROGRAM FLOW
Abstraction, by its nature, hides the details. In software systems, higher levels of abstraction always mean that less information is available at the code level. Looking at a code
segment doesn’t tell you the whole story that will unfold during system execution. For
example, in OOP, due to polymorphic methods, you can’t tell the exact method that will
be executed at runtime, because the choice of method is based on the type of the
object, not the static type of the declared variable. This makes analyzing program flow
a complex task. Even in procedural languages such as C, if you use function pointers,
the program flow isn’t static and requires some effort to be understood.
AOP abstracts away program flow even further. You may not know (except through
good tooling support) that a crosscutting action will take place in a certain part of the
code. Many programmers new to AOP get stuck until they realize that this separation
of concerns is the whole point. If you insist on understanding the exact program flow,
it’s a sign that you need to reflect a little longer on the core ideas of AOP. But just as
OOP requires a few years of practice before you understand the underlying core ideas,
most developers get AOP eventually.
1.8.2 Benefits of AOP
Now that you know the costs, let’s look at the benefits.
SIMPLIFIED DESIGN
The architect of a system is often faced with underdesign/overdesign issues. If you
underdesign, you may have to make massive changes later in the development cycle.
If you overdesign, the implementation may be burdened with code of questionable
usefulness. With AOP, you can delay making design decisions for future requirements
because you can implement those as separate aspects. You can focus on the current
requirements of the system.
AOP works in harmony with one of the most popular trends of agile programming
by supporting the practice of “You aren’t gonna need it” (YAGNI). Implementing a feature just because you may need it in the future often results in wasted effort because you
won’t actually need it. With AOP, you can practice YAGNI; and if you do need a particular
kind of functionality later, you can implement it without having to make system-wide
modifications. Even for the feature that you need, agile programming promotes developing them progressively. AOP helps you add features incrementally through the introduction of aspects, often without modifying the rest of the code.
CLEANER IMPLEMENTATION
AOP allows a module to take responsibility only for its core concern, thus following
the SRP; a module is no longer liable for other crosscutting concerns. For example, a
module implementing business logic is no longer responsible for the security functionality. This results in cleaner assignments of responsibilities, reduced code clutter,
and less duplication. It also improves the traceability of requirements to their implementation, and vice versa.
Reduced code tangling makes it simpler to test code, spot potential problems, and
perform code reviews. Reviewing the code of a module that implements only one concern requires the participation of an expert in the functionality implemented by that
module. Such a simplified process leads to higher-quality code.
Reduced code scattering avoids the cost of modifying many modules to implement
a crosscutting concern. Thus, AOP makes it cheaper to implement a crosscutting feature. By letting you focus on the core concern of a module and make the most of your
expertise, AOP also reduces the cost of the core concerns.
The end effect is a cheaper overall feature implementation, better time-to-market,
and easier system evolution.
BETTER CODE REUSE
The key to greater code reuse is a more loosely coupled implementation. If a module
is implementing multiple concerns, other systems requiring similar functionality may
not be able to use the module if they implement a different set of crosscutting concerns. With AOP, because you can implement each crosscutting module as an aspect,
core modules aren’t aware of crosscutting functionality. By modifying the aspects, you
can change the system configuration. For example, a service layer may be secured in a
project with one security scheme, in another project with another scheme, or in still
another project with no security at all by including or excluding appropriate aspects.
Without AOP, a service layer tied with a specific security implementation may not be
reused in another project.
1.9 Summary
The most fundamental principle in software engineering is that the separation of concerns leads to a system that is simpler to understand and easier to maintain. Various
methodologies and frameworks support this principle in some form. For instance,
with OOP, by separating interfaces from their implementation, you can modularize
the core concerns well. But for crosscutting concerns, OOP forces the core modules to
embed the crosscutting concern’s logic. Although the crosscutting concerns are independent of each other, using OOP leads to an implementation that no longer preserves independence in the implementation.
Aspect-oriented programming changes this by modularizing crosscutting concerns
in a generic and methodical fashion. With AOP, crosscutting concerns are modularized by encapsulating them in a new unit called an aspect. Core concerns no longer
embed the crosscutting concern’s logic, and all the associated complexity of the crosscutting concerns is isolated into the aspects. AOP marks the beginning of a new way of
dealing with a software system by viewing it as a composition of mutually independent
concerns. By building on top of existing programming methodologies, AOP preserves
the investment in knowledge gained over the last few decades.
In the last few years, AOP has become a practical technology. It has been deployed
in many organizations, big and small, to add powerful features that we might have otherwise shied away from or implemented in a laborious manner.
In the next eight chapters, we’ll study a specific implementation of AOP for Java,
AspectJ, as well as its integration with Spring. Those chapters and the rest of the book
will provide examples that use this technology to solve real problems. In chapter 2,
you’ll see how AspectJ implements AOP for Java.
3657



被折叠的 条评论
为什么被折叠?



