Oosc 18 Patterns To Components
Oosc 18 Patterns To Components
Bertrand Meyer
Lecture 18:
Design patterns
A successful story: the Observer pattern
From patterns to components
Design patterns
A successful story: the Observer pattern
From patterns to components
NOT REUSABLE
Design patterns
A successful story: the Observer pattern
From patterns to components
OBSERVER * SUBJECT *
update* add_observer*
remove_observer*
notify_observers*
MY_OBSERVER MY_SUBJECT
add_observer+
update+ remove_observer+
notify_observers+
notify_observers is
-- Notify all observers.
-- (Call update on each observer.)
do
from
observers.start
until
observers.after
loop
observers.item.update
observers.forth
end
end
invariant
observers_not_void: observers /= Void
end
Chair of Software Engineering OOSC - Summer Semester 2004
Class OBSERVER 13
update is
-- Update observer according to the state of
-- subject data.
deferred
end
data: SUBJECT
-- Observable data
end
feature -- Initialization
make is
-- Initialize GUI and register an observer of data.
do
create add_button.make_with_text_and_action (“Add”, agent on_add)
create remove_button.make_with_text_and_action (“Remove”, agent on_remove)
data.add_observer (Current)
end
feature -- Access
add_button: EV_BUTTON
-- Button with label Add
remove_button: EV_BUTTON
-- Button with label Remove
data: MY_DATA
-- Data to be observed
on_add is
-- Action performed when add_button is pressed
do
data.add
end
on_remove is
-- Action performed when remove_button is pressed
do
data.remove
end
update is
-- Update GUI.
do
-- Something here
end
end
SUBJECT
add is
-- Add Current to data to be observed.
do Redundancy:
-- Do something. → Hardly maintainable
notify_observers
end → Not reusable
remove is
-- Remove Current from data to be observed.
do
-- Do something.
notify_observers
end
end
Basically:
One generic class: EVENT_TYPE
Two features: publish and subscribe
Design patterns
A successful story: the Observer pattern
From patterns to components
Prototype
Abstract Factory
Factory Method
Builder
Singleton
Prototype
Abstract Factory
Factory Method
Builder
Singleton
Intent:
“Specify the kinds of objects to create using a
prototypical instance, and create new objects by
copying this prototype.” [Gamma 1995, p 117]
prototype clone
CLIENT PROTOTYPE
Class
Client relationship
In fact: a feature of ANY
Prototype
Abstract Factory
Factory Method
Builder
Singleton
Intent:
“Provide an interface for creating families of related or
dependent objects without specifying their concrete
classes.” [Gamma 1995, p 87]
new_product_a: PRODUCT_A is
-- New product of type PRODUCT_A
deferred
ensure
product_a_not_void: Result /= Void
end
new_product_b: PRODUCT_B is
-- New product of type PRODUCT_B
deferred
ensure
product_b_not_void: Result /= Void
end
end
FACTORY
feature -- Factory methods
new_product_a: PRODUCT_A1 is
-- New product of type PRODUCT_A1
do
create Result
end
new_product_b: PRODUCT_B1 is
-- New product of type PRODUCT_B1
do
create Result
end
end
Code redundancy:
FACTORY_1 and FACTORY_2 will be similar
Lack of flexibility:
FACTORY fixes the set of factory functions
new_product_a and new_product_b
make
feature -- Initialization
feature -- Access
new: G is
-- New instance of type G
do
factory_function.call ([])
Result := factory_function.last_result
ensure
new_not_void: Result /= Void
end
invariant
end
Chair of Software Engineering OOSC - Summer Semester 2004
Sample application 33
+ + *
SIMULATION TRAFFIC VEHICLE
+ + +
CAR BUS METRO
simulated_traffic: TRAFFIC
simulated_traffic.add_vehicle (…)
*
VEHICLE_FACTORY
new_vehicle*
new_car+ + + + new_metro+
CAR_FACTORY BUS_FACTORY METRO_FACTORY
new_bus+
simulated_traffic.add_vehicle ( With:
car_factory.new_car (a_power,
car_factory: CAR_FACTORY is
a_wheel_diameter,
-- Factory of cars
a_door_width,
once
a_door_height) create Result
) ensure
car_factory_not_void: Result /= Void
end
simulated_traffic.add_vehicle (
car_factory.new_with_args ([a_power,
a_wheel_diameter,
a_door_width,
a_door_height]
)
)
With:
car_factory: FACTORY [CAR] is
-- Factory of cars
once
create Result.make (agent new_car)
ensure
car_factory_not_void: Result /= Void
end
and:
Benefits:
Get rid of some code duplication
Fewer classes
Reusability
Prototype
Abstract Factory
Factory Method
Builder
Singleton
Intent:
“Define an interface for creating an object, but
let subclasses decide which class to instantiate.
Factory Method lets a class defer instantiation
to subclasses.” [Gamma 1995, p 107]
Prototype
Abstract Factory
Factory Method
Builder
Singleton
Intent:
“Separate the construction of a complex object
from its representation so that the same
construction process can create different
representations.” [Gamma 1995, p 97]
build is
-- Create and build last_product.
do
build_product
build_part_a
build_part_b
ensure
last_product_not_void: last_product /= Void
end
...
end
Issue:
How to know how many parts the product has?
Not reusable
g: ANY
-- First part of the product to be created
h: ANY
-- Second part of the product to be created
-- set_g
-- set_h
end
Prototype
Abstract Factory
Factory Method
Builder
Singleton
Intent:
“Ensure a class only has one instance, and
provide a global point of access to it.”
[Gamma 1995, p 127]
singleton
SHARED_ SINGLETON SINGLETON
invariant
end
invariant
singleton_created: singleton_created
singleton_pattern: Current = singleton
end
Composite Proxy
Flyweight Decorator
Adapter
Bridge
Facade
Karine Arnout. Contracts and tests. Ph.D. research plan, December 2002.
Available from http://se.inf.ethz.ch/people/arnout/phd_research_plan.pdf
Karine Arnout, and Éric Bezault. “How to get a Singleton in Eiffel?”. Available
from http://se.inf.ethz.ch/people/arnout/arnout_bezault_singleton.pdf
End of lecture 18