CSC/ECE 517 Fall 2013/ch1 1w34 fs: Difference between revisions

From Expertiza_Wiki
Jump to navigation Jump to search
No edit summary
Line 129: Line 129:
   end
   end
  end
  end
==AspectJ/AspectR==
==Problem with Aspect Oriented Programming==


==Summary==
==Summary==

Revision as of 02:45, 8 October 2013

Aspect-Oriented Programming (AOP) in Ruby on Rails is a programming paradigm which aims at preserving the modularity of object –oriented programs by separating behaviors that make overall implementation scattered, bulky and tangled. It so happens with huge applications that the object boundaries in the problem domain get obscured with the introduction of more and more aspects as an application gets bigger leading to spaghetti code scenario. AOP tackles this issue and compliments the object-oriented programming principles such as DRY by removing excess duplication throughout the program by separating cross-cutting concerns, resulting in a highly modular, easy to maintain and testable application code.

By isolating behavior, tight coupling between functionalities handling different logic, can be prevented. Also by separating these independent aspects such as logging, transactions and security further reuse can be made in other applications as well.

Overview

Aspect-Oriented Programming (AOP) complements OO programming by allowing the developer to dynamically modify the static OO model to create a system that can grow to meet new requirements. Just as objects in the real world can change their states during their lifecycles, an application can adopt new characteristics as it develops.

Consider an example: many of you have developed simple web applications that use servlets as the entry point, where a servlet accepts the values of a HTML form, binds them to an object, passes them into the application to be processed, and then returns a response to the user. The first cut of the servlet may be very simple, with only the minimum amount of code required to fulfill the use case being modeled. The code, however, often inflates to three to four times its original size by the time secondary requirements such as exception handling, security, and logging have been implemented. The term used here is "secondary requirements" because a servlet should not need to know about the logging or security mechanisms being used; its primary function is to accept input and process it.

