- another example of a structural pattern

Post on 22-Jan-2016

36 Views

Category:

Documents

0 Downloads

Preview:

Click to see full reader

DESCRIPTION

Decorator Pattern. - Another Example of a Structural Pattern Alternative way of adding Functionality to an existing class (alternative to a derived class) Favors Composition over Inheritance Often referred to as a Wrapper Advantage: No need for several levels of Inheritence - PowerPoint PPT Presentation

TRANSCRIPT

Nov 2005 MSc Slide

1

- Another Example of a Structural Pattern

Alternative way of adding Functionality to an existing class (alternative to a derived class)

Favors Composition over Inheritance

Often referred to as a Wrapper

Advantage: No need for several levels of Inheritence (reduces Complexity)

Decorator Pattern

Nov 2005 MSc Slide

2

Instead of:

Decorator Pattern

X

Y

Z Z p = new Z();

X Y Z

Z p=new Z(new Y(new X()));

Can add functionality by adding more Objects

Nov 2005 MSc Slide

3

Typically used to change appearanceof a Visual Component

One big advantage is that you can dynamically change appearance/functionality of a component

Decorator Pattern

Nov 2005 MSc Slide

4

Decorator Pattern

Want to decorate a Button

Nov 2005 MSc Slide

5

using System;using System.Windows.Forms;using System.Drawing;

abstract class Decorator : Panel { protected Control ctrl; public Decorator(Control c) {

this.Size=c.Size; ctrl=c; Controls.Add(c); c.Paint += new PaintEventHandler( paint); }

virtual public void paint(object sender, PaintEventArgs pe){}}

Nov 2005 MSc Slide

6

class SlashDecorator : Decorator {

public SlashDecorator(Control c):base(c) {}

override public void paint(object sender, PaintEventArgs pe){ Pen aPen = new Pen(Color.Black , 1); Graphics g = pe.Graphics;

int x2 = this.Size.Width; int y2 = this.Size.Height; g.DrawLine(aPen,0,0,x2,y2);

} }

Nov 2005 MSc Slide

7

class GFrame:Form {private Button cbutton=new Button();private Button dbutton=new Button();private SlashDecorator d;public GFrame():base(){

cbutton.Text="cbutton"; dbutton.Text="dbutton"; d=new SlashDecorator(dbutton); cbutton.SetBounds(10,10,cbutton.Size.Width, cbutton.Size.Height); d.SetBounds(100,10,d.Size.Width,d.Size.Height); Controls.Add(cbutton); Controls.Add(d);

}}

Nov 2005 MSc Slide

8

public class Test92{public static void Main(string[] args){

Application.Run(new GFrame());}

}

Nov 2005 MSc Slide

9

Example 2:

This time we have a Decorated Label

Nov 2005 MSc Slide

10

using System;using System.Windows.Forms;using System.Drawing;

abstract class Decorator : Panel { protected Control ctrl; public Decorator(Control c) {

this.Size=c.Size; ctrl=c; Controls.Add(c); c.Paint += new PaintEventHandler( paint); }

virtual public void paint(object sender, PaintEventArgs pe){}}

As before

Nov 2005 MSc Slide

11

class CoolDecorator : Decorator {

public CoolDecorator(Control c):base(c) { }

override public void paint(object sender, PaintEventArgs pe){ Pen aPen = new Pen(Color.Red , 2);

Graphics g = pe.Graphics; int x2 = this.Size.Width;

int y2 = this.Size.Height; g.DrawRectangle(aPen,0,0,x2,y2);

} }

Draw a Rectangle

Nov 2005 MSc Slide

12

class GFrame:Form {private Label l=new Label();private CoolDecorator c;

public GFrame():base(){ l.Text="MyLabel"; c=new CoolDecorator(l); c.SetBounds(10,10,c.Size.Width, c.Size.Height-5); Controls.Add(c);

}}

Nov 2005 MSc Slide

13

public class Test92{public static void Main(string[] args){

Application.Run(new GFrame());}

}

Nov 2005 MSc Slide

14

Now to add Dynamic Behaviour, change Colour to Blue

Nov 2005 MSc Slide

15

class CoolDecorator : Decorator { bool mouse_over=false;

public CoolDecorator(Control c):base(c) { EventHandler evh = new EventHandler(mouseEnter); ctrl.MouseEnter+= evh; ctrl.MouseLeave += new EventHandler(mouseLeave); } public void mouseEnter(object sender, EventArgs e){ mouse_over = true; ctrl.Refresh (); } public void mouseLeave(object sender, EventArgs e){ mouse_over = false; this.Refresh (); }

Nov 2005 MSc Slide

16

override public void paint(object sender, PaintEventArgs pe){ Pen aPen = new Pen(Color.Red , 2); Pen bPen = new Pen(Color.Blue , 2); Graphics g = pe.Graphics;

int x2 = this.Size.Width; int y2 = this.Size.Height; g.DrawRectangle(aPen,0,0,x2,y2); if (mouse_over == true){ g.DrawRectangle(bPen,0,0,x2,y2);} } }

Nov 2005 MSc Slide

17

UML Class DiagramControl

CoolDecorator SlashDecorator

GFrame

Decorator Control

Panel

Nov 2005 MSc Slide

18

Big Advantage of Decorator(Wrapper) is that you can addfunctionality by adding Objects

Label lab=new Label(); lab.Text="Example"; SlashDecorator c=new SlashDecorator(lab); Controls.Add(c);

Nov 2005 MSc Slide

19

Combining Decorators

c=new CoolDecorator(b);Normally:

Want: c=new SlashDecorator(new CoolDecorator(b));

Nov 2005 MSc Slide

20

Combining Decorators

c=new CoolDecorator(null, b);Normal Wrapper:

Embedded Wrapper:

sd=new SlashDecorator(new CoolDecorator(null,b),b);

In practice new a ref to parent and underlying control:

Nov 2005 MSc Slide

21

abstract class Decorator : Panel {protected Control ctrl; public Decorator(Control c) {

this.Size=c.Size; ctrl=c; Controls.Add(c); c.Paint += new PaintEventHandler( paint); }

virtual public void paint(object sender, PaintEventArgs pe){}}

As before

Nov 2005 MSc Slide

22

class CoolDecorator : Decorator { bool mouse_over=false; SlashDecorator sdec;

public CoolDecorator(SlashDecorator sdec,Control c) :base(c) { this.sdec = sdec; if (sdec !=null) c.Paint += new PaintEventHandler( sdec.paint); EventHandler evh = new EventHandler(mouseEnter); ctrl.MouseEnter+= evh; MouseEventHandler(mouseMove); ctrl.MouseLeave += new EventHandler(mouseLeave); }

override public void paint(object sender, …

As before

Nov 2005 MSc Slide

23

class SlashDecorator : Decorator { private CoolDecorator cd=null;

public SlashDecorator(CoolDecorator cd,Control c) :base(c) {

this.cd=cd; if (cd !=null)

c.Paint += new PaintEventHandler( cd.paint);}

override public void paint(object sender, …

As before

Nov 2005 MSc Slide

24

class GFrame:Form {private Label l=new Label();private SlashDecorator sd;

public GFrame():base(){ l.Text="MyLabel";

sd=new SlashDecorator(new CoolDecorator(null,l),l);

sd.SetBounds(100,10,sd.Size.Width,sd.Size.Height); Controls.Add(sd); this.Refresh();}

Nov 2005 MSc Slide

25

Exercise 0:

Modify the first Decorator (test0.java) so its in the following format

Nov 2005 MSc Slide

26

Exercise 1: Modify Exercise 0 to include some dynamic Behaviour

Red X

top related