I am trying to implement the Decorator Pattern in a very simple example.
In this way, which should be the right one as far as "Decorator Interface" implements "Shape Interface" it does not work.
The line triangle := TGreenShapeDecorator.create(triangle); fails because tringle is of type IShape but not IShapeDecorator;
program project1;
{$mode objfpc}{$H+}
uses
Classes, SysUtils;
type
{Shape Interface}
IShape = interface
function draw():String;
end;
{Clase 1}
TTriangle = class(TInterfacedObject, IShape)
function draw():String;
end;
{Decorator Interface}
IShapeDecorator = interface(IShape)
property shape:IShape;
function draw():String;
end;
{Decorator 1}
TGreenShapeDecorator = class(TInterfacedObject, IShapeDecorator)
shape : IShape;
constructor create(shape_in:IShape);
function draw():String;
end;
function TTriangle.draw():String;
begin
Result := 'Triangle';
end;
constructor TGreenShapeDecorator.Create(shape_in:IShape);
begin
shape := shape_in;
end;
function TGreenShapeDecorator.draw():String;
begin
Result := 'Green ' + shape.draw();
end;
var
triangle : IShape;
begin
// Triangle OBJECT
triangle := TTriangle.Create;
WriteLn(triangle.draw());
// Green decorated triangle
triangle := TGreenShapeDecorator.create(triangle);
WriteLn(triangle.draw());
ReadLn();
end.
In this other way it works:
program project1;
{$mode objfpc}{$H+}
uses
Classes, SysUtils;
type
{Interfaz}
IShape = interface
function draw():String;
end;
{Clase 1}
TTriangle = class(TInterfacedObject, IShape)
function draw():String;
end;
{Decorator Interface}
IShapeDecorator = interface
property shape:IShape;
function draw():String;
end;
{Decorator 1}
TGreenShapeDecorator = class(TInterfacedObject, IShapeDecorator, IShape)
shape : IShape;
constructor create(shape_in:IShape);
function draw():String;
end;
function TTriangle.draw():String;
begin
Result := 'Triangle';
end;
constructor TGreenShapeDecorator.Create(shape_in:IShape);
begin
shape := shape_in;
end;
function TGreenShapeDecorator.draw():String;
begin
Result := 'Green ' + shape.draw();
end;
var
triangle : IShape;
begin
// Triangle OBJECT
triangle := TTriangle.Create;
WriteLn(triangle.draw());
// Green decorated triangle
triangle := TGreenShapeDecorator.create(triangle);
WriteLn(triangle.draw());
ReadLn();
end.
Showing the result:
Triangle Green Triangle
Is it possible to do it in the first way and I am doing something wrong?, or is it not possible and the only way is the second one?
Thank you.
Aucun commentaire:
Enregistrer un commentaire