TDDB84: Lecture 5 Singleton, Builder, Proxy, Mediator fredag 27 - - PowerPoint PPT Presentation

tddb84 lecture 5
SMART_READER_LITE
LIVE PREVIEW

TDDB84: Lecture 5 Singleton, Builder, Proxy, Mediator fredag 27 - - PowerPoint PPT Presentation

TDDB84: Lecture 5 Singleton, Builder, Proxy, Mediator fredag 27 september 13 Creational Singleton Abstract Factory Builder Structural Bridge Composite Proxy Adapter Template method Behavioral Iterator Chain of responsibility


slide-1
SLIDE 1

TDDB84: Lecture 5

Singleton, Builder, Proxy, Mediator

fredag 27 september 13

slide-2
SLIDE 2

Template method Iterator

LE3 LE4 LE5 LE6 Behavioral Structural Creational

Abstract Factory Composite Builder Singleton Proxy Mediator Adapter Bridge Observer Chain of responsibility

LA1

Observer

LA2

Creational patterns

LA3

Structural patterns

fredag 27 september 13

slide-3
SLIDE 3

Template method Iterator

LE3 LE4 LE5 LE6 Behavioral Structural Creational

Abstract Factory Composite Builder Singleton Proxy Mediator Adapter Bridge Observer Chain of responsibility

LA1

Observer

LA2

Creational patterns

LA3

Structural patterns Dynamic proxies in C# & Java Classes ARE objects, and each object can have a class (in Ruby)

fredag 27 september 13

slide-4
SLIDE 4

Muddy Cards

  • Compare patterns
  • Fewer examples
  • Present more patterns
  • More UML
  • Lab session staffing/time sharing

fredag 27 september 13

slide-5
SLIDE 5

The assistant role

Let me go!

fredag 27 september 13

slide-6
SLIDE 6

The assistant role

Let me go!

fredag 27 september 13

slide-7
SLIDE 7

On UML

fredag 27 september 13

slide-8
SLIDE 8

What is this?

X1 Y1 Y2 f() y X y.g() g() Y

fredag 27 september 13

slide-9
SLIDE 9

Bridge?

fredag 27 september 13

slide-10
SLIDE 10

Builder?

fredag 27 september 13

slide-11
SLIDE 11

Strategy?

Context1 ConcreteStrategy1 ConcreteStrategy2 f() strategy Context strategy.g() g() Strategy

fredag 27 september 13

slide-12
SLIDE 12

What UML?

Arrays.sort(ducks, (arg0, arg1) -> new Integer(arg1.weight).compareTo(arg0.weight))

fredag 27 september 13

slide-13
SLIDE 13

1. What are the relationships between the Strategy and Flyweight patterns? a) They both concern decoupling objects from their dependencies b) Using a Flyweight pattern may also require the Strategy pattern c) Using the Strategy pattern may also result in using the Flyweight pattern d) The Strategy pattern, if implemented with the use of type template parameters, does not necessitate the Flyweight pattern e) You often implement the Flyweight pattern by using the Strategy pattern for object creation f) The Flyweight pattern is a simplified form of the Strategy pattern

fredag 27 september 13

slide-14
SLIDE 14
  • 1. What are the relationships between the Strategy and Flyweight patterns?

a) They both concern decoupling objects from their dependencies

  • True. As in the strategy pattern behavior or independent and in the flyweight pattern we implement a kind of factory which decouple object from their

dependencies. b) Using a Flyweight pattern may also require the Strategy pattern False. c) Using the Strategy pattern may also result in using the Flyweight pattern

  • True. As behavior (strategy objects) can be implemented as flyweight to enable to share behavior objects, and avoid creating several time the same behavior
  • bject.

d) The Strategy pattern, if implemented with the use of type template parameters, does not necessitate the Flyweight pattern

  • False. I think that using template parameters doesn't prevent from creating unnecessary new objects.

