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

From Expertiza_Wiki
Jump to navigation Jump to search
(Created page with "'''Aspect-Oriented Programming''' ('''AOP''') in '''Ruby on Rails''' is a programming paradigm which aims at preserving the modularity of object –oriented programs by separatin...")
 
No edit summary
Line 36: Line 36:


==AOP'istic flavored Rails Framework==
==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
  someController
  before_filter :login_required
  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 '''Logging'''aspect. 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.
==Ruby in Rails implementation==
Also it is needed for any update to any aspect be applied everywhere in the business logic where that updated aspect was injected.
  [[File:Aspect2.jpg|thumb|Aspects in Rails MVC]]
  [[File:Aspect2.jpg|thumb|Aspects in Rails MVC]]
  class ItemsUseCase
  class ItemsUseCase
Line 66: Line 66:
  end
  end


Introducing AOP concept for separating Logging
'''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
  class ItemsUseCase
   attr_reader :items
   attr_reader :items
Line 79: Line 79:
  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'
  require 'aquarium'
  class ItemsUseCaseGlue
  class ItemsUseCaseGlue
Line 89: Line 90:
   end
   end
   def inject!
   def inject!
     Aspect.new(:after, object: usecase, calls_to: :user_adds) do |af, obj, item|
     Aspect.new(:after, object: usecase, calls_to: :user_adds) do |jp, obj, item|
       cart.push(item,  
       cart.push(item,  
                       success: usecase.method(:user_added),
                       success: usecase.method(:user_added),
Line 97: Line 98:
       logger.info("Successfully added: #{item.name})")
       logger.info("Successfully added: #{item.name})")
     end
     end
     Aspect.new(:after, object: usecase, calls_to: :fails_to_add) do |af, obj, item|
     Aspect.new(:after, object: usecase, calls_to: :fails_to_add) do |jp, obj, item|
       logger.error "Failed to add item"
       logger.error "Failed to add item"
     end
     end
Line 103: Line 104:
  end
  end


Finally, the application retains its pure domain object properties without including any aspect layer specifications.
  class Application
  class Application
   def initialize
   def initialize
Line 115: Line 117:
  end
  end


==Summary==






 
==External Links==
==References==
*http://java9s.com/spring-framework/spring-aop-tutorial-aspect-oriented-programming
{{reflist}}
*http://guides.rubyonrails.org/action_controller_overview.html
<!--- After listing your sources please cite them using inline citations and place them after the information they cite. Please see http://en.wikipedia.org/wiki/Wikipedia:REFB for instructions on how to add citations. --->
*http://www.codeproject.com/Articles/11385/Aspect-Oriented-Programming-in-NET
*
*https://en.wikipedia.org/wiki/Cross-cutting_concern
*
*http://msdn.microsoft.com/en-us/library/ee658105.aspx
*
*http://aquarium.rubyforge.org/examples.html
*

Revision as of 01:25, 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 thus compliments the object-oriented principles such as DRY by removing excess duplication throughout the program by handling cross-cutting concerns, making the resulting code as highly modular, easy to maintain and test.


By isolating behavior, tight coupling between functionalities handling specific logic, in a program can be prevented. Also these independent aspects such as logging, transactions and security can be applied to other applications as well.

Overview

History

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

Point-cut

Aspect

AOP Interactions

File:Aspect Interactions.jpg
Interactions


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
==Summary==


External Links