Vous êtes sur la page 1sur 39

Aspect-Oriented Programming in Ruby

Dean Wampler Sr. Trainer, Mentor, and Consultant Object Mentor, Inc. Chicago, IL dean@objectmentor.com Friday, March 23, 2007, 3:30-5:00 PM

Outline
Why Aspect-Oriented Programming? AOP in Java and AspectJ (a Review). AOP in Ruby. What you can do today. Example AOP-isms in Ruby on Rails. Aspect-Oriented Design. The AOP Promise for Tomorrow.

1993-2007 Object Mentor Incorporated. All Rights Reserved. www.objectmentor.com 1-800-338-6716 Version 1.0 / Page 2

Why Aspect-Oriented Programming?

1993-2007 Object Mentor Incorporated. All Rights Reserved. www.objectmentor.com 1-800-338-6716 Version 1.0 / Page 3

Why Aspect-Oriented Programming? ! Aspect-Oriented Programming (AOP):


! A modularity approach for logical concerns that cut across the domain model. ! Complementary to Object-Oriented Programming, Functional Programming, etc.

! But why do we need a new approach?

1993-2007 Object Mentor Incorporated. All Rights Reserved. www.objectmentor.com 1-800-338-6716

Version 1.0 / Page 4

The Problem:
require 'insufficient_funds' class BankAccount attr_accessor :balance def initialize @balance = 0.0 end def deposit(amount) @balance += amount end def withdraw(amount) if @balance < amount raise InsufficientFunds end @balance -= amount end end

Plain Old Ruby Object (PORO): Simple to understand, maintain, reuse, ... but ...

1993-2007 Object Mentor Incorporated. All Rights Reserved. www.objectmentor.com 1-800-338-6716

Version 1.0 / Page 5

The Problem: ! What if you need persistence?


require 'insufficient_funds_error' class BankAccount attr_reader :balance # 1 def balance=(amount) @balance = amount persist_balance # 2 end def initialize @balance = retrieve_balance # 3 end def deposit(amount) @balance += amount persist_balance # 2 end def withdraw(amount) if @balance < amount raise InsufficientFundsError end @balance -= amount persist_balance #2 end def retrieve_balance # 3 # Get from database end def persist_balance # Save to database end end #2

1993-2007 Object Mentor Incorporated. All Rights Reserved. www.objectmentor.com 1-800-338-6716

Version 1.0 / Page 6

The Problem: ! Now add:


! Transactional behavior. ! Authentication and authorization. ! Observers, like a UI. ! Then cut and paste the code for these concerns across many other domain objects that need the same behavior.

1993-2007 Object Mentor Incorporated. All Rights Reserved. www.objectmentor.com 1-800-338-6716

Version 1.0 / Page 7

The Problem: ! Finally, attempt to reuse this code in a new application with a different persistence store, transaction engine, security model...

1993-2007 Object Mentor Incorporated. All Rights Reserved. www.objectmentor.com 1-800-338-6716

Version 1.0 / Page 8

The Problem: ! The modularity of plain old domain object models break down when adding real world concerns.
! A cross-cutting concern.

BankAccount Persistence Observer Pattern

Transactions

Security

1993-2007 Object Mentor Incorporated. All Rights Reserved. www.objectmentor.com 1-800-338-6716

Version 1.0 / Page 9

The Problem: ! Note: Persistence itself is already modular,


! But the code that uses it isnt! ! Persistence invocation code is scattered. ! BankAccount code is tangled with code from other concerns.

BankAccount

Persistence

1993-2007 Object Mentor Incorporated. All Rights Reserved. www.objectmentor.com 1-800-338-6716

Version 1.0 / Page 10

The Problem: ! BankAccounts modularity is compromised. ! Also, similar persistence code is added to other components:
! Redundancy:
Hard to change all occurrences consistently. Hard to replace the Persistence solution. Breaks Dont Repeat Yourself! (DRY)

! Reuse is hard.
The persistence solution may be different in another context.

1993-2007 Object Mentor Incorporated. All Rights Reserved. www.objectmentor.com 1-800-338-6716

Version 1.0 / Page 11

The Solution: ! Some modern OO design approaches help.


