Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Connector design pattern?

I want to connect several classes which are functioning separately but are related.

Lets say I am writing an app in which you can swipe to draw a chart. There are lots of classes in the app which are related and should be connected.

For example three of the classes are:

Swiper - responsible for interpreting the gesture of the user

Points - responsible for handling the points on the chart

ChartDrawer - responsible for drawing the chart on the screen

I want to know is there any design pattern such as a connector which can handle the relation and communication of these classes? Any way i can redesign in a better way or make mind more object oriented?

This is my ChartDraw class which extends a view:

public class ChartDraw extends View implements GestureReceiver {
    int chartYPosition;
    private int circleColor;
    private int circleRadius;
    int height;
    private float lastPointOnChart;
    private int lineColor;
    private int lineWidth;
    private Paint paint;
    private float tempPoint;
    int width;

    public ChartDraw(Context context) {
        super(context);
        init();
    }

    public ChartDraw(Context context, AttributeSet attrs) {
        super(context, attrs);
        init();
    }

    public ChartDraw(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init();
    }

    private void init() {
        this.lineWidth = 15;
        this.circleRadius = 20;
        this.lineColor = Color.parseColor("#1976D2");
        this.circleColor = Color.parseColor("#536DFE");
        this.lastPointOnChart = 0.0f;
        this.tempPoint = 0.0f;
        this.paint = new Paint();
        this.height = getHeight();
        this.width = getWidth();
        this.chartYPosition = this.height / 2;
    }

    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        this.chartYPosition = canvas.getHeight() / 2;
        this.paint.setStrokeWidth((float) this.lineWidth);
        this.paint.setColor(this.lineColor);
        canvas.drawLine(0.0f, (float) this.chartYPosition, this.tempPoint, (float) this.chartYPosition, this.paint);
        if (this.tempPoint > 20.0f) {
            this.paint.setColor(this.circleColor);
            canvas.drawCircle(20.0f, (float) this.chartYPosition, 20.0f, this.paint);
            drawTriangle(canvas, this.paint, this.tempPoint, this.chartYPosition);
        }
    }

    private void drawTriangle(Canvas canvas, Paint paint, float startX, int startY) {
        Path path = new Path();
        path.moveTo(startX, (float) (startY - 20));
        path.lineTo(startX, (float) (startY + 20));
        path.lineTo(30.0f + startX, (float) startY);
        path.lineTo(startX, (float) (startY - 20));
        path.close();
        canvas.drawPath(path, paint);
    }

    public void onMoveHorizontal(float dx) {
        this.tempPoint = this.lastPointOnChart + dx;
        invalidate();
    }

    public void onMoveVertical(float dy) {
    }

    public void onMovementStop() {
        this.lastPointOnChart = this.tempPoint;
    }
}

And this is My SwipeManager which is handling user gesture:

public class SwipeManager implements View.OnTouchListener {
    GestureReceiver receiver;
    private int activePointer;

    private float initX,
            initY;
    private long startTime,
            stopTime;

    private boolean resolving = false;
    private boolean resolved = false;

    private Direction direction;

    @Override
    public boolean onTouch(View view, MotionEvent motionEvent) {
        if (receiver == null) throw new AssertionError("You must register a receiver");
        switch (motionEvent.getActionMasked()) {
            case ACTION_DOWN:
                activePointer = motionEvent.getPointerId(0);

                initX = motionEvent.getX(activePointer);
                initY = motionEvent.getY(activePointer);

                startTime = new Date().getTime();
                break;

            case ACTION_MOVE:
                if (!resolving && !resolved) {
                    resolving = true;
                    float x = motionEvent.getX(activePointer);
                    float y = motionEvent.getY(activePointer);
                    direction = resolveDirection(x, y);
                    if (direction != Direction.STILL) {
                        resolved = true;
                        resolving = false;
                    } else {
                        resolving = false;
                        resolved = false;
                    }
                    break;
                }

                if (resolved) {
                    if (direction == Direction.HORIZONTAL)
                        receiver.onMoveHorizontal(motionEvent.getX(activePointer) - initX);
                    else receiver.onMoveVertical(motionEvent.getX(activePointer) - initY);
                }
                break;

            case ACTION_UP:
                resolved = false;
                receiver.onMovementStop();
                break;
        }
        return true;
    }

    private Direction resolveDirection(float x, float y) {
        float dx = x - initX;
        float dy = y - initY;
        float absDx = Math.abs(dx);
        float absDy = Math.abs(dy);
        if (absDx > absDy + 10) {
            return Direction.HORIZONTAL;
        } else if (absDy > absDx + 10) {
            return Direction.VERTICAL;
        }
        return Direction.STILL;
    }

    public void setReceiver(GestureReceiver receiver) {
        this.receiver = receiver;
    }

    private enum Direction {HORIZONTAL, VERTICAL, STILL;}
}

And i didn't start the Points class because i was not sure about the architecture.

I want this Connector to register all the listeners for the classes and wait for a change and inform the corresponding class of the change, like new point added or swipe started and finished or any other event in the app.

like image 299
Saeed Entezari Avatar asked Feb 11 '26 05:02

Saeed Entezari


1 Answers

Chain of Responsibility might be what you are looking for.

It is a pattern to tie a series of 'processing objects' in a 'chain' that can handle 'command objects'.

I could see you making command objects that encapsulate the touch events and then get passed through several processors and finally get 'processed' by the 'processing objects' which handle input detection/output generation for that particular 'command object'.

I don't know if this is -ideal-, but it is potentially valid.

Other related patterns to look into might be:

https://en.wikipedia.org/wiki/Command_pattern

https://en.wikipedia.org/wiki/Observer_pattern

https://en.wikipedia.org/wiki/Bridge_pattern

like image 169
mawalker Avatar answered Feb 12 '26 19:02

mawalker



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!