Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Design pattern to replace repetitive code when changing properties of one object

I have 4 custom spinners which modify the width, height, X location and Y location of one selected widget. My widget can be dragged around the screen, and the idea is to use these spinners to change certain properties such as width or height, and see immediate effect on the changes. Is there a pattern that I can use to replace all these classes (XSpinnerListener, YSpinnerListener...) with only one and indicate which property of my current object (a JButton) needs to change? Is this a good design approach?

public void init(){
    widthSpinner.setListener(new WidthSpinnerListener());
    heightSpinner.setListener(new HeightSpinnerListener());
    xSpinner.setListener(new XSpinnerListener());
    ySpinner.setListener(new YSpinnerListener());
}


public class XSpinnerListener implements SpinnerListener {

    @Override
    public void spinnerValueChanged() {
         current.setLocation(xSpinner.getValue(), current.getY());
    }
}

public class YSpinnerListener implements SpinnerListener {

    @Override
    public void spinnerValueChanged() {
        current.setLocation(current.getX(), ySpinner.getValue());
    }
}

public class WidthSpinnerListener implements SpinnerListener {

    @Override
    public void spinnerValueChanged() {
         current.setSize(widthSpinner.getValue(), current.getHeight());
    }
}

public class HeightSpinnerListener implements SpinnerListener {

    @Override
    public void spinnerValueChanged() {
         current.setSize(current.getWidth(), heightSpinner.getValue());
    }
 }
like image 287
Andrei Avatar asked May 10 '15 00:05

Andrei


People also ask

What design pattern would you use to make it easy to change the class of the object that a method returns?

Factory Method is a creational design pattern that provides an interface for creating objects in a superclass, but allows subclasses to alter the type of objects that will be created.

Which design pattern can be used to modify the functionality of an object at runtime?

Decorator design pattern is used to modify the functionality of an object at runtime. At the same time other instances of the same class will not be affected by this, so individual object gets the modified behavior.

Which design pattern ensures that only one object of particular class gets created?

The Singleton Design Pattern is a Creational pattern, whose objective is to create only one instance of a class and to provide only one global access point to that object.


1 Answers

Some musings...

You could emulate Swing's design by giving your SpinnerListener spinnerValueChanged(...) method a SpinnerEvent parameter, one that indicated which axis is being changed. The Axis could be encapsulated by an enum,...

enum Axis {
   X("X"), Y("Y"), WIDTH("Width"), HEIGHT("Height");

   private String name;

   private Axis(String name) {
      this.name = name;
   }

   public String getName() {
      return name;
   }

}

And the SpinnerEvent parameter class could look something like:

class SpinnerEvent {
   private Object source;
   private Axis axis;
   private int value;

   public SpinnerEvent(Object source, Axis axis, int value) {
      this.source = source;
      this.axis = axis;
      this.value = value;
   }

   public Object getSource() {
      return source;
   }

   public Axis getAxis() {
      return axis;
   }

   public int getValue() {
      return value;
   }

}

Your SpinnerListener interface (which you don't show us) would have to change:

interface SpinnerListener {
   public void SpinnerValueChanged(SpinnerEvent e);
}

And perhaps your concrete implementations could work on objects that implement a Movable interface:

interface Movable {

   public abstract int getX();
   public abstract void setX(int x);
   public abstract int getY();
   public abstract void setY(int y);
   public abstract int getWidth();
   public abstract void setWidth(int width);
   public abstract int getHeight();
   public abstract void setHeight(int height);
   public abstract void move(Axis axis, int value);
}

with a key method, move that could be implemented like so:

@Override
public void move(Axis axis, int value) {
  switch (axis) {
  case X:
     x += value;
     break;
  case Y:
     y += value;
     break;
  case WIDTH:
     width += value;
     break;
  case HEIGHT:
     height += value;
  default:
     break;
  }
}

Small concrete implementation

class ConcreteSpinnerListener implements SpinnerListener {
   private Movable movable;

   public ConcreteSpinnerListener(Movable movable) {
      this.movable = movable;
   }

   @Override
   public void SpinnerValueChanged(SpinnerEvent e) {
      movable.move(e.getAxis(), e.getValue());
   }

}
like image 115
Hovercraft Full Of Eels Avatar answered Oct 24 '22 07:10

Hovercraft Full Of Eels