! Inheritance or Modules. ! Design Patterns. ! Inversion of Control (IoC) containers.

! But they tend to work at a coarse-grained level of interaction.

1993-2007 Object Mentor Incorporated. All Rights Reserved. www.objectmentor.com 1-800-338-6716

Version 1.0 / Page 12

A Better Solution?

! Aspect-Oriented Programming:
Encapsulate the separate concerns as aspects, Provide mechanisms for fine-grained modification of target component behavior to incorporate the aspects behaviors, and thereby restore system modularity.

1993-2007 Object Mentor Incorporated. All Rights Reserved. www.objectmentor.com 1-800-338-6716

Version 1.0 / Page 13

Aspect-Oriented Programming ! Use a Persistence Aspect:


! It adds the blue lines invoking persistence behavior. ! BankAccount remains agnostic. ! The aspect code is maintained in one place.

! Easy to change to a different solution or to remove the concern.


Persistence Aspect

BankAccount Persistence

1993-2007 Object Mentor Incorporated. All Rights Reserved. www.objectmentor.com 1-800-338-6716

Version 1.0 / Page 14

Aspect-Oriented Programming ! If BankAccount is no longer tangled with other code, it is


! ! ! ! Simpler (again). More comprehensible. More maintainable. More extensible.

! More testable. ! More reusable.

1993-2007 Object Mentor Incorporated. All Rights Reserved. www.objectmentor.com 1-800-338-6716

Version 1.0 / Page 15

AOP in Java and AspectJ: a Quick Review

1993-2007 Object Mentor Incorporated. All Rights Reserved. www.objectmentor.com 1-800-338-6716 Version 1.0 / Page 16

Static vs. Dynamic Typing ! Static Typing


! Behavior depends on type of the variable.
Usually determined at compile time. Type is fixed; doesnt change. a.k.a. early typing.

! Dynamic Typing
! Behavior depends on type of the value.
Variable can be assigned a different value. a.k.a. late typing.

1993-2007 Object Mentor Incorporated. All Rights Reserved. www.objectmentor.com 1-800-338-6716

Version 1.0 / Page 17

AOP in Static Languages ! Area of greatest R&D to-date. ! Ironic since many of the inventors come from Lisp backgrounds ! but reflects practical realities:
! Cross-cutting concerns most problematic in enterprise and web applications written in Java, .NET, etc. ! Metaprogramming facilities tend to be weaker...

1993-2007 Object Mentor Incorporated. All Rights Reserved. www.objectmentor.com 1-800-338-6716

Version 1.0 / Page 18

Java AOP ! AspectJ


! Most sophisticated AOP solution.

! Spring Framework AOP


! springframework.org

! JBoss AOP
! jboss.org

1993-2007 Object Mentor Incorporated. All Rights Reserved. www.objectmentor.com 1-800-338-6716

Version 1.0 / Page 19

Aspect Concepts (from AspectJ) ! Join Points


! Points of program execution where new behavior might be inserted.

! Pointcuts
! Sets of Join Points with a similar theme.

! Advice
! Code invoked before, after, or around a Join Point.

1993-2007 Object Mentor Incorporated. All Rights Reserved. www.objectmentor.com 1-800-338-6716

Version 1.0 / Page 20

10

AspectJ Example

aspect is like a class

Pointcut