e) You often implement the Flyweight pattern by using the Strategy pattern for object creation

  • False. As strategy pattern is not a creational pattern and enable to use different algorithm and not to create different objects.

f) The Flyweight pattern is a simplified form of the Strategy pattern

  • False. UML seems similar (GoF p198, 316) but they don't do the same thing at all, strategy enable to use different algorithm and change them runtime whereas

the goal of flyweight pattern is to create new object, if they weren't created before,or to share object if the same object was created before.

fredag 27 september 13

Correct answers marked

slide-15
SLIDE 15
  • 1. What are the relationships between the Strategy and Flyweight patterns?

a) They both concern decoupling objects from their dependencies

  • True. As in the strategy pattern behavior or independent and in the flyweight pattern we implement a kind of factory which decouple object from their

dependencies. b) Using a Flyweight pattern may also require the Strategy pattern False. c) Using the Strategy pattern may also result in using the Flyweight pattern

  • True. As behavior (strategy objects) can be implemented as flyweight to enable to share behavior objects, and avoid creating several time the same behavior
  • bject.

d) The Strategy pattern, if implemented with the use of type template parameters, does not necessitate the Flyweight pattern

  • False. I think that using template parameters doesn't prevent from creating unnecessary new objects.

e) You often implement the Flyweight pattern by using the Strategy pattern for object creation

  • False. As strategy pattern is not a creational pattern and enable to use different algorithm and not to create different objects.

f) The Flyweight pattern is a simplified form of the Strategy pattern

  • False. UML seems similar (GoF p198, 316) but they don't do the same thing at all, strategy enable to use different algorithm and change them runtime whereas

the goal of flyweight pattern is to create new object, if they weren't created before,or to share object if the same object was created before.

fredag 27 september 13

Correct answers marked

slide-16
SLIDE 16

c) Using the Strategy pattern may also result in using the Flyweight pattern Flyweights are light-weight objects with externalized state, useful if supplying multiple strategies to a problem-solving context d) The Strategy pattern, if implemented with the use of type template parameters, does not necessitate the Flyweight pattern Using a template parameter, See C# demo

public class TaxCalculation<T>

  • where T: TaxStrategy, new()
  • {
  • private static T taxStrategy = Activator.CreateInstance<T>();
  • public TaxCalculation ()
  • {
  • }
  • public double GetTax(Person p) {
  • return taxStrategy.calculateTax(p.Salary);
  • }
  • }

fredag 27 september 13

slide-17
SLIDE 17

c) Using the Strategy pattern may also result in using the Flyweight pattern Flyweights are light-weight objects with externalized state, useful if supplying multiple strategies to a problem-solving context d) The Strategy pattern, if implemented with the use of type template parameters, does not necessitate the Flyweight pattern Using a template parameter, See C# demo

public class TaxCalculation<T>

  • where T: TaxStrategy, new()
  • {
  • private static T taxStrategy = Activator.CreateInstance<T>();
  • public TaxCalculation ()
  • {
  • }
  • public double GetTax(Person p) {
  • return taxStrategy.calculateTax(p.Salary);
  • }
  • }

fredag 27 september 13

slide-18
SLIDE 18

Singleton

fredag 27 september 13

slide-19
SLIDE 19

public class Singleton { private static Singleton instance = new Singleton(); private String name; public String getName() { return name; } private Singleton() { [ ... ] } }

fredag 27 september 13

slide-20
SLIDE 20

