Expertiza Wiki:Help: Difference between revisions

From Expertiza_Wiki
Jump to navigation Jump to search
No edit summary
No edit summary
 
(5 intermediate revisions by the same user not shown)
Line 13: Line 13:
2.The object being changed should be able to notify other objects about the change without having any idea about the current state    of the objects.
2.The object being changed should be able to notify other objects about the change without having any idea about the current state    of the objects.


As an example consider an application in which we intend to calculate the area and circumference of a circle for varying values of its radius.So we will have a subject class that contains the following methods.
Following is a pseudocode for an application in which we intend to calculate the area and circumference of a circle for varying values of its radius.


1.Attach()
  This method is used to update the list of observers


2.Update()
class Subject
  This method updates the radius and calls the notify method.


3.Notify()
def initialize
  This method notifies all the observers in the list about the event which is the change in the value of the radius.


@list=[]


class Subject
def initialize
@list=[]
end
end
def attach(&list)
def attach(&list)
@list << list
@list << list
end
end
def notify
def notify
@list.each{|x| x.call(@radius)}
@list.each{|x| x.call(@radius)}
end
end
def update(r)
def update(r)
@radius=r
@radius=r
notify
notify
end
end
end
end


class Observer1
class Observer1
def calc_area(radius)
def calc_area(radius)
@area=radius*radius*3.14
@area=radius*radius*3.14
puts "Area #{@area}"
puts "Area #{@area}"
end
end
end
end


class Observer2
class Observer2
def calc_circumference(radius)
def calc_circumference(radius)
@circum=2*3.14*radius
@circum=2*3.14*radius
puts "Circumference #{@circum}"
puts "Circumference #{@circum}"
end
end
end
end


o1=Observer1.new
o1=Observer1.new
o2=Observer2.new
o2=Observer2.new
s=Subject.new
s=Subject.new
s.attach { |s| o1.calc_area(s)}
s.attach { |s| o1.calc_area(s)}
s.attach { |s| o2.calc_circumference(s)}
s.attach { |s| o2.calc_circumference(s)}
s.update(5)
s.update(5)




The output is  
 
The output is
Area 78.5
Area 78.5
Circumference 31.4
Circumference 31.4
Here we have a subject class that contains the following methods.
1.Attach()
  This method is used to update the list of observers
2.Update()
  This method updates the radius and calls the notify method.
3.Notify()
  This method notifies all the observers in the list about the event which is the change in the value of the radius.
We have two observers for calculating area and circumference.
On receiving notify,these functions return updated values of area and circumference depending on the new value of the radius.




Line 72: Line 116:


The iterator pattern provides a way to access the elements of an aggregate object sequentially without exposing its underlying representation.
The iterator pattern provides a way to access the elements of an aggregate object sequentially without exposing its underlying representation.
An aggregate object can be an array or a hash.


Following is a simple example that illustrates the iterator pattern using the power of Ruby closures.


   def find_birthdays_in_range(min,max)
   def find_birthdays_in_range(min,max)
Line 82: Line 128:


A : find_birthdays_in_range
A : find_birthdays_in_range
B : find_all
B : find_all
C : anonymous block  
C : anonymous block  


The third one is the closure ,it accepts one parameter called birthday which is defined in the first function.
The third one is the closure ,it accepts one parameter called birthday which is defined in the first function.Thus we iterate over the array to find only those values which are in the range specified by min and max.

Latest revision as of 00:48, 2 October 2007

Observer Pattern

An observer pattern defines a one to many dependency between objects so that when one object changes state all its dependents are notified and updated accordingly.

In its simplified form, the observer design pattern consists of a subject,and one or more observers,which observe an event in the subject.An event can be a change in the state of the subject and can be defined accordingly.

The subject class maintains a list of observers and contains methods to add and delete observers from the list .It also contains a notify method which is used to notify the observers whenever an event occurs in.The observer class on the other hand contains methods to handle such notifications.

Closures can be used to implement Observer pattern.The role of closures can be the basis of the following two applications of Observer design patterns.

1.A change in one object requires changing other objects.Also the number of objects to be changed is unknown.

2.The object being changed should be able to notify other objects about the change without having any idea about the current state of the objects.

Following is a pseudocode for an application in which we intend to calculate the area and circumference of a circle for varying values of its radius.


class Subject

def initialize

@list=[]

end

def attach(&list)

@list << list

end

def notify

@list.each{|x| x.call(@radius)}

end

def update(r)

@radius=r

notify

end

end


class Observer1

def calc_area(radius)

@area=radius*radius*3.14

puts "Area #{@area}"

end

end


class Observer2

def calc_circumference(radius)

@circum=2*3.14*radius

puts "Circumference #{@circum}"

end

end


o1=Observer1.new

o2=Observer2.new

s=Subject.new

s.attach { |s| o1.calc_area(s)}

s.attach { |s| o2.calc_circumference(s)}

s.update(5)


The output is

Area 78.5

Circumference 31.4


Here we have a subject class that contains the following methods.

1.Attach()

 This method is used to update the list of observers

2.Update()

 This method updates the radius and calls the notify method.

3.Notify()

 This method notifies all the observers in the list about the event which is the change in the value of the radius. 

We have two observers for calculating area and circumference. On receiving notify,these functions return updated values of area and circumference depending on the new value of the radius.


ITERATOR PATTERN

The iterator pattern provides a way to access the elements of an aggregate object sequentially without exposing its underlying representation. An aggregate object can be an array or a hash.

Following is a simple example that illustrates the iterator pattern using the power of Ruby closures.

 def find_birthdays_in_range(min,max)
 birthdays = [ "1970-06-15", "1975-08-13", "1939-03-21", "2001-12-01" ]
 birthdays.find_all { |birthday| birthday > min && birthday < max }
 end

Here there are 3 functions here that are called from within each other.

A : find_birthdays_in_range

B : find_all

C : anonymous block

The third one is the closure ,it accepts one parameter called birthday which is defined in the first function.Thus we iterate over the array to find only those values which are in the range specified by min and max.