aspect PersistenceAspect { pointcut stateChange(BankAccount ba): (call(void BankAccount.deposit(*)) || call(void BankAccount.withdraw(*))) after && target(ba); Advice

2 Join Points

after(BankAccount ba) returning: stateChange(ba) { // persist ba.getBalance() value } }

1993-2007 Object Mentor Incorporated. All Rights Reserved. www.objectmentor.com 1-800-338-6716

Version 1.0 / Page 21

AOP in Ruby

1993-2007 Object Mentor Incorporated. All Rights Reserved. www.objectmentor.com 1-800-338-6716 Version 1.0 / Page 22

11

AOP in Ruby (??) ! If youre doing enterprise or web development today, you should either be using Java or .NET with AOP enhancements or you should be using a dynamic language like Ruby or Smalltalk.
Anonymous consultant colleague of mine

1993-2007 Object Mentor Incorporated. All Rights Reserved. www.objectmentor.com 1-800-338-6716

Version 1.0 / Page 23

AOP in Ruby (??) ! Once you have decent reflection and metaclasses, AOP is just part of the language.
! Dave Thomas
c2.com/cgi/wiki?AspectsAndDynamicLanguages

1993-2007 Object Mentor Incorporated. All Rights Reserved. www.objectmentor.com 1-800-338-6716

Version 1.0 / Page 24

12

AOP in Ruby (??) ! Is AOP really only a tool for static languages?
! Cross-cutting concerns are easier to address in dynamic languages because their metaprogramming facilities are better.

1993-2007 Object Mentor Incorporated. All Rights Reserved. www.objectmentor.com 1-800-338-6716

Version 1.0 / Page 25

Is AOP Just Metaprogramming? ! Is AOP just a constrained form of general metaprogramming?


! No more so than OOP. ! You can use MP facilities to simulate features not found natively in the language. ! However, Its important to keep the semantics separate from the implementation.
Having an AOP toolkit avoids mental mapping between metaprogramming and aspects. Your code more closely matches your design concepts

! For more on AOP vs. metaprogramming.


! sdmagazine.com/documents/s=8993/sdm0411f/

1993-2007 Object Mentor Incorporated. All Rights Reserved. www.objectmentor.com 1-800-338-6716

Version 1.0 / Page 26

13

Is AOP Really Needed? ! SW complexity keeps growing.


! OOP modularity doesnt solve all problems. ! AOP will become more necessary and pervasive over time.

! Native language support is easier to use than metaprogramming facilities.

1993-2007 Object Mentor Incorporated. All Rights Reserved. www.objectmentor.com 1-800-338-6716

Version 1.0 / Page 27

To Be AOP You Need ! Interception


! Interjection of advice, at least around methods.

! Introduction
! Enhancing with new (orthogonal!) state and behavior .

! Inspection
! Access to meta-information that may be exploited by pointcuts or advice.

! Modularization
! Encapsulate as aspects.

1993-2007 Object Mentor Incorporated. All Rights Reserved. www.objectmentor.com 1-800-338-6716

Version 1.0 / Page 28

14

Interception in Ruby ! Use alias to wrap methods with advice.


# foo.rb class Foo def bar "bar" end end # foo_advice.rb class Foo alias old_bar bar def bar "{[< "+ old_bar+ " >]} end end

puts Foo.new.bar # => "{[< bar >]}"

1993-2007 Object Mentor Incorporated. All Rights Reserved. www.objectmentor.com 1-800-338-6716

Version 1.0 / Page 29

Interception in Ruby (Slightly Better) ! define_method: not as clear, but more robust.
! Avoids potential namespace collisions (with other old_bars). ! Avoids namespace pollution (you want old_bar invisible). ! http://jayfields.blogspot.com/2006/12/ruby-alias-methodalternative.html
# foo.rb class Foo def bar "bar end end # foo_advice.rb class Foo old_bar = self.instance_method(:bar) define_method(:bar) do "{[< " + old_bar.bind(self).call() + " >]}" end end

puts Foo.new.bar # => "{[< bar >]}"


1993-2007 Object Mentor Incorporated. All Rights Reserved. www.objectmentor.com 1-800-338-6716 Version 1.0 / Page 30

15

Introductions in Ruby ! Add new methods and fields to a class


# foo.rb class Foo def bar "bar end end # foo_intro.rb # Introduce a method in the class: class Foo def other "{other}" end attr_accessor :name end

f = Foo.new puts f.other # => {other} f.name = "FOO" puts f.name # => FOO
1993-2007 Object Mentor Incorporated. All Rights Reserved. www.objectmentor.com 1-800-338-6716 Version 1.0 / Page 31

Introductions in Ruby (cont.) ! Add a method to an instance (Cant do this with AspectJ)
f = Foo.new def f.and_another and_another end puts f.and_another puts f.singleton_methods.inspect # A "singleton method"

# => and_another # => ["and_another"]

class << f # Another way def yet_another; "yet another"; end end puts f.yet_another puts f.singleton_methods.inspect # => yet another # => ["yet_another", "and_another"]

1993-2007 Object Mentor Incorporated. All Rights Reserved. www.objectmentor.com 1-800-338-6716

Version 1.0 / Page 32

16

Inspection in Ruby ! Lots of reflection methods (run using irb)


i=0 s="foo" local_variables global_variables s.class s.display s.inspect s.instance_variables s.methods s.private_methods s.protected_methods s.public_methods s.singleton_methods
1993-2007 Object Mentor Incorporated. All Rights Reserved. www.objectmentor.com 1-800-338-6716

s.method(:size).arity s.method(:replace).arity

Version 1.0 / Page 33

Inspection in Ruby (cont.) ! Simulating pointcuts:


# List all the classes ObjectSpace.each_object(Class) do |o| puts o.inspect end # List all the modules ObjectSpace.each_object(Module) do |o| puts o.inspect end # List all the instances of class String ObjectSpace.each_object(String) do |o| puts o.inspect end
1993-2007 Object Mentor Incorporated. All Rights Reserved. www.objectmentor.com 1-800-338-6716 Version 1.0 / Page 34

17

Inspection in Ruby (cont.) ! One you have the objects


! Get the methods you want ! Add advice ! Rinse ! Repeat

1993-2007 Object Mentor Incorporated. All Rights Reserved. www.objectmentor.com 1-800-338-6716

Version 1.0 / Page 35

Modularization (& Full Example) ! The Observer Design Pattern


# observer.rb module Subject def add_observer observer @observers = [] if @observers.nil? @observers.push observer end def notify @observers.each {|o| o.receive_update(self)} end end

1993-2007 Object Mentor Incorporated. All Rights Reserved. www.objectmentor.com 1-800-338-6716

Version 1.0 / Page 36

18

Modularization (& Full Example) ! Observe changes to the Users name


# user.rb class User attr_accessor :name def initialize name @name = name end end # user_observer_aspect.rb class UserObserver def receive_update subject super; puts "New name: #{subject.name}; end end class User # advice User include Subject alias :set_name :name= def name= new_name set_name(new_name) notify end end
1993-2007 Object Mentor Incorporated. All Rights Reserved. www.objectmentor.com 1-800-338-6716 Version 1.0 / Page 37

Observer Example (cont.) ! Test Run:


bob = User.new "bob" ted = User.new "ted" bob.add_observer UserObserver.new bob.add_observer UserObserver.new ted.add_observer UserObserver.new bob.name = "fred" ted.name = "ed"

New name: fred New name: fred New name: ed

1993-2007 Object Mentor Incorporated. All Rights Reserved. www.objectmentor.com 1-800-338-6716

Version 1.0 / Page 38

19

Note: No Observer Interface ! An Observer interface is not required in Ruby. ! With duck typing, the pattern still works. ! How do we enforce the Observer contract?

1993-2007 Object Mentor Incorporated. All Rights Reserved. www.objectmentor.com 1-800-338-6716

Version 1.0 / Page 39

Idiom: Ensure Methods Are Present ! Enforce the contract in Subject#add_observer.


# observer.rb module Subject def add_observer observer raise Observer must respond to receive_update \ unless observer.respond_to? :receive_update @observers ||= [] @observers.push observer end end

1993-2007 Object Mentor Incorporated. All Rights Reserved. www.objectmentor.com 1-800-338-6716

Version 1.0 / Page 40

20

Enforcing the Observer Contract ! Test Run:


bob = User.new "bob" ted = User.new "ted" bob.add_observer UserObserver.new bob.add_observer UserObserver.new ted.add_observer UserObserver.new bob.name = "fred" ted.name = "ed bob.add_observer bogus

New name: fred New name: fred New name: ed in add_observer: Observer must respond to receive_update. (RuntimeError)
1993-2007 Object Mentor Incorporated. All Rights Reserved. www.objectmentor.com 1-800-338-6716 Version 1.0 / Page 41

About method_missing ! Used everywhere in Rails and other toolkits. ! Your method_missing often collides with mine ! Its a form of Introductions. ! Consider using aspects to preserve modularity and reduce collisions.
! Introduce expected methods by reopening classes, ! Reduce the actual calls to method_missing.

1993-2007 Object Mentor Incorporated. All Rights Reserved. www.objectmentor.com 1-800-338-6716

Version 1.0 / Page 42

21

Off-the-Shelf Ruby AOP Tools ! AspectR. ! Facets. ! Ruby 1.9-2.0 Proposed Features:
! Cuts. ! Method Wrappers.

! Others

1993-2007 Object Mentor Incorporated. All Rights Reserved. www.objectmentor.com 1-800-338-6716

Version 1.0 / Page 43

Ruby AOP: AspectR ! AspectJ workalike. ! Join Point Model:


! Specify individual classes. ! Specify methods with regular expressions.

! Only ~300 lines of ruby code!


! Demonstrates power of metaprogramming in Ruby.

! Viable for use today.


! Example given in OReillys Ruby Cookbook.

! aspectr.sourceforge.net

1993-2007 Object Mentor Incorporated. All Rights Reserved. www.objectmentor.com 1-800-338-6716

Version 1.0 / Page 44

22

Facets ! Large Ruby Add-On Library. ! Aspects and Cut Modules. ! http://facets.rubyforge.org/

1993-2007 Object Mentor Incorporated. All Rights Reserved. www.objectmentor.com 1-800-338-6716

Version 1.0 / Page 45

Facets Cut Example


# Adapted from Facets Unit Tests require 'rubygems' require 'facet/cut.rb' class F def f ; "f" ; end end cut :G < F do def f; '<'+super+'>' ; end end f = F.new p f.class p f.object_class p f.f # => F" # => F" # => "<f>"

1993-2007 Object Mentor Incorporated. All Rights Reserved. www.objectmentor.com 1-800-338-6716

Version 1.0 / Page 46

23

Facets Aspects Example


# Adapted from Facets documentation require 'rubygems' require 'facet/aspects.rb' class Controller pre :force_login, :where => :prepend wrap Benchmark, :on => :index post :auth, :on => login end

1993-2007 Object Mentor Incorporated. All Rights Reserved. www.objectmentor.com 1-800-338-6716

Version 1.0 / Page 47

A General-Purpose Option ! Erik Veenstras monitor functions library. ! Examples of:


! ! ! ! Design by Contract. Type checking of method arguments (gasp!). Value checking of method arguments.

! http://www.erikveen.dds.nl/monitorfunctions/index.html

1993-2007 Object Mentor Incorporated. All Rights Reserved. www.objectmentor.com 1-800-338-6716

Version 1.0 / Page 48

24

Cut-based AOP ! Proposed 1.9 or 2.0 language feature. ! Uses a subclassing-like syntax.
! Robust and fine-grained join point advising.

! No real pointcut language (currently). ! rcrchive.net/rcrs/1

1993-2007 Object Mentor Incorporated. All Rights Reserved. www.objectmentor.com 1-800-338-6716

Version 1.0 / Page 49

Cut-based AOP: Example


class C def m1; 1; end def m2; 2; end end Or class A < C # subclass def m1 print '{ + super + '}' end end A is instantiated cut A < C def m1 print '{' + super + '}' end end C is instantiated # "cut"

A.new.m1 # prints: "{1}"

C.new.m1 # prints: "{1}"

1993-2007 Object Mentor Incorporated. All Rights Reserved. www.objectmentor.com 1-800-338-6716

Version 1.0 / Page 50

25

Method Wrappers
class Foo def foo:pre(*args) p "pre" end def foo:post(*args) p "post" end def foo:wrap(*args) p "wrap pre" super p "wrap post" end def foo(*args); p "foo; end end
1993-2007 Object Mentor Incorporated. All Rights Reserved. www.objectmentor.com 1-800-338-6716 Version 1.0 / Page 51

! Another proposed 1.9 or 2.0 language feature.

Foo.new.foo wrap pre pre foo post wrap post

So, Whats Missing? ! Disconnect between the AOP semantics and the code boilerplate.
! Extra mental mapping between metaprogramming (MP) API and AOP semantics required. ! Not as efficient as native AOP features. ! MP is harder for average developers to understand and use.
They struggle already with objects!

! Proposed Ruby 1.9/2.0 features only support advice.

1993-2007 Object Mentor Incorporated. All Rights Reserved. www.objectmentor.com 1-800-338-6716

Version 1.0 / Page 52

26

So, Whats Missing? ! No Join Point model!


! ! ! ! (a.k.a. Pointcut Language) Biggest missing piece. Nontrivial pointcuts require grepping output of ObjectSpace Hard to do temporal events:
Advice C.m if in the context flow of C2.m2. if event E has happened, advice C3.m3.

1993-2007 Object Mentor Incorporated. All Rights Reserved. www.objectmentor.com 1-800-338-6716

Version 1.0 / Page 53

Example AOP-isms in Ruby on Rails


! method_missing ! Method aliasing ! Introductions through
! (class|module|instance)_eval expression ! Singleton classes for objects. ! Reopened classes.

! Used extensively to augment classes and modules with new behavior.


! Augment (advise) existing methods with alias_method. ! Add new methods through method_missing and explicit addition of new methods to classes.

! Many new methods added to core Ruby classes.


! whiny_nil.rb and core_ext in ActiveSupport.

1993-2007 Object Mentor Incorporated. All Rights Reserved. www.objectmentor.com 1-800-338-6716

Version 1.0 / Page 54

27

Advice Using method_missing


class NilClass WHINERS = [ ::ActiveRecord::Base, ::Array ] @@method_class_map = Hash.new WHINERS.each do |klass| methods = klass.public_instance_methods public_instance_methods methods.each do |method| @@method_class_map[method.to_sym] = klass end end

1993-2007 Object Mentor Incorporated. All Rights Reserved. www.objectmentor.com 1-800-338-6716

Version 1.0 / Page 55

Advice Using method_missing


private def method_missing(method, *args, &block) raise_nil_warning_for @@method_class_map[method], method, caller end def raise_nil_warning_for(klass = nil, selector = nil, with_caller = nil) message = "You have a nil object when you didn't expect it!" message << "\nExpected an instance of #{klass}?" if klass message << "\nThe error occurred .. nil.#{selector}" if selector raise NoMethodError, message, with_caller || caller end end

1993-2007 Object Mentor Incorporated. All Rights Reserved. www.objectmentor.com 1-800-338-6716

Version 1.0 / Page 56

28

Introductions Using *_eval methods


! Add class-level attributes created on demand
class Class def cattr_reader(*syms) syms.flatten.each do |sym| next if sym.is_a?(Hash) class_eval(<<-EOS, __FILE__, __LINE__) unless defined? @@#{sym}; @@#{sym} = nil end def self.#{sym}; @@#{sym}; end def #{sym}; @@#{sym}; end EOS end end

1993-2007 Object Mentor Incorporated. All Rights Reserved. www.objectmentor.com 1-800-338-6716

Version 1.0 / Page 57

alias_method and class_eval Advice ! ~175 Uses of alias_method in Rails 1.2 stack.
! E.g., activerecord-1.15.2/lib/active_record/associations.rb module ActiveRecord::Associations::ClassMethods def has_and_belongs_to_many(association_id, options = {}, &extension) reflection = create_has_and_belongs_to_many_reflection(association_id, options, &extension) old_method = "destroy_without_habtm_shim_for_#{reflection.name}" class_eval <<-end_eval alias_method :#{old_method}, :destroy_without_callbacks def destroy_without_callbacks; ; end end_eval end

1993-2007 Object Mentor Incorporated. All Rights Reserved. www.objectmentor.com 1-800-338-6716

Version 1.0 / Page 58

29

Advice Using alias_method (another one)


! Fixtures are a way of organizating data for testing.
! activerecord-1.15.2/lib/active_record/fixtures.rb module Test::Unit::TestCase def setup_with_fixtures; ; end alias_method :setup, :setup_with_fixtures def self.method_added(method) case method.to_s when 'setup' unless method_defined?(:setup_without_fixtures) alias_method :setup_without_fixtures, :setup define_method(:setup) do setup_with_fixtures setup_without_fixtures end end

1993-2007 Object Mentor Incorporated. All Rights Reserved. www.objectmentor.com 1-800-338-6716 Version 1.0 / Page 59

Introductions Using method_missing ! ActiveRecord Models (ActiveRecord::Base)


! Methods and attributes for models are generated based on the corresponding schema. ! Class-level missing_method handles finders:
find_by_user_name_and_password(name, pwd) find_all_by_birth_date(date)

! Instance-level missing_method handles attribute readers/writers:


user_name=(name) user_name()

1993-2007 Object Mentor Incorporated. All Rights Reserved. www.objectmentor.com 1-800-338-6716

Version 1.0 / Page 60

30

AOP-isms in Ruby on Rails: Recap ! Metaprogramming:


! Reduces Boilerplate and LoCs. ! Supports DRY. ! Makes cross-cutting concerns more modular.

! AOP-like features are pervasive.


! Would first-class AOP support make the code base cleaner and more robust?
Sometimes 3rd-party libraries step on each others' aliases and method_missing implementations.

1993-2007 Object Mentor Incorporated. All Rights Reserved. www.objectmentor.com 1-800-338-6716

Version 1.0 / Page 61

Aspect-Oriented Design

1993-2007 Object Mentor Incorporated. All Rights Reserved. www.objectmentor.com 1-800-338-6716 Version 1.0 / Page 62

31

Quantification and Obliviousness ! AOP is Quantification and Obliviousness.


! Robert E. Filman and Daniel P. Friedman (OOPSLA 2000).
http://ic.arc.nasa.gov/people/filman/text/oif/aop-is.pdf http://ic.arc.nasa.gov/publications/pdf/2001-0240.pdf

! AOP can be understood as the desire to make quantified statements about the behavior of programs, and to have these quantifications hold over programs written by oblivious programmers.

1993-2007 Object Mentor Incorporated. All Rights Reserved. www.objectmentor.com 1-800-338-6716

Version 1.0 / Page 63

Obliviousness ! The writer of the source code is unaware that aspects may be applied to the code. ! Does a programmer have to do anything to prepare the code for aspects?
! At odds with Obliviousness.

! On the other hand, wouldnt module writers want to restrict some aspects?
! Limit accessible join points? ! Limit types of advice?

1993-2007 Object Mentor Incorporated. All Rights Reserved. www.objectmentor.com 1-800-338-6716

Version 1.0 / Page 64

32

Obliviousness: The AOSD-Evolution Paradox ! On the Existence of the AOSD-Evolution Paradox.


! Tom Tourw, Johan Brichau, Kris Gybels.
http://homepages.cwi.nl/~tourwe/articles/aosd2003-splatWS.pdf

! Aspects improve modularity initially. ! Subsequent evolution is harder.


Because of hard dependencies on concrete details BankAccount Persistence Aspect
PCD: set(* *.name)

Version 1

name

??

BankAccount
first_name last_name

Version 2

1993-2007 Object Mentor Incorporated. All Rights Reserved. www.objectmentor.com 1-800-338-6716

Version 1.0 / Page 65

AOSD-Evolution Paradox ! Why is it an Obliviousness Problem?


! The paradox occurs because coupling is defined in terms of concrete details.
It should be in terms of abstractions.

! If the module is designed to be completely oblivious to possible aspects, it will probably not expose the necessary abstractions.

! These are really old problems, already solved by OOD principles

1993-2007 Object Mentor Incorporated. All Rights Reserved. www.objectmentor.com 1-800-338-6716

Version 1.0 / Page 66

33

We Forgot OOD Principles ! Open-Closed Principle ! Liskov Substitution Principle ! Dependency Inversion Principle ! Others ! These principles can be extended for aspects
! aosd.net/2007/program/industry/I6-AspectDesignPrinciples.pdf

1993-2007 Object Mentor Incorporated. All Rights Reserved. www.objectmentor.com 1-800-338-6716

Version 1.0 / Page 67

Like for Objects ! Treat pointcuts as dependencies.


! Couple only to abstractions.

1993-2007 Object Mentor Incorporated. All Rights Reserved. www.objectmentor.com 1-800-338-6716

Version 1.0 / Page 68

34

The AOP Promise for Tomorrow

1993-2007 Object Mentor Incorporated. All Rights Reserved. www.objectmentor.com 1-800-338-6716 Version 1.0 / Page 69

Native AOP Support ! Advice


! Explicit support for advice available today.
Libraries. Metaprogramming API.

! Possible extensions in 1.9 or 2.0


Cut mechanism. :pre, :post, and :wrap for methods.

! Join Points and Pointcuts


! Very limited library support today.
Hacks are also difficult for nontrivial cases.

! No plans for native support.


but I think it will happen eventually.

1993-2007 Object Mentor Incorporated. All Rights Reserved. www.objectmentor.com 1-800-338-6716

Version 1.0 / Page 70

35

Frameworks and Components ! Hyped in the 80's and 90's.


! But they didn't live up to their promise.

! Problem: All or Nothing Proposition.


! Framework wants to be comprehensive.
To be all things to all people. Thats great if you can adopt the whole thing, But that means you cant take pieces because of dependencies.

! Hence, relatively few frameworks succeeded.

! Could aspects reduce the hard dependencies?


! Satisfy all potential users?

1993-2007 Object Mentor Incorporated. All Rights Reserved. www.objectmentor.com 1-800-338-6716

Version 1.0 / Page 71

Rails as a Framework ! Rails fits its niche very well.


! But are there limits that may prevent diversification of its user base?

! Consider ActiveRecord models:


# person.rb class Person < ActiveRecord::Base has_many :Addresses end # address.rb class Address < ActiveRecord::Base belongs_to :Person end

1993-2007 Object Mentor Incorporated. All Rights Reserved. www.objectmentor.com 1-800-338-6716

Version 1.0 / Page 72

36

Rails as a Frameworks ! The domain abstractions are closely tied to the persistence framework. ! The model objects are used in all tiers of a Rails application. ! The dependency on ActiveRecord sometimes gets in the way.
! Testing. ! Non-persistent model objects. ! Scalability

! Can we break the dependency?

1993-2007 Object Mentor Incorporated. All Rights Reserved. www.objectmentor.com 1-800-338-6716

Version 1.0 / Page 73

Rails as a Framework
# person.rb class Person < DomainObject # 1 has_many :Addresses end # address.rb class Address < DomainObject # 1 belongs_to :Person end

# active_record_persistance.rb

#2

persist :DomainObjects, :to => :ActiveRecord # flat_file_persistance.rb #3

persist :DomainObjects, :to => :FlatFilePersistence # web_view.rb #4

present :DomainObjects, :except => [...], :using => :ActionPack


1993-2007 Object Mentor Incorporated. All Rights Reserved. www.objectmentor.com 1-800-338-6716 Version 1.0 / Page 74

37

Domain Specific Languages ! Express the Cross-Cutting Concerns as DSLs


! Use aspects to manage the internal access to resources,
Method_missing collisions, etc.

! Dont expose AOP concepts directly!

! Cant you just use objects and metaprogramming?


! Yes, but:
Its all ad hoc and harder than it needs to be. Lots of hard boilerplate that isnt very DRY.

! Aspects are a natural fit for keeping non-trivial, cross-cutting concerns modular.

1993-2007 Object Mentor Incorporated. All Rights Reserved. www.objectmentor.com 1-800-338-6716

Version 1.0 / Page 75

Conclusions ! Ruby doesnt have native AOP support. ! Rubys metaprogramming features cover many requirements.
! We saw examples of what you can do today. ! 3rd-party libraries implement some AOP concepts.

! As applications grow more complex, AOP will grow more important.


! Hence, explicit AOP support will be needed in Ruby.

! An AOP infrastructure will make it easier to implement cross-cutting concerns with less explicit metaprogramming.

1993-2007 Object Mentor Incorporated. All Rights Reserved. www.objectmentor.com 1-800-338-6716

Version 1.0 / Page 76

38

Thank You! ! dean@objectmentor.com ! objectmentor.com ! aosd.net ! aspectprogramming.com ! aspectprogramming.com/sdwest2007/ ! aosd.net/2007/program/industry/I6AspectDesignPrinciples.pdf

1993-2007 Object Mentor Incorporated. All Rights Reserved. www.objectmentor.com 1-800-338-6716

Version 1.0 / Page 77

39

Vous aimerez peut-être aussi