设计模式在更改一个对象的属性时替换重复代码

And*_*rei 10 java design-patterns

我有4个自定义微调器,可以修改一个选定小部件的宽度,高度,X位置和Y位置.我的小部件可以在屏幕上拖动,并且想法是使用这些微调器来更改某些属性,例如宽度或高度,并立即看到对更改的影响.是否有一个模式可以用来替换所有这些类(XSpinnerListener,YSpinnerListener ...)只有一个,并指示我当前对象(JButton)的哪个属性需要更改?这是一个很好的设计方法吗?

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());
    }
 }
Run Code Online (Sandbox Code Playgroud)

Hov*_*els 6

一些沉思......

您可以通过为SpinnerListener spinnerValueChanged(...)方法提供SpinnerEvent参数来模拟Swing的设计,该参数指示正在更改哪个轴.Axis可以用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;
   }

}
Run Code Online (Sandbox Code Playgroud)

SpinnerEvent参数类可能类似于:

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;
   }

}
Run Code Online (Sandbox Code Playgroud)

你的SpinnerListener接口(你没有告诉我们)必须改变:

interface SpinnerListener {
   public void SpinnerValueChanged(SpinnerEvent e);
}
Run Code Online (Sandbox Code Playgroud)

也许你的具体实现可以在实现Movable接口的对象上工作:

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);
}
Run Code Online (Sandbox Code Playgroud)

使用关键方法,移动可以这样实现:

@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;
  }
}
Run Code Online (Sandbox Code Playgroud)

小具体实施

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());
   }

}
Run Code Online (Sandbox Code Playgroud)