There is an educational task:

Define class specifications for representing graphic manipulators of geometric properties (position, size) in the vector graphics editor.

And there are three patterns: composite, decorator, and proxy. It seems to me that here is the decorator.

It is necessary to implement it with "stubs", i.e. not graphically.

And I ran into the problem that I cannot implement it as a pure decorator, since the functions for changing the size and position require transmitted values.

public interface Shape { public void draw(); public void setX(int x); public void setY(int y); public void setLength(int length); public void setHeight(int height); public void changePosition(int x, int y); public void changeSize(int length, int height); } 

The descendants that inherit the Shape also have the functions changePosition(int x, int y) and changeSize(int length, int height) , and it seems to me that this is not entirely correct. Maybe I chose the wrong pattern?

  • I didn’t understand something, what needs to be done, what has already been done, and what I don’t really like? - Grundy
  • Composite is better. So you can combine objects into groups and manipulate with groups as graphic objects, causing resizing for all child elements. - Dmitriy Simushev
  • @grundy does not like the fact that the decorator does not seem to be a decorator. - thundermind
  • @Dmitriy Simushev but the decorator extends the functionality - thundermind
  • one
    @thundermind, and as for Composite , it may be redundant in this case. A little thought, I do not really imagine why within the framework of this task the listed patterns are needed. - Dmitriy Simushev

1 answer 1

Decorator has nothing to do with the fact that descendants have their own functions.

And this is also an erroneous statement:

I cannot implement it as a pure decorator, since the functions for changing the size and position require transmitted values.

The decorator for the specified interface will look like this:

 public class ShapeWrapper implements Shape { private Shape original; public void draw() { original.draw(); } public void setX(int x) { //добавляем свой код, например original.setX(x); //передаем вызов "настоящему" Shape'у //добавляем свой код, например } ... public void changeSize(int length, int height) { original.changeSize(length, height); } //Обязательно нужен конструктор декоратора из объекта Shape public ShapeWrapper(Shape original) { this.original = original; } } 

In each method we can add our code before or after transferring the call to the original object, this is the meaning of the decorator. If this is not what you need, this pattern does not suit you.