Aspect-Oriented Programming allows us to dynamically modify our static model to include the code required to fulfill the secondary requirements without having to modify the original static model (in fact, we don't even need to have the original code). Better still, we can often keep this additional code in a single location rather than having to scatter it across the existing model, as we would have to if we were using Object-Oriented Concept on its own.

History

AOP has several direct antecedents A1 and A2:<ref>"Aspect-Oriented Programming" "Kiczales, G.; Lamping, J; Mehdhekar, A; Maeda, C; Lopes, C. V.; Loingtier, J; Irwin, J. Proceedings of the European Conference on Object-Oriented Programming (ECOOP), Springer-Verlag LNCS 1241. June 1997."</ref> reflection and Metaobject protocols, subject-oriented programming, Composition Filters and Adaptive Programming.<ref>"Adaptive Object Oriented Programming: The Demeter Approach with Propagation Patterns" Karl Liebherr 1996 ISBN 0-534-94602-X presents a well-worked version of essentially the same thing (Lieberherr subsequently recognized this and reframed his approach).</ref>

Gregor Kiczales and colleagues at Xerox PARC developed the explicit concept of AOP, and followed this with the AspectJ AOP extension to Java. IBM's research team pursued a tool approach over a language design approach and in 2001 proposed Hyper/J and the Concern Manipulation Environment, which have not seen wide usage. EmacsLisp changelog added AOP related code in version 19.28. The examples in this article use AspectJ as it is the most widely known AOP language.

The Microsoft Transaction Server is considered to be the first major application of AOP followed by Enterprise JavaBean.

Terminology

Cross Cutting Concerns

Many applications share common functionality in their design and implementation. This shared and common logic spans across many layers and leads to repetition and bloating of the application and thereby termed as crosscutting concerns. The aim of AOP is to centralize these functionalities into modular and independent logical aspects which can be inserted into the application either during compilation or at run time, as per requirement, thereby complimenting the DRY principle. The benefits of adopting such an approach are many. Apart from keeping the application with distinct object boundaries, it modularizes aspects in separate locations which are easy to update and maintain in future as well as reuse in other web applications. Some such aspects known commonly which can be treated in AOP way are:

Authentication
authorization
caching
communication
logging
validation

This reusing behavior as per outside defined aspects, crosscutting concerns can be effectively dealt with.

Advice

This is the additional code that you want to apply to your existing model. In our example, this is the logging code that we want to apply whenever the thread enters or exits a method.

Point-cut

This is the term given to the point of execution in the application at which cross-cutting concern needs to be applied. In our example, a pointcut is reached when the thread enters a method, and another pointcut is reached when the thread exits the method.

Aspect

The combination of the pointcut and the advice is termed an aspect. In the example above, we add a logging aspect to our application by defining a pointcut and giving the correct advice.

AOP Interactions

Persistence of model objects is a cross-cutting concern, in the sense that the desired persistence approach (database, flat files, replication, etc.) is independent of the domain logic represented by the model. So, why should the model code have any persistence logic? Instead, capture the details of mapping the domain to the persistence approach in separate components and programmatically or declaratively modify the model objects to synchronize state changes with the persistent memory of the state.




AOP'istic flavored Rails Framework

Rails framework allows methods to be called before and after a method invocation by employing method aliasing and metaprogramming features of Ruby, but using a third party library such as Aquarium, to glue the aspects is more cleaner and robust to failures ( such as plugins overriding method_missing stepping over each other). Rails already provides for filters which can be called before, after or around to wrap the controllers such as shown here:

someController
before_filter :admin_login_required

We also show how aspect oriented programming can be employed in Rails framework by separating aspects which cross-cut the application. In the following example we illustarte it for Loggingaspect. We start by building an application which stores items to be purchased in a cart. To help log user's activity while successfully adding or removing the items, logging needs to be performed for each action. As application gets bigger more aspects need to corporated such as authentication, security etc which makes it difficult to maintain and understand the code. Also it is needed for any update to any aspect be applied everywhere in the business logic where that updated aspect was injected.

Aspects in Rails MVC
class ItemsUseCase
attr_reader :cart, :logger, :items
 def initialize(cart = cart.new, logger = Logger.new)
   @cart = cart
   @logger = logger
   @items = []
 end
# Logging Aspect for adding items to cart
def user_adds(item)
  items << item
  cart.add(item, 
                   success: self.method(:user_added),
                   failure: self.method(:fails_to_add))
 end
def user_added(item)
   logger.info "Item successfully added: #{item.name})"
 end
def fails_to_add(item)
   logger.error "Failed to add item}"
end
end

Introducing AOP concept for separating Logging aspect. By separating the logging aspect to ItemsUseCaseGlue, we see that our ItemsUseCase become much simpler and having comprehensible object boundaries. It handles all the above stated issues that comes with integrating aspect knowledge in the business logic.

class ItemsUseCase
 attr_reader :items
 def initialize
   @items = []
 end
 def user_adds(item)
   items << item
 end
 def user_added(item); end
 def fails_to_add(item);  end
end

ItemsUseCaseGlue, where we employ Aquarium for employing AOP concepts, method invocation using- calls_to is used to specify our Joint points. When invoked in the program, advice is injected to take effect before, after or around the joint point.

require 'aquarium'
class ItemsUseCaseGlue
 attr_reader :usecase, :cart, :logger
 include Aquarium::Aspects
 def initialize(usecase, cart, logger)
   @usecase = usecase
   @ cart = cart
   @logger = logger
 end
 def inject!
   Aspect.new(:after, object: usecase, calls_to: :user_adds) do |jp, obj, item|
     cart.push(item, 
                     success: usecase.method(:user_added),
                   failure: usecase.method(:fails_to_add))
   end
   Aspect.new(:after, object: usecase, calls_to: :user_added) do |jp, obj, item|
     logger.info("Successfully added: #{item.name})")
   end
   Aspect.new(:after, object: usecase, calls_to: :fails_to_add) do |jp, obj, item|
     logger.error "Failed to add item"
   end
 end
end

Finally, the application retains its pure domain object properties without including any aspect layer specifications.

class Application
 def initialize
   @items = ItemsUseCase.new
   @cart = Cart.new
   @logger = Logger.new
   @items_glue = ItemsUseCaseGlue.new(items,@cart, @logger)
                        
   @items_glue.inject!
   # logic
 end
end

AspectJ/AspectR

Problem with Aspect Oriented Programming

Summary

References

  • Kiczales, G., J. Lamping, A. Mendhekar, C. Maeda, C. Videira Lopes, J.-M. Loingtier, J. Irwin (1997): Aspect-Oriented Programming, in: Proceedings of the 11th European Conference on Object-Oriented Programming (ECOOP 1997), Jyväskylä, Finland, Lecture Notes in Computer Science 1241, Springer-Verlag, 220-242

External Links