Множество объектов с глобальным и локальным состоянием - PullRequest
0 голосов
/ 04 апреля 2009

Я ищу лучший дизайн для следующей ситуации.

У нас есть много объектов, образующих один класс, например, рамку рисунка. Теперь каждая из рамок изображения может отображать 3 типа изображения. 1) лицо 2) скриншот 3) пусто

Это просто:

public enum PictureMode 
{
    Face,
    Screen,
    None
}

public class PictureFrame {
    private PictureMode mode;
    public PictureMode Mode 
    {
        get { retrun mode; }
        set { /* set currentPicture to the correct one */ }
    }

    private Image currentPicture;
    private Image face;
    private Image screen;
    private Image empty;

    public PictureFrame(Image face, Image screen) {
        this.face = face;
        this.screen = screen;

        mode = PictureMode.None; // Maybe this is our default.
    }
}

Теперь мы можем создавать несколько фоторамок с разными изображениями и легко менять режим для каждого.

Теперь я хочу добавить глобальный установщик для всех PictureFrames. Тогда каждый новый PictureFrame должен принимать глобальную настройку как настройку по умолчанию. Позже он может быть настроен на другое сквозное.

Вот мое решение, но я хочу обсудить, есть ли лучшее.

Я добавил статическое поле PictureFrame.Instances в класс PictureFrame, где доступны все PictureFrame. Теперь я могу перебрать все PictureFrames для применения нового глобального режима ко всем кадрам.

Кроме того, у меня есть второе статическое поле PictureFrame.GlobalImageMode, где я устанавливаю глобальный режим, если я изменяю его во всех кадрах и читаю его в конструкторе PictureFrame. Сеттер для GlobalImageMode также может быть статическим в классе PictureFrame.

Ответы [ 2 ]

1 голос
/ 04 апреля 2009

Просто дикий выстрел здесь ...: Почему вы не всегда используете геттер для текущего режима кадра с условием в нем:

class PictureFrame {
  private PictureMode instanceMode;
  private static PictureMode? globalMode;

  private PictureMode CurrentMode {
    get {
       return globalMode ?? instanceMode;
    }
  }
}
0 голосов
/ 04 апреля 2009

Если я правильно понимаю формулировку проблемы, я думаю, что это похоже на то, что вам нужно:

public class Face extends Image { }
public class Screen extends Image { }

public class PictureFrame {
  private Image picture = null;

  public PictureFrame(Image newPicture) {
    this.setPicture(newPicture);
  }

  public setPicture(Image newPicture) {
    this.picture = newPicture;
  }
}

public class PictureFactory {
  private static Image defaultPicture = null;

  public static void setDefaultPicture(Image newPicture) {
    PictureFactory.defaultPicture = newPicture;
  }

  public static Image getDefaultPicture() {
    return PictureFactory.defaultPicture;
  }

  public static PictureFrame getNewPictureFrame() {
    return new PictureFrame(PictureFactory.defaultPicture);
  }
}

public class PictureFrameManager {
  private static PictureManager INSTANCE = new PictureManager();
  private Vector<PictureFrame> frames = new Vector<PictureFrame>();

  public static PictureFrameManager getInstance() {
    return PictureManager.INSTANCE;
  }

  private PictureFrameManager() {}

  private void addPictureFrame(PictureFrame frame) {
    this.frames.add(frame);
  }

  private void setFramesToDefault() {
    Image defaultPicture = PictureFactory.getDefaultPicture();
    Enumeration<PictureFrame> iFrames = frames.elements();
    while(iFrames.hasMoreElements()) {
      iFrames.nextElement().setPicture(defaultPicture);
    }
  }
}

Вы используете его через:

Face face = new Face();
//...do something to load the face object here

PictureFactory.setDefaultPicture(face);
PictureFrame frame = PictureFactory.getNewPictureFrame();

PictureFrameManager manager = PictureFrameManager.getInstance();
manager.addPictureFrame(frame);

Screen screen = new Screen();
//...do something to load the screen object here

PictureFactory.setDefaultPicture(screen);
manager.setFramesToDefault();

В качестве альтернативы, если вы не хотите расширять Image или хотите иметь несколько режимов, вы можете создать объект-декоратор, чтобы обернуть изображение и сказать, в каком он режиме.

...