2009-04-27 5 views
2

У меня есть три класса, взаимодействующих интересным способом. Один из них является модельным классом, и к нему должны быть доступны оба других класса, поэтому один его экземпляр хранится как член каждого из них. Оба этих класса взаимодействуют с моделью по-разному.Модель, разделенная между двумя объектами

Существует несколько случаев, когда объект модели должен быть полностью выброшен и заменен новым экземпляром, что усложняет ситуацию. И эти случаи возникают в обоих классах просмотра/контроля. Таким образом, любой из этих классов должен иметь возможность посылать сигнал другому: «Нам нужно координировать и облегчать замену нашего объекта модели новым объектом модели». Прямо сейчас у меня есть код в классе B, чтобы сообщить классу A построить новую модель и отправить ее обратно, но теперь мне нужно обработать противоположную ситуацию, когда событие возникает в классе A, и, к сожалению, класс A не имеет ссылки на класс B, и, вероятно, не следует.

Что такое хороший способ справиться с этим?

Обновление: Извините, это не может быть одноэлементный. Синглтоны - это когда вам нужно гарантировать, что есть только одно. Это не имеет никакого отношения ни к одному из требований, изложенных выше. Этот класс не является синглом и не должен быть.

Update: До сих пор, там на самом деле только был один экземпляр этого класса модели, но у меня было смутное подозрение, мне нужно, чтобы позволить больше, и я не хочу ограничивать себя с помощью Singleton когда это действительно затрагивает различные проблемы из того, что у меня есть. Оказывается, я был прав: вчера я получил новое требование, и теперь мне нужна поддержка произвольного числа из них. :) Не ограничивайте себя, когда вам это не нужно, и не злоупотребляйте шаблонами проектирования в ситуациях, когда они не предназначены!

ответ

5

Вам понадобится слой промежуточной модели, объект «держатель» модели, который будет использоваться для каждого из двух классов. ModelHolder содержит ссылку на модель.

Этот ModelHolder также должен поддерживать слушателей, поэтому, когда его модель выбрасывается, она может уведомить слушателей о том, что модель изменилась.

+0

Я полностью согласен. Владелец модели является владельцем модели. Он управляет жизненным циклом модели, включая запросы на обслуживание клиентов, чтобы попросить, чтобы модель была заменена новой. Клиенты могут регистрировать слушателя для уведомления об изменениях (например, новой модели). –

+0

Я думаю, что я собираюсь с измененной версией этого.ClassA на самом деле является ModelHolder, в некотором смысле, поэтому я просто реализовал интерфейс прослушивателя, который будет реализован ClassB, чтобы получать уведомления о появлении нового объекта Model, который он должен получить. – skiphoppy

+0

hm. да? Не нужно подвергать действию разные модели! Пусть SuperModel отправит своим слушателям «я обновлен», когда изменил его внутреннее представление. COmpare, как работает StatePattern. – KarlP

1

Хорошо, если вам нужно изменить модель (но не заставляйте), вы можете сделать интерфейс слушателя, и сделать как объекты А и В ее реализации:

public interface ModelListener { 

    public void modelChanged(Model newModel); 
} 

и в нужное время вы можете уведомить слушатели новой модели меняются. Вы также можете иметь список, в котором хранятся все зарегистрированные слушатели.

List<ModelListener> modelListeners = new ArrayList<ModelListener>(); 

    public void setNewModel(Model m) { 
     for (ModelListener aListener : m.modelListeners) 
      aListener.modelChanged(m); 
    } 

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

+0

Я не думаю, что это сработает; Я не вижу, как статический метод в классе Model может приводить примеры экземпляров ClassA и ClassB для замены содержимого поля модели. – skiphoppy

+0

Модель не одиночная. – skiphoppy

+0

Почему getNewModel() синхронизирован? –

0

Я часто сталкиваюсь с этой проблемой дизайна в проектах GUI (Swing, GWT). Обычно я создаю модель состояния «более высокого уровня», которая содержит экземпляр объекта, который разделяется между двумя или более классами. Затем у государства есть интерфейс ModelListener, который другие классы могут реализовать, чтобы получать уведомления об изменениях базовой модели. State.setFoo() затем запускает события ModelChanged слушателям, которые отвечают соответственно.

Смежные вопросы