0

I have the task of creating a simple drawing app, where one can draw basic shapes (ovals,lines,rectangles) with border and fill colors of choice, using Java Swing and MVC.

The shapes part of the model is implemented using the composite pattern. The functionality to be implementing is drawing (this is already handled by the shapes classes themselves), resizing, moving and deleting shapes and I am supposed to use chain of responsibility (CoR) pattern to accomplish this.

CoR makes sense to me in theory, but I have difficulty grasping how I can apply it for implementing the functionality in practice. I understand that when I click on the drawing panel the program should recognize which shape is selected and then I can implement the methods for resizing,moving,deleting.

So what I need advice on is:

1) how to practically implement CoR pattern here?

2) what is a good way to implement the functionality for resizing, moving, deleting? In own concrete handler classes, as methods in the shapes classes, other?

Many thanks for help.

J.Dow
  • 103
  • 9
  • Are you sure you don't need (abstract) factories or any creational pattern suitable for object creation? The Chain of Responsibility is a behavioral pattern, a good use-case of the usage might be an ATM. – Nikolas Charalambidis Dec 17 '19 at 08:41
  • I agree that it would make sense to use a factory, but for the assignment I was instructed to use the Composite pattern for the model part. – J.Dow Dec 17 '19 at 10:01
  • I'm not sure about CoR, but some related examples are cited [here](https://stackoverflow.com/a/15702152/230513); `GraphPanel` is the simplest. – trashgod Dec 18 '19 at 02:34

1 Answers1

1

Here is a proposed basic implementation of CoR.
For ease of use the following code is a one-file mre : the entire code can be copy-pasted into ShapeManipulator.java and run:

public class ShapeManipulator {

    public static void main(String[] args) {
        Shape s1 = new Shape();
        Shape s2 = new Shape();
        Shape s3 = new Shape();

        ShapeManipulationBase move = new MoveHandler();
        ShapeManipulationBase resize = new ResizeHandler();
        ShapeManipulationBase delete = new DeleteHandler();

        move.setXparam(50).setYparam(25).handle(s1);
        resize.setXparam(100).setYparam(250).handle(s1);
        resize.setXparam(200).setYparam(20).handle(s2);
        delete.handle(s3);
    }
}

//CoR basic interface 
interface ShapeManipulationHandler {
     void handle(Shape shape);
}

//base class allows swtting of optional x, y parameters 
abstract class ShapeManipulationBase implements ShapeManipulationHandler {

    protected int Xparam, Yparam; 

    //setters return this to allow chaining of setters 
    ShapeManipulationBase setXparam(int xparam) {
        Xparam = xparam;
        return this;
    }

    ShapeManipulationBase setYparam(int yparam) {
        Yparam = yparam;
        return this;
    }

    @Override
    public abstract void handle(Shape shape) ;
}

class MoveHandler extends ShapeManipulationBase {

    @Override
    public void handle(Shape shape) {
        System.out.println("Moving "+ shape + " by X="+ Xparam + " and Y="+ Yparam);
    }
}

class ResizeHandler extends ShapeManipulationBase {

    @Override
    public void handle(Shape shape) {
        System.out.println("Resizing "+ shape + " by X="+ Xparam + " and Y="+ Yparam);
    }
}

class DeleteHandler extends ShapeManipulationBase {

    @Override
    public void handle(Shape shape) {
        System.out.println("Deleting "+ shape);
    }
}

class Shape{
    private static int shapeCouner = 0;
    private final int shapeNumber;

    Shape() {
        shapeNumber = ++shapeCouner;
    }

    @Override
    public String toString() {
        return "Shape # "+shapeNumber;
    }
}
c0der
  • 18,467
  • 6
  • 33
  • 65