Многие объекты с глобальным и локальным состоянием

StackOverflow https://stackoverflow.com/questions/717587

  •  23-08-2019
  •  | 
  •  

Вопрос

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

У нас есть много объектов, образующих один класс, например рамка для фотографий.Теперь каждая из фоторамок может отображать 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.

Это было полезно?

Решение

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

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

  private PictureMode CurrentMode {
    get {
       return globalMode ?? instanceMode;
    }
  }
}

Другие советы

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

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 или хотите иметь несколько режимов, вы можете создать объект-декоратор, чтобы обернуть изображение и указать, какой это режим.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top