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