CSC/ECE 517 Fall 2013/ch1 1w34 fs

From Expertiza_Wiki
Revision as of 00:39, 8 October 2013 by Schauha (talk | contribs) (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...")
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to navigation Jump to search

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

someController
before_filter :login_required


Ruby in Rails implementation

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

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
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 |af, 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 |af, obj, item|
     logger.error "Failed to add item"
   end
 end
end
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



References