public class Singleton { private static Singleton instance = new Singleton(); private String name; public String getName() { return name; } private Singleton() { [ ... ] } } private Singleton() { try { // Very expensive job indeed Thread.sleep(100); } catch (InterruptedException e) { e.printStackTrace(); } name = Math.random() > 0.5 ? "Jonas" : "Anders"; }

fredag 27 september 13

slide-21
SLIDE 21

public class Singleton { private static Singleton instance = new Singleton(); private String name; public String getName() { return name; } private Singleton() { [ ... ] } }

Our app takes forever to load

private Singleton() { try { // Very expensive job indeed Thread.sleep(100); } catch (InterruptedException e) { e.printStackTrace(); } name = Math.random() > 0.5 ? "Jonas" : "Anders"; }

fredag 27 september 13

slide-22
SLIDE 22

public class Singleton { private static Singleton instance = new Singleton(); private String name; public String getName() { return name; } private Singleton() { [ ... ] } }

Our app takes forever to load

public static void someOtherMethod(){ System.out.println("Hi there!"); }

What about static methods?

private Singleton() { try { // Very expensive job indeed Thread.sleep(100); } catch (InterruptedException e) { e.printStackTrace(); } name = Math.random() > 0.5 ? "Jonas" : "Anders"; }

fredag 27 september 13

slide-23
SLIDE 23

Thread t1 = new Thread(new StaticMethodInvocation()); Thread t2 = new Thread(new SingletonLookup()); t0 = System.nanoTime(); t1.start(); t2.start(); try { t1.join(); t2.join(); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } someOtherMethod invoked Singleton name: Anders Singleton lookup took 1 003 348 000 ns Static method invocation took 1 002 463 000 ns

fredag 27 september 13

slide-24
SLIDE 24

private static Singleton instance; public static Singleton getInstance() { if (instance == null) { instance = new Singleton(); } return instance; }

How about now?

someOtherMethod invoked Static method invocation took 899 000 ns Singleton name: Anders Singleton lookup took 1 002 277 000 ns

fredag 27 september 13

slide-25
SLIDE 25

What about threads?

fredag 27 september 13

slide-26
SLIDE 26

private Singleton() { try { // Very expensive job indeed Thread.sleep(100); } catch (InterruptedException e) { e.printStackTrace(); } name = Math.random() > 0.5 ? "Jonas" : "Anders"; }

fredag 27 september 13

slide-27
SLIDE 27

private Singleton() { try { // Very expensive job indeed Thread.sleep(100); } catch (InterruptedException e) { e.printStackTrace(); } name = Math.random() > 0.5 ? "Jonas" : "Anders"; } private static final class SingletonLookup implements Runnable { @Override public void run() { System.out.println(MessageFormat.format("Singleton name: {0}", Singleton.getInstance().getName())); } } public static void main(String[] args) { Thread t1 = new Thread(new SingletonLookup()); Thread t2 = new Thread(new SingletonLookup()); t0 = System.nanoTime(); t1.start(); t2.start(); try { t1.join(); t2.join(); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } System.out.println("Singleton name after our threads have run: "+Singleton.getInstance().getName()); }

fredag 27 september 13

slide-28
SLIDE 28

private Singleton() { try { // Very expensive job indeed Thread.sleep(100); } catch (InterruptedException e) { e.printStackTrace(); } name = Math.random() > 0.5 ? "Jonas" : "Anders"; } private static final class SingletonLookup implements Runnable { @Override public void run() { System.out.println(MessageFormat.format("Singleton name: {0}", Singleton.getInstance().getName())); } } public static void main(String[] args) { Thread t1 = new Thread(new SingletonLookup()); Thread t2 = new Thread(new SingletonLookup()); t0 = System.nanoTime(); t1.start(); t2.start(); try { t1.join(); t2.join(); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } System.out.println("Singleton name after our threads have run: "+Singleton.getInstance().getName()); }

fredag 27 september 13

slide-29
SLIDE 29

private Singleton() { try { // Very expensive job indeed Thread.sleep(100); } catch (InterruptedException e) { e.printStackTrace(); } name = Math.random() > 0.5 ? "Jonas" : "Anders"; } private static final class SingletonLookup implements Runnable { @Override public void run() { System.out.println(MessageFormat.format("Singleton name: {0}", Singleton.getInstance().getName())); } } public static void main(String[] args) { Thread t1 = new Thread(new SingletonLookup()); Thread t2 = new Thread(new SingletonLookup()); t0 = System.nanoTime(); t1.start(); t2.start(); try { t1.join(); t2.join(); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } System.out.println("Singleton name after our threads have run: "+Singleton.getInstance().getName()); }

fredag 27 september 13

slide-30
SLIDE 30

private Singleton() { try { // Very expensive job indeed Thread.sleep(100); } catch (InterruptedException e) { e.printStackTrace(); } name = Math.random() > 0.5 ? "Jonas" : "Anders"; } private static final class SingletonLookup implements Runnable { @Override public void run() { System.out.println(MessageFormat.format("Singleton name: {0}", Singleton.getInstance().getName())); } } public static void main(String[] args) { Thread t1 = new Thread(new SingletonLookup()); Thread t2 = new Thread(new SingletonLookup()); t0 = System.nanoTime(); t1.start(); t2.start(); try { t1.join(); t2.join(); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } System.out.println("Singleton name after our threads have run: "+Singleton.getInstance().getName()); }

fredag 27 september 13

slide-31
SLIDE 31

private Singleton() { try { // Very expensive job indeed Thread.sleep(100); } catch (InterruptedException e) { e.printStackTrace(); } name = Math.random() > 0.5 ? "Jonas" : "Anders"; } private static final class SingletonLookup implements Runnable { @Override public void run() { System.out.println(MessageFormat.format("Singleton name: {0}", Singleton.getInstance().getName())); } } public static void main(String[] args) { Thread t1 = new Thread(new SingletonLookup()); Thread t2 = new Thread(new SingletonLookup()); t0 = System.nanoTime(); t1.start(); t2.start(); try { t1.join(); t2.join(); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } System.out.println("Singleton name after our threads have run: "+Singleton.getInstance().getName()); } Singleton name: Anders Singleton name: Jonas Singleton name after our threads have run: Anders

Oops!

fredag 27 september 13

slide-32
SLIDE 32

Singleton name: Anders Singleton name: Anders Singleton lookup took 1 003 340 000 ns Singleton lookup took 1 003 286 000 ns Singleton name after our threads have run: Anders public static synchronized Singleton getInstance() { if (instance == null) { instance = new Singleton(); } return instance; }

Woohoo!

fredag 27 september 13

slide-33
SLIDE 33

Singleton name: Anders Singleton name: Anders Singleton lookup took 1 003 340 000 ns Singleton lookup took 1 003 286 000 ns Singleton name after our threads have run: Anders public static synchronized Singleton getInstance() { if (instance == null) { instance = new Singleton(); } return instance; }

Woohoo!

fredag 27 september 13

slide-34
SLIDE 34

Singleton as Enum

public enum EnumSingleton { INSTANCE; private String name; private int age; public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } }

fredag 27 september 13

slide-35
SLIDE 35

Singletons in Ruby

Class MetaClass A A Object foo

class A; end foo = A.new class A; end

fredag 27 september 13

slide-36
SLIDE 36

Singletons in Ruby

Class MetaClass A A Object foo Singleton Class for foo

class << foo; end class A; end foo = A.new class A; end

fredag 27 september 13

slide-37
SLIDE 37

Singletons in Ruby

Class MetaClass A A Object foo Singleton Class for foo

class << foo; end class A; end foo = A.new class A; end

Singleton Class for A

class << A; end

fredag 27 september 13

slide-38
SLIDE 38

class A end a = A.new class << A def new raise "Illegal!" end end

irb(main):014:0> a #<A:0x007f8d6b92bcb0> irb(main):016:0> A.new RuntimeError: Illegal! from (irb):10:in `new' from (irb):16 from /Users/olale/.rvm/rubies/ruby-2.0.0-p247/bin/irb:13:in `<main>'

Now we have one object, but we cannot produce another

  • f the same class

fredag 27 september 13

slide-39
SLIDE 39

Singleton: consequences

fredag 27 september 13

slide-40
SLIDE 40

Singleton: consequences

+Ensures single objects per

class

fredag 27 september 13

slide-41
SLIDE 41

Singleton: consequences

  • Violates several design

principles!

+Ensures single objects per

class

fredag 27 september 13

slide-42
SLIDE 42

Singleton considered dangerous

  • Encapsulate what varies
  • Program to an interface, not to an implementation
  • Favor composition over inheritance
  • Classes should be open for extension but closed for

modification

  • Don’t call us, we’ll call you
  • Depend on abstractions, do not depend on concrete

classes

  • Classes should only have one reason to change
  • Strive for loosely-coupled design

fredag 27 september 13

slide-43
SLIDE 43

Singleton considered dangerous

  • Encapsulate what varies
  • Program to an interface, not to an implementation
  • Favor composition over inheritance
  • Classes should be open for extension but closed for

modification

  • Don’t call us, we’ll call you
  • Depend on abstractions, do not depend on concrete

classes

  • Classes should only have one reason to change
  • Strive for loosely-coupled design

fredag 27 september 13

slide-44
SLIDE 44

Singleton considered dangerous

  • Encapsulate what varies
  • Program to an interface, not to an implementation
  • Favor composition over inheritance
  • Classes should be open for extension but closed for

modification

  • Don’t call us, we’ll call you
  • Depend on abstractions, do not depend on concrete

classes

  • Classes should only have one reason to change
  • Strive for loosely-coupled design

fredag 27 september 13

slide-45
SLIDE 45

Singleton considered dangerous

  • Encapsulate what varies
  • Program to an interface, not to an implementation
  • Favor composition over inheritance
  • Classes should be open for extension but closed for

modification

  • Don’t call us, we’ll call you
  • Depend on abstractions, do not depend on concrete

classes

  • Classes should only have one reason to change
  • Strive for loosely-coupled design

fredag 27 september 13

slide-46
SLIDE 46

Builder

fredag 27 september 13

slide-47
SLIDE 47

fredag 27 september 13

slide-48
SLIDE 48

Client Director Builder build() buildA() buildB() buildC() getProduct()

fredag 27 september 13

slide-49
SLIDE 49

fredag 27 september 13

slide-50
SLIDE 50

fredag 27 september 13

slide-51
SLIDE 51

Director

fredag 27 september 13

slide-52
SLIDE 52

Director Client

fredag 27 september 13

slide-53
SLIDE 53

Director Client Builder

fredag 27 september 13

slide-54
SLIDE 54

Demo

fredag 27 september 13

slide-55
SLIDE 55

Client requests a product from Factory Client receives a Factory Client receives an abstract product

Abstract Factory

fredag 27 september 13

slide-56
SLIDE 56

Client requests a product from Factory Client receives a Factory Client receives an abstract product

Abstract Factory

Client asks Director to build Client receives a builder-specific product Client initializes Director with Builder Client requests product from Builder

Builder

fredag 27 september 13

slide-57
SLIDE 57

Client requests a product from Factory Client receives a Factory Client receives an abstract product

Abstract Factory

Client asks Director to build Client receives a builder-specific product Client initializes Director with Builder Client requests product from Builder

Builder

fredag 27 september 13

slide-58
SLIDE 58

Client requests a product from Factory Client receives a Factory Client receives an abstract product

Abstract Factory

Client asks Director to build Client receives a builder-specific product Client initializes Director with Builder Client requests product from Builder

Builder

fredag 27 september 13

slide-59
SLIDE 59

Client requests a product from Factory Client receives a Factory Client receives an abstract product

Abstract Factory

Client asks Director to build Client receives a builder-specific product Client initializes Director with Builder Client requests product from Builder

Builder

fredag 27 september 13

slide-60
SLIDE 60

Client requests a product from Factory Client receives a Factory Client receives an abstract product

Abstract Factory

Client asks Director to build Client receives a builder-specific product Client initializes Director with Builder Client requests product from Builder

Builder

fredag 27 september 13

slide-61
SLIDE 61

Builder: consequences

fredag 27 september 13

slide-62
SLIDE 62

Builder: consequences

+Can control the way

  • bjects are created

fredag 27 september 13

slide-63
SLIDE 63

Builder: consequences

+Can control the way

  • bjects are created

+Can produce different

products using the same Director

fredag 27 september 13

slide-64
SLIDE 64

Builder: consequences

  • Not necessarily a

common interface for products

+Can control the way

  • bjects are created

+Can produce different

products using the same Director

fredag 27 september 13

slide-65
SLIDE 65

Builder: consequences

  • Not necessarily a

common interface for products

  • Clients must know how

to initialize builders and retrieve products

+Can control the way

  • bjects are created

+Can produce different

products using the same Director

fredag 27 september 13

slide-66
SLIDE 66

Design principles

  • Encapsulate what varies
  • Program to an interface, not to an implementation
  • Favor composition over inheritance
  • Classes should be open for extension but closed for

modification

  • Don’t call us, we’ll call you
  • Depend on abstractions, do not depend on concrete

classes

  • Classes should only have one reason to change
  • Strive for loosely-coupled design

fredag 27 september 13

slide-67
SLIDE 67

Mediator

fredag 27 september 13

slide-68
SLIDE 68
  • nEvent(){

checkCalendar(); checkSprinkler(); startCoffee(); //do more stuff }

  • nEvent(){

checkDayOfTheWeek(); doShower(); doCoffee(); doAlarm(); //do more stuff }

  • nEvent(){

checkCalendar(); checkAlarm(); //do more stuff }

  • nEvent(){

checkCalendar(); checkShower(); checkTemperature //do more stuff }

fredag 27 september 13

slide-69
SLIDE 69

if(alarmEvent)(){ checkCalendar(); checkShower(); checkTemp(); //do more stuff } if(weekend){ checkWeather(); } if(trashDay){ resetAlarm(); }

fredag 27 september 13

slide-70
SLIDE 70

Demo

fredag 27 september 13

slide-71
SLIDE 71

Mediator vs Observer

fredag 27 september 13

slide-72
SLIDE 72

Mediator: consequences

fredag 27 september 13

slide-73
SLIDE 73

Mediator: consequences

  • Creates a complex

single point of failure

fredag 27 september 13

slide-74
SLIDE 74

Mediator: consequences

  • Creates a complex

single point of failure

+The Mediator and its

colleagues can be varied independently

fredag 27 september 13

slide-75
SLIDE 75

Mediator: consequences

  • Creates a complex

single point of failure

+The Mediator and its

colleagues can be varied independently

+Replaces N-M

relationships with 1-M relationships with the Mediator in the middle

fredag 27 september 13

slide-76
SLIDE 76

Mediator: consequences

  • Creates a complex

single point of failure

+The Mediator and its

colleagues can be varied independently

+Replaces N-M

relationships with 1-M relationships with the Mediator in the middle

+Centralizes interaction

management

fredag 27 september 13

slide-77
SLIDE 77

Proxy

fredag 27 september 13

slide-78
SLIDE 78

fredag 27 september 13

slide-79
SLIDE 79

Id Name Age 1 Ola 34 2 Lisa 31 Id StartDate EndDate PersonId 2012-05-01 1 2012-06-01 1 2 2001-04-06 2006-07-29 2 3 2004-01-01 2010-12-31 1 4 2006-07-30 2007-11-30 2

Person Employment

  • public class Person: DomainObject
  • {
  • public String Name { get; set;}
  • public String Age { get; set;}
  • public virtual ICollection<Employment> Employments { get; set;}
  • }
  • public class Employment: DomainObject
  • {
  • public virtual Person Person { get; set;}
  • public DateTime StartDate { get; set;}
  • public DateTime EndDate { get; set;}
  • }

fredag 27 september 13

slide-80
SLIDE 80
  • var people = GenericDAO<Person>.Get();
  • people.Should ().NotBeEmpty ();
  • Retrieve records from the table Person

and map them to objects Intercept method calls to access the property Employments (get_Employments) and fetch the related Employments records for the current Person object

2 1

people.First ().Employments.Should ().NotBeNull ();

Data Access Layer All ORM layers support this

fredag 27 september 13

slide-81
SLIDE 81

public class LazyLoadingInterceptor<T>:BaseInterceptor,IInterceptor where T:class, new() { private static string GetPropertyName(string getterName) { return getterName.Remove(0,4); } public void Intercept(IInvocation invocation) {

  • bject proxy=invocation.Proxy;

// Get the target property access method var target=invocation.MethodInvocationTarget; string propertyName=GetPropertyName(target.Name); if(target.Name.StartsWith("get_")) { Prefetcher<T>.FetchRelatedProperty(new List<T>() { proxy as T },typeof(T).GetProperty(propertyName)); } invocation.Proceed(); } }

Castle DynamicProxy

fredag 27 september 13

slide-82
SLIDE 82

Demo

fredag 27 september 13

slide-83
SLIDE 83

Java: InvocationHandler

return (PersonBean) Proxy.newProxyInstance( person.getClass().getClassLoader(), person.getClass().getInterfaces(), new NonOwnerInvocationHandler(person)); package headfirst.proxy.javaproxy;

fredag 27 september 13

slide-84
SLIDE 84

Ruby: method_missing

class A def initialize name @name=name end def foo "foo" end def bar "bar" end def to_s @name end end class AProxy def initialize(a) @a = a end def method_missing(m,*args) p "calling #{m} on #{@a}" @a.send(m,*args) end end

fredag 27 september 13

slide-85
SLIDE 85

Ruby: method_missing

class A def initialize name @name=name end def foo "foo" end def bar "bar" end def to_s @name end end class AProxy def initialize(a) @a = a end def method_missing(m,*args) p "calling #{m} on #{@a}" @a.send(m,*args) end end irb(main):067:0> proxy=AProxy.new(A.new("original_object")) #<AProxy:0x007fa26a12bc40 @a=#<A:0x007fa26a12bc68 @name="original_object">> irb(main):068:0> proxy.foo "calling foo on original_object" "foo"

fredag 27 september 13

slide-86
SLIDE 86

Proxy: consequences

fredag 27 september 13

slide-87
SLIDE 87

Proxy: consequences

  • Depending on the

implementation, proxies may incur an overhead cost for method calls

fredag 27 september 13

slide-88
SLIDE 88

Proxy: consequences

  • Depending on the

implementation, proxies may incur an overhead cost for method calls

  • Depending on the

implementation, proxies may require that all proxied objects implement interfaces (in Java)

fredag 27 september 13

slide-89
SLIDE 89

Proxy: consequences

  • Depending on the

implementation, proxies may incur an overhead cost for method calls

  • Depending on the

implementation, proxies may require that all proxied objects implement interfaces (in Java)

+Allows expensive objects

to be referenced before they are fully initialized

fredag 27 september 13

slide-90
SLIDE 90

Proxy: consequences

  • Depending on the

implementation, proxies may incur an overhead cost for method calls

  • Depending on the

implementation, proxies may require that all proxied objects implement interfaces (in Java)

+Allows expensive objects

to be referenced before they are fully initialized

+Can transparently extend

  • bjects with new aspects

such as access control, logging, method call forwarding, lazy loading

fredag 27 september 13

slide-91
SLIDE 91

Singleton, Builder, Proxy, Mediator

Summary

fredag 27 september 13

slide-92
SLIDE 92

Next seminar

fredag 27 september 13